storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.53k stars 9.15k forks source link

[Bug]: Eslint new flat configuration support #24326

Open benjaminrindaroy opened 9 months ago

benjaminrindaroy commented 9 months ago

Describe the bug

Storybook fails to read new eslint configuration.

Eslint is planning to remove the old .eslintrc.json config setup and going to use eslint.config.js from version 9 on. As of version 8 it still supports current supported .eslintrc.json in storybook. More reading on eslint page here

For projects using storybook that would like to future-proof eslint and change over to the new config system, I wish to report issue to work on this.

Further reading on the new config setup:

Terminal error On this terminal print you can se that the disable comment to supress eslint rules gets an error because the eslint confiugration is not read from eslint.config.js with all its plugins (in this case @typescript-eslint)

yarn run v1.22.19
$ storybook dev -p 6006
@storybook/cli v7.4.5

WARN No story files found for the specified pattern: src/**/*.mdx
info => Serving static files from ././public at /
info => Starting manager..
info Addon-docs: using MDX2
info => Loading Webpack configuration from node_modules/react-scripts
info => Removing existing JavaScript and TypeScript rules.
info => Modifying Create React App rules.
info => Using default Webpack5 setup
<i> [webpack-dev-middleware] wait until bundle finished
99% end closing watch compilationWARN Force closed preview build
[ESLintError: [eslint] 
src/Button/Button.stories.tsx
  Line 5:1:  Definition for rule '@typescript-eslint/no-explicit-any' was not found  @typescript-eslint/no-explicit-any

src/Button/Button.tsx
  Line 12:3:  Definition for rule '@typescript-eslint/no-explicit-any' was not found  @typescript-eslint/no-explicit-any

Search for the keywords to learn more about each error.]

WARN Broken build, fix the error above.
WARN You may need to refresh the browser.

No issues found.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

To Reproduce

You can test this code using storybook with the new flat config system.

Also you can test this using this simple code: https://github.com/benjaminrindaroy/storybook-eslint-flat-config

Be sure to run yarn install after you fetch the repo. This project is a fresh install of storybook.

System

Environment Info:

  System:
    OS: macOS 13.5.2
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 20.2.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 9.6.6 - /usr/local/bin/npm
  Browsers:
    Chrome: 116.0.5845.187
    Safari: 16.6
  npmPackages:
    @storybook/addon-essentials: ^7.4.5 => 7.4.5 
    @storybook/addon-interactions: ^7.4.5 => 7.4.5 
    @storybook/addon-links: ^7.4.5 => 7.4.5 
    @storybook/addon-onboarding: ^1.0.8 => 1.0.8 
    @storybook/blocks: ^7.4.5 => 7.4.5 
    @storybook/preset-create-react-app: ^7.4.5 => 7.4.5 
    @storybook/react: ^7.4.5 => 7.4.5 
    @storybook/react-webpack5: ^7.4.5 => 7.4.5 
    @storybook/testing-library: ^0.2.1 => 0.2.1

Additional context

If anyone counters this, there is a workaround in order to make storybook run. But you have create a .eslintrc.json. Still it defeats the purpose using the new flat config.

Put any plugins that the disable-comments are using. For example:

// eslint-disable-next-line @typescript-eslint/no-explicit-any - needs the @typescript-eslint eslint plugin. // eslint-disable-next-line import/no-extraneous-dependencies - needs the import eslint plugin // eslint-disable-next-line react-hooks/exhaustive-deps - needs the react eslint plugin ...etc

So in order for my reproduce code to work for the workaround I need to create a .eslintrc.json with these settings:

{
  "root": true,
  "extends": ["eslint:recommended"],
  "parser": "@typescript-eslint/parser",
  "parserOptions": { "project": ["./tsconfig.json"] },
  "plugins": ["@typescript-eslint", "react", "import"],
  "ignorePatterns": ["*"]
}

The caveat of config above is that it ignores all files. But as long as you use the flat config in vscode linter, and eslint CLI. (you can set the .env rule on/off by using the ESLINT_USE_FLAT_CONFIG enviroment flag). Of course you can put your rules back in the .eslintrc.json that you use in the new eslint.config.js.

wireless25 commented 7 months ago

Hi @benjaminrindaroy

There is a FlatCompat class provided by Eslint, which can help with issues like the one you describe. With the FlatCompat, using "old style" Eslint configs inside a flat config is possible. It's not ideal, but for now, until all your plugins officially support flat config, it's a good workaround.

import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat()

export default [
  // other flat configs
  ...compat.config({
    extends: [
      'plugin:storybook/recommended',
      // other extends
    ],
    // .eslintignore is not supported with flat config, make sure to ignore also other build and test folders
    ignorePatterns: ['!.storybook', 'storybook-static'],
  })
]

I did not test this in your demo repo, but used this approach in a project at work, and had no issues so far.