The big reorganization PR for v6 (WIP)#3145
The big reorganization PR for v6 (WIP)#3145benlesh wants to merge 11 commits intoReactiveX:masterfrom benlesh:reorg
Conversation
Generated by 🚫 dangerJS |
|
Assigning myself to give a quick peek. |
Moves all patching operator implementations to a directory `internal/patching/operator`. BREAKING CHANGE: Deep imports to `rxjs/operator/*` (NOT `rxjs/operators/*`!!!) will no longer work. Again, pipe operators are still where they were.
…ctory
- Moves all files from `src/observables` to `src/internal/observables`
- Updates some tests to reference those internal files, this is
temprorary
- Adds an `index.ts` file at root that exports the static observable
creation functions
BREAKING CHANGE: You can no longer import observables from
`rxjs/observable/*`, now you must import them from `rxjs` directly, like
so: `import { fromEvent, timer } from 'rxjs';`
BREAKING CHANGE: You should no longer deep import custom Observable
implementations
BREAKING CHANGE: `_throw` is now exported as `throwError`
BREAKING CHANGE: `if` is now exported as `iif`
- Exports all pipeable operators from `rxjs`.
BREAKING CHANGE: Pipeable operators must now be imported from `rxjs`
like so: `import { map, filter, switchMap } from 'rxjs';`
BREAKING CHANGE: Operator versions of static observable creators such as
`merge`, `concat`, `zip`, `onErrorResumeNext`, and `race` have been
removed. Please use the static versions of those operations. e.g.
`a.pipe(concat(b, c))` becomes `concat(a, b, c)`.
- Exports schedulers as `asapScheduler`, `asyncScheduler`, `queueScheduler` and `animationFrameScheduler` BREAKING CHANGE: Scheduler instances have changed names to be suffixed with `Scheduler`, (e.g. `asap` -> `asapScheduler`)
- moves operators directory under `internal`. - moves `operators.ts` to `internal/operators/index.ts`
BREAKING CHANGE: Can no longer deep import top-level types such as `rxjs/Observable`, `rxjs/Subject`, `rxjs/ReplaySubject`, et al. All imports should be done directly from `rxjs`, for example: `import \{ Observable, Subject \} from 'rxjs';`
|
Changes Unknown when pulling 8bb23d1 on benlesh:reorg into ** on ReactiveX:master**. |
|
I thought the transition from v4 -> v5 was good, this is even better. So much easier to navigate what's being exported, the interfaces make so much sense, and I'm looking forward to introducing more people to Rx with how much simpler the imports read. I'm loving this switchover from v5 -> v6. |
kwonoj
left a comment
There was a problem hiding this comment.
Initial high level it looks fine, I guess there may be some glitches but we can fix it since this is for non stable builds.
|
Would it be helpful to have the creation methods named something like: I feel like the latter is most descriptive, but too verbose. And that's coming from a guy that can type the word "observable" blindfolded. (irony: I typo'ed "observable" three times just there) And then still have a single import location? |
|
I don't really see a problem with having the source of the operators be in many files, but then have an index.ts that does
This is definitely a question I have asked myself. Just using |
|
My instincts lie with @IgorMinar. Renaming creation operators will make migration harder and still leave you with something to explain. How many kinds are there? Creators/Observables, Operators, Subscribers, and Schedulers as I recall. And then there are Utilities right? That’s five. So is n===5? I guess that’s livable. One big rxjs bucket is my least favorite because there are just too many kinds of things in there that are easy to confuse. Adding prefixes (such as “rx” or “from”)will make migration harder and is just another way of saying “These things belong in the same bucket.” If so, give them a bucket. Bikeshedding perhaps. It’s a great direction however you decide. |
|
I should also point out that the small N paths solution doesn't suffer from ergonomics issues of introducing a new import line, because most editors and IDEs do that for you automatically. If you however use an editor that can't create imports for you via autocompletion then using a single path is obviously more ergonomic. The question is if optimizing the api surface for code authoring using an editor that has no ES import support is the right goal. I don't think it is, but that's my personal opinion 😄 I believe that this is an example of authoring workflow most rxjs developers deserve: source: https://marketplace.visualstudio.com/items?itemName=steoates.autoimport (note webstorm and other editors, support this workflow as well) |
|
I forgot to mention that you should notice how the autocompletion in the screencast above highlights the path the symbol is coming from. This is what helps me pick the right symbol and in case of rxjs would help me distinguish between creation methods and operators. Once I make the choice, I no longer see the path (except) in the import, which removes clutter (unlike the "rx" prefix which would remain in the code even after I pick the symbol) |
|
@IgorMinar I get that argument and I personally use an editor that has that feature, but I would still prefer to not have the top of every file look like this (as atm): So not adding 1 import per operator is a valid goal no matter of having an IDE or not |
|
Btw, static operators like of(1, 2, 3).pipe(
$ => concat($, of(4, 5, 6))
) |
|
@felixfbecker most of those import lines are because each operator is imported separately. my proposal would reduce that snippet to two imports ( Schedulers and other symbols are used very rarely so 99% of the code should not need to import them. |
|
Controversial: I think the discoverability of operators via IDE auto complete is critical. Gives back what we lose moving away from proto and towards pipes. import { of, concat, $map, $filter } from ‘rxjs’;
of(1).pipe(
$map(v => v + 1),
$ => concat($, of(3),
$filter(v => v > 2),
) |
|
I'm on the same path as @IgorMinar. Personally, I would love to rename the creation methods as this would make it way more explicit what they are doing. However, as that is breaking backwards compatibility too much I don't think its a good idea. Adding aliases would sadly only add to the confusion. When that's from the table, |
|
I back @IgorMinar mostly as well although I would argue that as this is a major version, I think pulling the trigger and renaming is cleaner. I like the from* options as that is very descriptive to what you are doing and reduces confusion between the operators. Sure we can import from two places but that then leaves code readability up to how it was imported and can create collision and confusion. If I am adopting a new major version I know things are going to break. When I switched to lettables I had to go through and rename catch and do in many places, why would this be any different. That is just my own feelings personally. Overall amazing work and looking forward to seeing this in the wild. |
|
I think single import path will be fine for TypeScript developers, as the type will tell the difference between operators and create function, but for JS developers, especially for beginners, single import will create some confusion, so agree with @IgorMinar |
|
I'm for importing from either a single entry point (1st preference) or ~5 paths (2nd preference). I would also welcome renaming creation operators to I think renaming the creation operators has a relative minor impact on existing code bases (search/replace). The bigger impact is removing the lettable operator equivalents. I now use the creation methods exclusively now, but our older code does not. Changing from operators to create methods involves more shifting of code around. |
|
It seems like the vocal people here would like to divide things up in terms of functionality to some degree. This would give us:
Is the compromise proposal to have:
?? I'm going to finish up this PR today and merge. This has taken too long. I have to be honest, I really don't like it. I'd just assume have one entry point. (EDIT: Got a few DMs that I sounded "angry"... I'm not at all.. just bad text maybe? haha) |
|
@benlesh Your "one" notion has much wisdom, is very compatible with the future of bundling tools, is easy to consume, etc. The only downsides, discussed here, are that the list of things exported from that one place can get a little long (hard to look through it by hand), and names have to be deconflicted. Trust your heart :-) |
|
Well the fact is, even if we split them up, there's going to be a problem with import { concat } from 'rxjs';
import { concat } from 'rxjs/operators';... you'll need to alias regardless. What to, though? |
For me at least, the idea was primarily to have
I thought the operator variants were going away?
|
That's what I'd like, but I felt like there is a subtext here to keep them. I'm probably mistaken. If so, that's great. |
|
@benlesh It always seemed odd to have two ways to do |
|
So:
|
|
I think it's cool to put |
|
Speaking in favor of what Ben said up a ways (just one package): It seems silly to have a |
Yeah, I liked the |
|
If I can chime in here: I would vote for importing everything from "RxJs". I don't agree that this would be very confusing, because there are types and documentation for everything. (Thanks btw!) If anything, I'm afraid that having multiple import paths deviates from the norm and would be worse complexity wise! When in doubt, go for simple.. Just my 2 cents.. |
|
Moving this pr to #3223 ... it's the same PR I just had a problem with my fork. (Sorry). |
|
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |


See commit messages for more details.
rxjs.import { map, filter, scan, switchMap } from 'rxjs';import { timer, concat, fromEvent } from 'rxjs';concat(a, b, c)instead ofa.pipe(concat(b, c)))