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

WIP - Add an eslint rule for detecting package level side effects #14135

Closed
wants to merge 8 commits into from

Conversation

talldan
Copy link
Contributor

@talldan talldan commented Feb 27, 2019

Fixes #13910

Description

This checks for violations of the package.json sideEffects property. At the moment there are a couple of particular patterns it checks for:

  • Function calls in the top-most scope where the return value isn't used. e.g.:
registerStore( // ... );
window.addEventListener( // ... );
  • Imports of other modules that don't create any new variables. e.g.:
import './store';

When it detects these patterns and the file has not been added to the package.json sideEffects property it warns the developer to do so.

Other patterns that I've thought about:

  • Mutation of an imported value. I think this is possible to add a lint rule for. I imagine there aren't (m)any instances of this, since I'd expect it to be considered bad practice and caught in a code review.
  • Any others?

Patterns that are hard to lint for:

  • If a mutation or side-effect happens as the result of a function call - e.g. function initializeModule() { window.addEventListener( // ... ); }, it's hard to catch since I'd have to trace back to the callsite.

How has this been tested?

Screenshots

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.

@talldan talldan added [Type] Code Quality Issues or PRs that relate to code quality [Tool] ESLint plugin /packages/eslint-plugin labels Feb 27, 2019
@talldan talldan self-assigned this Feb 27, 2019
@talldan talldan force-pushed the add/package-side-effect-linting branch 3 times, most recently from f7c01c3 to 14753be Compare February 28, 2019 07:02
Copy link
Member

@noisysocks noisysocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very interesting!! 🤯


// Function calls can introduce side effects when the return value is not used.
window.addEventListener( 'resize', handleResize );
registerStore( store );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same example as above.

Copy link
Contributor Author

@talldan talldan Mar 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, was trying to illustrate that adding the file to the sideEffects property resolves the issue, but I need to make it clearer. Will rewrite.

@gziolo
Copy link
Member

gziolo commented Mar 5, 2019

It might be helpful to have this rule to catch which packages have side-effects but I don't expect this would be bullet-proof. I think we have maybe a handful of packages which don't have side-effects and they are very low-level like:

  • autop
  • block-serialization-default-parser
  • block-serialization-spec-parser
  • compose
  • deprecated
  • element
  • escape-html
  • is-shallow-equal
  • keycodes
  • priority-queue
  • redux-routine
  • tokens-list
  • url
  • wordcount

and maybe a few more which I didn't explore in depth. For sure this PR contains a few false positives like data or api-fetch which run some logic when imported.

@talldan
Copy link
Contributor Author

talldan commented Mar 7, 2019

@gziolo Thanks for taking a look. Do you have an example of where data and api-fetch introduce side effects?

I'm looking for other patterns that could be added to this rule, but as you say it'd be hard to make anything bullet-proof.

I think if a rule can help manage those side-effects it'd still be beneficial to making it a completely manual process, and should also help alert devs to the need to think about side effects.

@talldan talldan force-pushed the add/package-side-effect-linting branch from 14753be to 5c0045f Compare March 7, 2019 06:58
@gziolo
Copy link
Member

gziolo commented Mar 7, 2019

@gziolo Thanks for taking a look. Do you have an example of where data and api-fetch introduce side effects?

Sure, a related line for data:

I might be wrong about api-fetch - it probably sets up all middlewares on the server in WordPress core.

@talldan talldan force-pushed the add/package-side-effect-linting branch from 516a048 to 9eea50b Compare April 30, 2019 08:09
@talldan
Copy link
Contributor Author

talldan commented Aug 20, 2019

Closing this as it has lain dormant for some time and there's a bit more thought that needs to go into it.

@talldan talldan closed this Aug 20, 2019
@gziolo gziolo deleted the add/package-side-effect-linting branch August 26, 2019 08:53
@gziolo
Copy link
Member

gziolo commented Aug 26, 2019

Closing this as it has lain dormant for some time and there's a bit more thought that needs to go into it.

Do you still think, we should we at least pick some of the packages manually and apply this magic field to those which are all pure?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Tool] ESLint plugin /packages/eslint-plugin [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add sideEffects property to package.json for our packages
3 participants