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

wrong eslint rules when extending from plugins (because 'react-scripts start' uses own, outdated version of plugin) #9083

Closed
tobiaskraus opened this issue May 29, 2020 · 11 comments · May be fixed by admmasters/create-react-app#34 or joseroubert08/create-react-app#55

Comments

@tobiaskraus
Copy link

tobiaskraus commented May 29, 2020

Describe the bug

I added to my CRA with the TypeScript template some ESLint settings, but yarn start complained about errors in rules, which were not part of my eslint settings and which weren't shown up, when running eslint src/**/*.{ts,tsx}

After hours of searching I found the bug:

react-scripts has it's own, outdated version of @typescript-eslint/eslint-plugin (^2.10.0 instead of 3.0.1). That's why extending plugin:@typescript-eslint/recommended resulted in different rules when yarn start ran react-scripts start than eslint src/**/*.{ts,tsx}

Steps to reproduce

yarn add eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin

... actually also the libraries eslint-config-prettier, eslint-plugin-prettier, eslint-plugin-react but doesn't matter to describe the issue here.

In .env I added

EXTEND_ESLINT=true

I added .eslintrc.js (simplified for this issue)

module.exports = {
  parser: "@typescript-eslint/parser", // Specifies the ESLint parser
  extends: [
    "eslint:recommended",
    // Uses the recommended rules from the @typescript-eslint/eslint-plugin
    "plugin:@typescript-eslint/recommended",
  ],
  env: {
    "es6": true,
    "node": true,
  },
  rules: {
  },
};

I removed this in package.json

"eslintConfig": {
    "extends": "react-app"
},

And had these scripts in package.json

"scripts": {
    "start": "react-scripts start",
    ...
    "lint": "eslint src/**/*.{ts,tsx}"
},

Result

  • yarn start gave me warnings & errors for rules @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-use-before-define
  • yarn lint gave me no wwarnings or errors for these rules
  • these rules are not part of plugin:@typescript-eslint/recommended@3.0.1 but part of plugin:@typescript-eslint/recommended@2.XX.X

Expected behavior

When I create my .eslintrc.* and install the eslint plugins I need, I expect that the version of my installed plugins are used, and not some older version of react-scripts' own dependencies.

Proposal

Change react-sccripts/config/webpack.config.js this block:

{
  test: /\.(js|mjs|jsx|ts|tsx)$/,
  enforce: 'pre',
  use: [
    {
      options: {
        cache: true,
        formatter: require.resolve('react-dev-utils/eslintFormatter'),
        eslintPath: require.resolve('eslint'),
        resolvePluginsRelativeTo: __dirname,
        // @remove-on-eject-begin
        ignore: isExtendingEslintConfig,
        baseConfig: isExtendingEslintConfig
          ? undefined
          : {
              extends: [require.resolve('eslint-config-react-app')],
            },
        useEslintrc: isExtendingEslintConfig,
        // @remove-on-eject-end
      },
      loader: require.resolve('eslint-loader'),
    },
  ],
  include: paths.appSrc,
},

ideas

  • Idea A: Maybe an additional .env setting which defines that resolvePluginsRelativeTo will be set to root of app
  • Idea B: resolvePluginsRelativeTo will always be set to app root, if isExtendingEslintConfig is true (.env has EXTEND_ESLINT)

dependencies (not so relevant)

I use yarn in v1.22.0

Before writing this issue, I deleted yarn.lock, node_modules and re-installed.

In my package.json was

"@typescript-eslint/eslint-plugin": "^3.0.2"

In node_modules/react-scripts/package.json was

"@typescript-eslint/eslint-plugin": "^2.10.0",

In yarn.lock

"@typescript-eslint/eslint-plugin@^2.10.0":
  version "2.33.0"
  ....
"@typescript-eslint/eslint-plugin@^3.0.2":
  version "3.0.2"
  ....

In node_modules/@typescript-eslint/eslint-plugin/package.json

"version": "3.0.2",

In node_modules/react-scripts/node_modules/@typescript-eslint/eslint-plugin/package.json

"version": "2.34.0",

yarn --version v1.22.0

Environment (not so relevant)

current version of create-react-app: 3.4.1
  running from /Users/XXX/.npm/_npx/43288/lib/node_modules/create-react-app

  System:
    OS: macOS 10.15.4
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 14.3.0 - /usr/local/bin/node
    Yarn: 1.22.0 - /usr/local/bin/yarn
    npm: 6.14.4 - /usr/local/bin/npm
  Browsers:
    Chrome: 83.0.4103.61
    Firefox: Not Found
    Safari: 13.1
  npmPackages:
    react: ^16.13.1 => 16.13.1
    react-dom: ^16.13.1 => 16.13.1
    react-scripts: Not Found
  npmGlobalPackages:
    create-react-app: Not Found
@tobiaskraus
Copy link
Author

This proposal could also fix in future issues of outdated eslint plugins like

Alternative: Again only @typescript-eslint/eslint-plugin gets bumped from version 2 to 3, and apps using CRA still cannot use own eslint-plugins or own version of them without ejecting. This is easy to do, but for me it sounds worth the effort to try implementing one of the mentioned ideas above to allow some flexibility.

Also if there were an option in .env like RESOLVE_ESLINT_PLUGINS_FROM_ROOT, it would be maybe more clear to people, that there are 2 ways to go, and that you could fell into a trap like me, where your installed plugins are not used by react-scripts start. Especially annoying when having an own npm script like me eslint src/**/*.{ts,tsx}which get's called by some CI pipelines, and this script gets another result than react-scripts start.

@miafoo
Copy link

miafoo commented Jun 8, 2020

I've got a similar case, except I've got errors and warnings reported by eslint (for example @typescript-eslint/explicit-function-return-type: "error"), but CRA runs without reporting any of them.

Edit: After deleting node_modules and package-lock.json it now reports errors when running CRA, but now I'm having the same issue as OP.

@selfdocumentingcode
Copy link

I am experiencing this issue myself.
I created a repo with a CRA project where this can be tested.
https://github.com/razvanmandache/vscode-eslint-test

Running "npm run lint" does not show any warning or errors.
Running "npm start" shows the warning Missing return type on function @typescript-eslint/explicit-function-return-type in ./src/useCustom.ts

@stale
Copy link

stale bot commented Aug 22, 2020

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

@stale stale bot added the stale label Aug 22, 2020
@stale
Copy link

stale bot commented Aug 29, 2020

This issue has been automatically closed because it has not had any recent activity. If you have a question or comment, please open a new issue.

@stale stale bot closed this as completed Aug 29, 2020
@hladf
Copy link

hladf commented Sep 15, 2020

Any news about?
I'm having the same issue.
In the Azure pipelines, react-scripts build uses their own @typescript-eslint version, that is very older than mine:

...\project\web> npm ls @typescript-eslint/eslint-plugin
+-- @typescript-eslint/eslint-plugin@4.0.1
`-- react-scripts@3.4.3
  `-- @typescript-eslint/eslint-plugin@2.34.0

@amorgan0
Copy link

amorgan0 commented Sep 15, 2020

We are also experience this issue. The lint errors when running "yarn start" are not the same as when running "yarn lint" (with a custom eslint config). Most developers are only seeing and fixing the yarn start errors which appear to be backed into create-react-app somewhere.

@hladf
Copy link

hladf commented Sep 17, 2020

I found a good solution!

Fixed this problem with customize-cra and react-app-rewired disabling Eslint inside config-overrides.js.
But you can pass your own eslintRc config to them.

const { override, disableEsLint, useEslintRc } = require('customize-cra');

const path = require('path');

module.exports = override(
  // choose between disable or pass eslintRc
  disableEsLint(), 
  useEslintRc(path.resolve(__dirname, '.eslintrc.json')),
);

@namoscato
Copy link

It looks like this will be resolved in react-scripts@4.0 with #9434 and #9587.

@InSuperposition
Copy link

I ran into this issue while following the CRA instructions to use prettier (with husky, lint-stage). After enabling debug for ESLint in VS Code's output window for ESlint ( ) stated I was missing 2 packages:

eslint-plugin-react and eslint-plugin-react-hooks which are peerDependencies of eslint-config-create-react-app

deleting my lock file (package-lock.json) and then npm i solved my issue.

@0xdevalias
Copy link

0xdevalias commented Apr 28, 2021

deleting my lock file (package-lock.json) and then npm i solved my issue.

@InSuperposition Thanks for this! It helped me narrow down the issue, and while deleting our package-lock.json wasn't something we were willing to do, I found that by using npm dedup it also seemed to solve the issue for us (see sparkletown/sparkle#1102 (comment)):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants