Git Product home page Git Product logo

eslint-plugin-react-perf's Introduction

eslint-plugin-react-perf

Performance-minded React linting rules for ESLint (motivated by esamatti's post "React.js pure render performance anti-pattern").

Installation

$ npm i eslint-plugin-react-perf

Add plugins section and specify eslint-plugin-react-perf as a plugin.

{
  "plugins": ["react-perf"]
}

List of supported rules

Configuration

As of v3.3.0, each eslint-plugin-react-perf rule supports configuration to control whether native elements (lower case first letter React components) are ignored.

With this configuration, all native elements are ignored for this rule:

{
  "react-perf/jsx-no-new-object-as-prop": [
    "error",
    {
      "nativeAllowList": "all"
    }
  ]
}

With this configuration, the "style" attribute is ignored for native elements for this rule:

{
  "react-perf/jsx-no-new-object-as-prop": [
    "error",
    {
      "nativeAllowList": ["style"]
    }
  ]
}

Recommended

This plugin exports a recommended configuration that enforce React good practices.

To enable this configuration use the extends property in your .eslintrc config file:

{
  "extends": ["plugin:react-perf/recommended"]
}

See ESLint documentation for more information about extending configuration files.

The rules enabled in this configuration are:

All

This plugin also exports an all configuration that includes every available rule.

{
  "plugins": [
    "react-perf"
  ],
  "extends": ["plugin:react-perf/all"]
}

Test anti-patterns in runtime

Try out cvazac/test-ref-pattern.

License

eslint-plugin-react-perf is licensed under the MIT License.

eslint-plugin-react-perf's People

Contributors

anajavi avatar cvazac avatar dependabot[bot] avatar robmeyer avatar trevorburnham avatar vbud avatar znewton 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

eslint-plugin-react-perf's Issues

Handling prop variables in tests

On recently upgrading, we found that our Jest/Enzyme tests have a bunch of new ESLint errors. Tests like:

describe('some component', () => {
  it('does the correct thing when color is red', () => {
    const color = 'red';
    const wrapper = shallow(<SomeComponent color={color} />);
    // ...
  });
});

Need to be re-written as:

const color = 'red';

describe('some component', () => {
  it('does the correct thing when color is red', () => {
    const wrapper = shallow(<SomeComponent color={color} />);
    // ...
  });
});

This is pretty far from ideal. I don't think that we will want to hoist all of test prop variables. It would be very difficult to read/reason about large test suites if we obey this rule there.

We're going to disable this plugin for our tests for now, but it seems like this might be something that should be handled out-of-the-box by the plugin in some way.

  • Is there a way for findRelevantNodes to determine that the variable is declared in a non-React-component function? I'm not sure this is possible, but maybe there's a way.
  • Could we maybe use some kind of callback exclusion list in the vein of #19?
  • Should we be dealing with this in some other way? Or is it just preferred to turn the rules off for test files?

Compiler

I wonder, could this plugin be implemented as a tsserver plugin so that I can write code like prop={{ blah: 123 }} with no problems.. it would just compile to JS with it hoisted.

Error using with atom

my .eslintrc:

{ "extends": "eslint-config-airbnb",
  "env": {
    "browser": true,
    "node": true,
    "mocha": true
  },
  "rules": {
    "react/no-multi-comp": 0,
    "import/default": 0,
    "import/no-duplicates": 0,
    "import/named": 0,
    "import/namespace": 0,
    "import/no-unresolved": 0,
    "import/no-named-as-default": 2,
    "comma-dangle": 0,  // not sure why airbnb turned this on. gross!
    "indent": [2, 2, {"SwitchCase": 1}],
    "no-console": 0,
    "no-alert": 0,
    "no-unused-vars": 1, // set to warning instead of error (better for development)
    "id-length": [3, {"min": 2, "properties": "never", "exceptions": ["t", "_", "i", "j", "k"]}], // allow underscore
    "react-perf/jsx-no-new-object-as-prop": 1,
    "react-perf/jsx-no-new-array-as-prop": 1,
    "react-perf/jsx-no-new-function-as-prop": 1,
    "react-perf/jsx-no-jsx-as-prop": 1,
  },
  "plugins": [
    "react", "import", "react-perf",
  ],
  "settings": {
    "import/parser": "babel-eslint",
    "import/resolve": {
      "moduleDirectory": ["node_modules", "src"]
    },
  },
  "globals": {
    "__DEVELOPMENT__": true,
    "__CLIENT__": true,
    "__SERVER__": true,
    "__DISABLE_SSR__": true,
    "__DEVTOOLS__": true,
    "__API_PATH__": true,
    "webpackIsomorphicTools": true
  }
}

Atom throws the following error:

Error: Error while loading rule 'react-perf/jsx-no-new-object-as-prop': ruleCreator is not a function

TypeError: Error while loading rule 'react-perf/jsx-no-new-object-as-prop': ruleCreator is not a function
    at /home/tim/workspace/projects/sapientia-web/src/app/node_modules/eslint/lib/eslint.js:692:28
    at Array.forEach (native)
    at EventEmitter.module.exports.api.verify (/home/tim/workspace/projects/sapientia-web/src/app/node_modules/eslint/lib/eslint.js:671:16)
    at processText (/home/tim/workspace/projects/sapientia-web/src/app/node_modules/eslint/lib/cli-engine.js:230:27)
    at CLIEngine.executeOnText (/home/tim/workspace/projects/sapientia-web/src/app/node_modules/eslint/lib/cli-engine.js:686:26)
    at Object.execute (/home/tim/workspace/projects/sapientia-web/src/app/node_modules/eslint/lib/cli.js:162:36)
    at lintJob (/home/tim/.atom/packages/linter-eslint/lib/worker.js:38:10)
    at /home/tim/.atom/packages/linter-eslint/lib/worker.js:75:20
    at Emitter.emit (/home/tim/.atom/packages/linter-eslint/node_modules/sb-event-kit/lib/emitter.js:70:19)
    at /home/tim/.atom/packages/linter-eslint/node_modules/sb-communication/lib/main.js:22:23

Support for eslint v8

The eslint ecosystem support for v8 is now pretty strong, and this library is the only remaining one in my stack requiring eslint 7.
Could you add support for it ?
Thanks in advance!

The linter should also warn against bad practices inside hooks

I expect the lint to also work inside React hooks functions:

Every hook function (which is a function named use* should not constantly return a new reference (which is an object/function/array/JSX which is not created outside the hook nor inside a useMemo/useCallback).

Exceptions option to jsx-no-new-object-as-prop and jsx-no-new-array-as-prop

Emotion adds the possibility to pass a css prop to all components that takes an object (of styling). It gets hoisted away with their babel plugin.

It would be nice to not have to globally disable the jsx-no-new-object-as-prop and jsx-no-new-array-as-prop (css prop can take an array also for style composition) rules or add a disable comment everywhere I add css πŸ˜….

I am thinking something like this:

rules: {
  'jsx-no-new-object-as-prop': [
    'error', 
    { 
      exceptProps: ['css'], 
    }
  ],
}

or

rules: {
  'jsx-no-new-object-as-prop': ['error', 'css'],
}

or

rules: {
  'jsx-no-new-object-as-prop': ['error', ['css']],
}

Disable rule for react-router-dom <Route/> element.

I've been having problems with the Route component of react-router-dom. I saw a couple of comments on Reddit and some internet forums about a way to solve the warning/error that the jsx-no-jsx-as-prop rule throws, but honestly, it makes the code too complicated just to not get that error. It would be a good idea to ignore this component, since to keep a cleaner code, at least in this case this rule does not help much. Maybe it would be even better to have a function that gives us the possibility to put something like:

{
ignoreList: [β€œRoute”],
}

I am not an expert, but I think that something like this would work better, since I don't know if there are other components out there that need something like this and instead of helping it would hurt the developer, but disabling this rule is not an option, because it is very useful in most cases.

image

Question about the react-perf/jsx-no-new-object-as-prop rule

Hi guys,

thanks for this great plugin! :-). I recently updated the library to version 3.1.0 and first of all, I was pleased with the new rules. But then I had an issue while refactoring the code:

I easily can refactor the "new objects" which are not related to the props:

render() {
   const style = {color: red};
    return (<div style={style} />)
}

No Problem. But I can't remove the "new objects" if they're related to the props because it has to be a new object in this case :

render() {
  const style = {left: this.props.left};
   return (<div style={style} />)
}

In our application, we have to calculate many inline styles (which can not be replaced by pure CSS). I don't want to disable the rule (by comment) above all style attributes, neither I want to disable the rule completely because it makes total sense in our project.
Is there a solution to this?

thank you very much

nativeAllowList use case

Hey there. I was just checking out the changes in 3.3.0.
I'm wondering what the motivation is for the nativeAllowList.
Are there no performance costs of passing objects/arrays to native attributes, or is there another reason one might want to allow them?

Question about the react-perf/jsx-no-new-object-as-prop rule [functions]

So, "JSX attribute values should not contain functions created in the same scope"

How I can use function toggleById if it uses open and close functions, passed from ContainerComponent props.

If I create this function out of ContainerComponent scope, how open and close will be passed into it?

const ContainerComponent = ({ open, close }) => {
    const toggleById = (id) => {
        if (id === 'some_id') open()
        else close()
    }

    return <OtherComponent toggleById={toggleById} />
}

Support for non-JSX render functions

Hi!

I just wondered if you had thought of also supporting non-JSX usages of React, where object/function identity is still a performance concern?

Thanks,
Oliver

add an `allowList` like `nativeAllowList` that allows all custom nodes to have allowed exceptions.

emotion allows css={[aRules, bRules]} and does the right thing for re-rendering, so it should not be flagged as a performance issue. We can turn this off for native elements like div, but css is allowed on any element, including custom elements.

There are other examples like this, for example, I can accept style on a custom element and pass it unchanged to the native one, and so would make sense to allow style as an exception on custom elements too.

cleanup warning

The react/require-extension rule is deprecated. Please use the import/extensions rule from eslint-plugin-import instead.

react-perf/jsx-no-jsx-as-prop listed as part of `recommended` in README.md, but isn't

Commit 2d81814 added the new jsx-no-jsx-as-prop rule and added it immediately to the recommended configuration. However, commit 8f121da then removed it from recommended, notably without updating the README.md.

I could submit a pull request to update the README.md to match the code. Before I do that, though, I was wondering if there's any context on why this was not a recommended rule? Commit 8f121da doesn't provide any context

Support for Eslint 4

Hello,
the plugin currently not supports the newest version of Eslint. Are you able to fix this?

npm ERR! peer dep missing: eslint@^2.0.0 || ^3.0.0, required by [email protected]

Thanks!

Release notes

Please write release notes to explain what changed from version to version. Either a commented git tag, or a changelog file.
Thank you!

Support for eslint@^7.x.x

@cvazac
In yarn install logs in ci/cd I see the warning:

warning " > [email protected]" has incorrect peer dependency "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0".

Screenshot 2020-07-13 16 00 01

We have eslint 7 installed and most of other plugins already support eslint 7

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.