Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New rule: disallow full import of RxJS operators #498

Conversation

rokerkony
Copy link
Contributor

The reason behind this PR is better described in my article:
https://medium.com/p/prevent-coding-mistakes-write-a-tslint-rule-specific-for-your-own-project-987d26f91647

Shortly: it can decrease a size of a bundle when RxJS operators are imported in a wrong way

I know it is not exactly Angular related, but Angular requires RxJS as a dependency. Therefore I think it could be part of the Styleguide.

The reason behind this PR is better described in my article:
https://medium.com/p/prevent-coding-mistakes-write-a-tslint-rule-specific-for-your-own-project-987d26f91647

Shortly: it can decrease a size of a bundle when RxJS operators are imported in a wrong way
@intellix
Copy link

intellix commented Jan 23, 2018

I was under the impression this was ok: import {delay, tap} from 'rxjs/operators'
Also, can't you already achieve this with import-blacklist from tslint?

@rokerkony
Copy link
Contributor Author

@intellix Let me try this once more in the evening but when I checked on the codebase of https://github.com/erento with source-map-explorer the outcome was different.

The advantage is that it has a fixer as well, so it can automatically fix the imports.

@intellix
Copy link

ng new rxjs-test && cd rxjs-test
npm i source-map-explorer
ng build -prod -sm -oh=false
./node_modules/.bin/source-map-explorer dist/main.bundle.js

app.component.ts:

import { Component } from '@angular/core';
import { timer } from 'rxjs/observable/timer';
import { tap } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  timer = timer(100, 100).pipe(tap(console.log));
}

Before using above (20.67kb):
screenshot 2018-01-23 14 48 50

After using above (27.01kb):
screenshot 2018-01-23 14 52 52

@lazarljubenovic
Copy link
Contributor

I don't think this belongs to codelyzer. Check out rxjs-lint-rules.

@rokerkony
Copy link
Contributor Author

@intellix I don't know what you mean with before and after... but from curiosity I run the same example you posted and these are my results:
import { tap } from 'rxjs/operators/tap'; -> 24.49 KB
import { tap } from 'rxjs/operators'; -> 27.01 KB

So I have a bit different number then you in the first line — it shows it is better to import directly from rxjs/operators/tap.

@lazarljubenovic I still think it would be valuable for other angular users but I'm not pushing for it hard, so when you agree I should close it I will :)

@lazarljubenovic
Copy link
Contributor

But Angular users can install the other module which already exists for the similar (same?) purpose. It's not like you're scoped on one linter plugin.

@intellix
Copy link

intellix commented Jan 23, 2018

ok so it seems more stuff is pulled in. I was thinking it was more a case of importing all vs a single operator. All operators would probably be something like 150kb+

@wKoza wKoza self-requested a review January 23, 2018 20:33
@wKoza
Copy link
Collaborator

wKoza commented Jan 23, 2018

I'm not sure this rule is durable. There are two things:

  • Rxjs explains that the best way to use lettable / pipeable is:
import { map, filter, mergeMap, tap } from 'rxjs/operators';

see : ReactiveX/rxjs#3018 (comment)

  • Our problem seems to be related to Webpack 3. Webpack 4 will improve it.

see: angular/angular-cli#9069 (comment)

So, using the deep import is a workaround. I'm not sure that a provisional rule has its place in codelyzer.

@lucasvanhalst
Copy link

They will remove the deep imports in rxjs 6, so don't think this rule should become a thing.

See here: https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md#600-alpha1-2018-01-12

operators: Pipeable operators must now be imported from rxjs like so: import { map, filter, switchMap } from 'rxjs/operators';. No deep imports.

@rokerkony
Copy link
Contributor Author

Thank you @wKoza and @lucasvanhalst for great arguments, I will close this PR as it really doesn't make sense when RxJS@6 will not have this problem anymore...

@rokerkony rokerkony closed this Jan 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants