RxJS version: 5.5
I've been using lettable operators since 5.5 was in beta, it was great. But I have a few concerns regarding the way to import them.
Are we supposed to do this:
import { map } from 'rxjs/operators';
or:
import { map } from 'rxjs/operators/map';
Either way, it works the same. But for the sake of consistency, shouldn't there be only one way of doing this?
As someone who used the deep import, I was told to use the rxjs/operators path.
https://twitter.com/IgorMinar/status/924088605810753536
The reason being ergonomics and the fact that deep imports are difficult to maintain.
@benlesh
One more question. Since rxjs/operators is "unoffically offical" entry point to lettable operators, will rxjs/observable (or something similar) be available as an entry point to rxjs/observable/of or rxjs/observable/combineLatest, and will the last two disappear in v6 (along with rxjs/add/*)?
I'm really hoping we see a future version where we can import most or all of the RxJS stuff from a single place. Here is an example I have in a simple use of RxJS right now:
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { _throw } from 'rxjs/observable/throw';
import { delayWhen } from 'rxjs/operators';
import { timer } from 'rxjs/observable/timer';
This is rather tedious, of the 5 things I want, all 5 have to come from a different module.
I'd like to write something more like:
import { Observable, of, _throw, delayWhen, timer } from 'rxjs';
Of course I could accomplish this myself with some kind of wrapper, but I would like something close to this to become idiomatic, documented official usage. A man can dream?
I think importing from rxjs/operators is _almost_ the same as importing from rxjs or rxjs/Rx. It loads this file https://github.com/ReactiveX/rxjs/blob/master/src/operators.ts that imports all the operators. Then if you want to bundle your app (eg. with angular-cli) it'll include all operators including those you're not using.
So a preferred way should be always importing only the operators you want. Just like you did:
import { map } from 'rxjs/operators/map';
import { filter } from 'rxjs/operators/filter';
import { timer } from 'rxjs/observable/timer';
However, I'm not an export on JS bundlers so maybe there's a plugin or something (or maybe the bundler are just smart enough) that will let you use rxjs/operators and stay tree-shakable. Anyway if you stay with imports such as 'rxjs/observable/timer' you should be always fine.
@martinsik No, it does not. When doing import { map } from 'rxjs/operators';, you selectively import the map operator. Tools like Webpack or Rollup are smart enough to not include operators that you don't use.
@sarunint I tried it yesterday. The bundler can't know if any of the imports in rxjs/operators doesn't modify any global object (or prototype) so it needs to include all of them.
If you used import { map } from 'rxjs/operators'; I suppose you transpiled it to ES5(?) with some module system. Can you give me an example with eg. rollup config where you import from rxjs/operators and the bundle will only include operators you are using in your code?
I tried importing an operator from rxjs/operators today in a real Angular 5.0.0 app with angular/[email protected] and RxJS 5.5.2 and it really does include all the operators.
hi, if you guys use webpack & ts-loader, you may want to try https://github.com/brooooooklyn/ts-import-plugin#rxjs
@martinsik here is my example: https://github.com/sarunint/rxjs-rollup
@sarunint In your example git, you actually do import map like that:
import { map } from 'rxjs/operators/map';
@martinsik wants to import like this:
import { map } from 'rxjs/operators';
And BTW, I believe angular apps use webpack by default. I may be wrong but Ionic/Angular ones do anyway! @martinsik, I think you should look into what @Brooooooklyn said...
Whoa, that was my biggest mistake ever. I just trusted VSCode autoimport too much.
Will investigate asap
@ptitjes Angular CLI is using webpack but you can't edit its configuration and add more another plugins. You can "eject" the config and maintain it yourself but that's absolute madness.
@martinsik Well, I do customize the webpack config in my Ionic/Angular app with some webpack-merge voodoo. You might want to look into it. It allows to tweak the config without copying it all.
@martinsik Angular CLI should do the tree-shaking properly since it's using RxJS Path Mapping as described here.
@sarunint In the next release, because it just landed in angular-cli-1.6.0-rc.0 prerelease...
@ptitjes No, this landed since 1.5.0-rc.2
My bad!
I'll try to investigate @martinsik's claim that rxjs/operators still include the whole thing in Angular CLI 1.5.2 to see if the config missed something!
@sarunint Well, there is that thing https://github.com/angular/angular-cli/commit/a7f2e7f which is in 1.6.0-rc.0 which is very similar to what I use in my application to have the tree shaken correctly.
Looping back to my earlier comment, it seems wise for the RxJS team would optimize for developer ergonomics. Aim for where the tooling is going to be (correct tree shaking), not for where the tooling has been. By the time the bulk of developers upgrade to the newest RxJS, likely they will be in parallel upgrading to build tooling that does the Right Thing.
@kylecordes I would like to see what you proposed in your previous comment too. Unfortunately, it's going at least RxJS v6 to see that happens, since it's a breaking change.
@martinsik I've updated the repo, it looks like that I need to use RxJS 5.5 path mappings to get the _esm2015 version.
The intended way to import lettable/pipeable operators in 5.5 is:
import { map, filter, mergeMap, tap } from 'rxjs/operators';
Sorry it took so long for me to respond. :+1:
@kylecordes By the way, your dream is coming true.
@martinsik I am also seeing the use of 'rxjs/operators' pull in all of the operators in Angular CLI 1.6.3. I heard today that it was due to a webpack bug that will be fixed 'soon'.
Does anyone have a link to the specific bug with webpack?
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.
Most helpful comment
I'm really hoping we see a future version where we can import most or all of the RxJS stuff from a single place. Here is an example I have in a simple use of RxJS right now:
This is rather tedious, of the 5 things I want, all 5 have to come from a different module.
I'd like to write something more like:
Of course I could accomplish this myself with some kind of wrapper, but I would like something close to this to become idiomatic, documented official usage. A man can dream?