Coder Social home page Coder Social logo

eslint-plugin-tree-shaking's People

Contributors

dependabot[bot] avatar greenkeeper[bot] avatar lukastaegert avatar maclockard avatar motiko avatar neal-codaio avatar pd4d10 avatar ziacik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

eslint-plugin-tree-shaking's Issues

Support React.forwardRef ignore using noSideEffectsWhenCalled

When using React.forwardRef i get eslint error: Cannot determine side-effects of mutating function return value
adding it to noSideEffectsWhenCalled doesn't help filter return value errors.

for example:

const ErrorPage = React.forwardRef((props, ref) => (
  <div ref={ref} {...props} />
));

with lint rule:

"noSideEffectsWhenCalled": [
    {
      "module": "react",
      "functions": ["forwardRef"]
    }
]

or

"noSideEffectsWhenCalled": [
    {
      "module": "react",
      "functions": "*"
    }
]

could you please advise how this issue could be resolved?

Support conditional chain operator (?.)

Currently get this stack trace when calling a function with a conditional chain operator upon initialization:

[Error - 10:22:26 PM] TypeError: Cannot read property 'hasValue' of undefined
Occurred while linting /Users/maclockard/workspace/hex-inc/hex/packages/client/components/markdown/MarkdownSanitizeSchema.ts:2
    at Object.|| (/Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:152:22)
    at Object.getValueAndReportEffects (/Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:663:48)
    at reportSideEffects (/Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:907:24)
    at /Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:256:43
    at Array.forEach (<anonymous>)
    at Object.reportEffects (/Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:256:24)
    at reportSideEffects (/Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:905:24)
    at /Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:734:11
    at Array.forEach (<anonymous>)
    at Object.reportEffects (/Users/maclockard/workspace/hex-inc/hex/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:732:25)

Config to assume upstream functions are pure

This plugin is pretty much exactly what I'm looking for to prevent side effects! Thanks for all the work that went into it. There is, however, one thing though preventing me from using this for my projects, and that's how many things you have to manually mark using magic comments. It makes perfect sense as to why, but it makes this plugin infeasible to use for medium to larger projects with lots of modules that import from both each other and 3rd party libraries.

I think the thing that would help most here would be the ability to mark functions as side effect free in the plugin config. This would really bring down the number of places you need to explicitly mark no-side-effects-when-called in code, making this plugin much more approachable for medium to larger projects!

Here's what it could possibly look like in config:

{
  "rules": {
    "tree-shaking/no-side-effects-in-initialization": ["error", {
      "noSideEffectsWhenCalled": [
        {"module": "react", "functions": ["memo", "createComponent"]},
        {"module": "styled-components", "functions": "*"},
        {"builtin": "Object.values"},
        {"module": "#local", "functions": ["myFunc1", "myFunc2"]}
      ]
    }]
  }
}

I hope this example is mostly self explanatory, but to call out some extra stuff I added for convenience:

  • You can white list all functions for a given module using "*" instead of passing an array of function names
  • You can white list functions from all "local" modules by using the special module name "#local". What I mean by a local module is one that is imported via a relative path.

This would also help address #43 by allowing folks to explicitly whitelist things themselves. Specifically since someone may be using a bundler besides rollup that already correctly handles a given builtin.

Be smarter about side effects of builtins

Object.freeze({}) or Object.values({}) assigned to a module global triggers "Cannot determine side-effects of calling member function", while the rule should know, that these methods themselves don't have any side effects for literals (or Object.values for any argument, since it does not modify it).

Interestingly Array.from doesn't seem to trigger the rule, at least not in the case of Array.from(Object.values({})).

Static blocks result in "Unknown node type StaticBlock."

ESLint version: 8.57.0

ESLint plugins:

"eslint-config-prettier": "~9.0.0",
"eslint-formatter-azure-devops": "^1.2.0",
"eslint-plugin-import": "~2.26.0",
"eslint-plugin-jest": "~27.4.3",
"eslint-plugin-jsdoc": "~46.2.6",
"eslint-plugin-prettier": "~5.0.0",
"eslint-plugin-tree-shaking": "^1.12.2",
"eslint-plugin-tsdoc": "~0.2.14",

Given a class with a static block, eslint-plugin-tree-shaking produces the following error:

error  Unknown node type StaticBlock.
If you are using the latest version of this plugin, please consider filing an issue noting this message, the offending statement, your ESLint version, and any active ESLint presets and plugins  tree-shaking/no-side-effects-in-initialization

For example:

class Foo {
    static {
        console.log("FOO");
    }
}

Find a way to automatically test against Webpack's tree-shaking

Currently, eslint-plugin-tree-shaking features a test suite of > 350 code snippets which are also automatically run against rollup. These tests check that if code is not tree-shaken, then there needs to be an ESLint error. That is, you can be fairly certain that if there are no ESLint errors, you do not have any hidden side-effects in rollup. Unfortunately, the same cannot be said for Webpack. This is particularly bad since Webpack is the final bundler for most Webapps and those would benefit most from tree-shaking.
What I am looking for is a way to run a code snippet through Webpack and reliably determine if tree-shaking would remove this snippet. Main problems:

  • Webpack always adds a lot of boilerplate code which is always present
  • Tree-shaking is realized via comments. In order for the code to be actually removed, Uglify needs to be run
  • After minification, it is even more difficult to determine which code is boilerplate and which is not
    If anyone has some good ideas here, this would be greatly appreciated.

Unknown node type SpreadElement at 1.8.0

I got this issue with 1.8.0

Unknown node type SpreadElement.
If you are using the latest version of this plugin, please consider filing an issue noting this message, the offending statement, your ESLint version, and any active ESLint presets and pluginseslint(tree-shaking/no-side-effects-in-initialization)

Screenshot 2020-01-11 18 13 21

Private identifiers not recognized

Hi,

If I have some TypeScript like:

export class Secret {
  #secret: string

  constructor() {
    this.#secret = 'secret'
  }

  getSecret(): string {
    return this.#secret
  }
}

I get an error:

Unknown node type PrivateIdentifier.
If you are using the latest version of this plugin, please consider filing an issue noting this message, the offending statement, your ESLint version, and any active ESLint presets and plugins eslint(tree-shaking/no-side-effects-in-initialization)

at the line #secret: string.

eslint: 8.22.0
eslint-plugin-tree-shaking: 1.10.0
eslint-config-prettier: 8.5.0
eslint-plugin-import: 2.26.0
eslint-plugin-prettier: 4.2.1,
typescript: 4.7.4
@typescript-eslint/eslint-plugin: 5.34.0
@typescript-eslint/parser: 5.34.0

Is this likely an issue with the plugin or my tsconfig or ....?

Thanks,

Tim

Throws exception when processing specific code (object spread with babel-eslint)

When using the preset in some of my projects I see such an error:

Cannot read property 'type' of undefined
TypeError: Cannot read property 'type' of undefined
    at verifyNodeTypeIsKnown (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:1013:21)
    at reportSideEffects (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:1021:10)
    at node.properties.forEach.subNode (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:814:11)
    at Array.forEach (<anonymous>)
    at Object.reportEffects (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:813:25)
    at reportSideEffects (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:1025:24)
    at Object.reportEffects (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:991:22)
    at reportSideEffects (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:1025:24)
    at node.declarations.node.declarations.forEach.declarator (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js:976:13)
    at Array.forEach (<anonymous>)

Incompatible with @typescript-eslint

When using the @typescript-eslint plugin in tandem with this package, there are UnknownNodeType errors

Unknown node type TSInterfaceDeclaration.
If you are using the latest version of this plugin, please consider filing an issue noting this message, the offending statement, your ESLint version, and any active ESLint presets and plugins  tree-shaking/no-side-effects-in-initialization

The issue appears to be here where you are checking the AST for known node types.

It looks like you should either add typescript specific AST nodes to the known node types, or maybe check for a TS prefix, or skip this check altogether and ignore unknown node types.

Error "x" breaking the linter

I got this very non-informative error:

null
Error: x
    at verifyNodeTypeIsKnown ([...]\no-side-effects-in-initialization.js:1015:13)

I've checked when it blew up and it was this line of code (written in TS):

class ActionMenu extends React.Component<ActionMenuProps, ActionMenuState> {
   // ...
   private boxRef?: HTMLDivElement; // HERE
   // ...
}

Improve error messages

Currently, the errors produced by eslint-plugin-tree-shaking may be accurate but also somewhat technical, i.e. "Could not determine side-effects of…".
Under this issue I want to collect ideas on how to improve this and give better feedback to the user.

Feature request: Support typescript language service as a plugin

I noticed a big problem is Eslint only scanning a single file at a time. If you changed to become a TS server plugin instead then maybe you would have access to the whole project in order to determine if what yyou are importing is pure or not.

Great work, I am excited to see this plugin have a "low noise" configuration in the future.

An in-range update of semantic-release is breaking the build 🚨

The devDependency semantic-release was updated from 15.12.3 to 15.12.4.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

semantic-release is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v15.12.4

15.12.4 (2018-11-30)

Bug Fixes

  • remove unnecessary branch parameter from push function (ffe1062)
Commits

The new version differs by 1 commits.

  • ffe1062 fix: remove unnecessary branch parameter from push function

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Feature request: Support React.forwardRef

Expected

using React.forwardRef shouldn't be a sideEffect and eslint rule should pass on component using React.forwardRef.

Actual

when using React.forwardRef with types in typescript files eslint rule fail on: Cannot determine side-effects of mutating function return value - eslint(tree-shaking/no-side-effects-in-initialization)

for example:
ErrorPage.js: (rule pass)

const ErrorPage = React.forwardRef((props, ref) => (
  <div {...props} ref={ref} />
));

ErrorPage.tsx: (rule fails)

const ErrorPage = React.forwardRef<HTMLDivElement, ErrorPageProps>(
  (props, ref) => <div {...props} ref={ref} />
);

An in-range update of travis-deploy-once is breaking the build 🚨

The devDependency travis-deploy-once was updated from 5.0.8 to 5.0.9.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

travis-deploy-once is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v5.0.9

5.0.9 (2018-09-27)

Bug Fixes

  • use require.resolve to load babel preset (16292d3)
Commits

The new version differs by 2 commits.

  • 16292d3 fix: use require.resolve to load babel preset
  • 858d475 test: add babel-register.js to test coverage

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Don't count 'use strict' as literal

Msg: [eslint] Cannot determine side-effects of executing Literal as a statement (tree-shaking/no-side-effects-in-initialization)

Code:

(function (window) {
	'use strict'

Unsupported logical operator ??

?? is a new operator not supported by this plugin yet.

patch-package patch to fix this:

eslint-plugin-tree-shaking+1.8.0.patch

diff --git a/

node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js b/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js
index 16c42ca..10e4728 100644
--- a/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js
+++ b/node_modules/eslint-plugin-tree-shaking/lib/rules/no-side-effects-in-initialization.js
@@ -150,6 +150,17 @@ const reportSideEffectsInProgram = (context, programNode) => {
         return leftValue
       }
       return getAndReportRight()
+    },
+    '??': (getAndReportLeft, getAndReportRight) => {
+      const leftValue = getAndReportLeft()
+      if (!leftValue.hasValue) {
+        getAndReportRight()
+        return leftValue
+      }
+      if (leftValue.value) {
+        return leftValue
+      }
+      return getAndReportRight()
     }
   }

Feature Request: Lax mode

Right now this plugin seems a little too aggressive for my needs.

Let's look at this small example.

Screen Shot 2021-03-04 at 7 58 03 PM

I am using RxJS that from my understanding is pretty good about tree shaking, and even if they aren't there isn't much I can do from my project to fix their problems and I would rather not have to add a bunch of eslint-disable everywhere.

So I am looking for options that will assume that other modules do not have any side effects.
I just want to make sure that the current module doesn't create any new side effects.

I also might be ignorant of this but does this

export class DeckService {
  private readonly internalDecks$ = new BehaviorSubject<Deck[]>([]);
  public readonly decks$: Observable<Deck[]>;

  constructor() {
    this.decks$ = this.internalDecks$.asObservable();
  }
}

Really differ from this?

export class DeckService {
  private readonly internalDecks$ = new BehaviorSubject<Deck[]>([]);
  public readonly decks$ = this.internalDecks$.asObservable();
}

Or is this just a false positive?

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

feat: support the Terser PURE annotation

Hi, it would be great if you could support the Terser /*@__PURE__*/ annotation since Webpack uses this as well. This would be in addition to or as a replacement for your existing support of /* tree-shaking no-side-effects-when-called */ annotations.

Add a Github page where you can paste code and get tree-shaking errors highlighted

Even though this plugin might be useful for library developers, I see its main use as a tool to manually check why tree-shaking does not work in a particular case. That easiest way to do this would be if there was a web app where you could paste your code and get your errors highlighted as it is done in https://eslint.org/demo/.
If someone has some experience with this or would be interested in helping to set something up this would be greatly appreciated. Bonus points if it is possible to generate links to a pre-filled version of this page because then you could use it as an easy reference when discussing tree-shaking problems in Github issues of Rollup or Webpack.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.