storybookjs / eslint-plugin-storybook

🎗Official ESLint plugin for Storybook
MIT License
245 stars 52 forks source link

Add `no-uninstalled-addons` rule #95

Closed yannbf closed 2 years ago

yannbf commented 2 years ago

Is your feature request related to a problem? Please describe.

Whenever users register addons in main.js, there's a possibility of: 1 - having typos 2 - registering addons that are not installed (not in package.json)

In either scenario, the users get this current error when running Storybook, which is not helpful at all:

WARN   Failed to load preset: {"type":"presets"} on level 1
ERR! TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received an instance of Object

Describe the solution you'd like

There should be an eslint rule that warns users that addons were registered in main.js but they are not installed.

1 - Process main.js files 2 - Identify the addons field from it 3 - Go through each addon and check whether they exist in package.json(Ideally read once and cached or something like that) 4 - If the addon is not in package.json, report to users

Possible

Additional context

It's important to know the ways you can register an addon:

// .storybook/main.js
module.exports = {
  addons: [
    // default way of registering an addon
    '@storybook/addon-essentials',

    // advanced way of registering an addon
    { 
      name: '@storybook/addon-essentials',
      options: { docs: false }
    }
  ]
}
andrelas1 commented 2 years ago

Hey, I would like to pick that up! I think we can add a solution that handles both scenarios:

  1. Addon is listed but not installed

The message from the plugin: The addon ${addonName} is not installed. Did you forget to install it?

  1. Addon is listed but with a typo (addon-esentials for instance, without the second s).

The addon ${addonName} is not installed. It looks like you mean CORRECT_NAME and not NAME_WITH_TYPO.

We will have to make some assumptions for the second case, such as the name of the addons we expect them to be (@storybook/addon or storybook-addon, for instance), but it's quite doable.

andrelas1 commented 2 years ago

Hey, after working through the feature, I noticed that it would be a bit too complicated to do the typo check properly. Since by checking if the plugin is installed would be already quite a benefit for every user and it would give a hint about a plugin with a typo, I left the typo check outside of this enhancement.

yannbf commented 2 years ago

Thanks a lot @andrelas1 you did an amazing job! Your work has been released in v0.6.0

sneko commented 1 year ago

Hi,

Note that in some cases the rule breaks for no reason:

  1. I installed the package @tomfreudenberg/next-auth-mock
  2. To use the addon I need to list it as @tomfreudenberg/next-auth-mock/storybook in my main.js

So I get:

  24:5  error  The @tomfreudenberg/next-auth-mock/storybook is not installed in docs/. Did you forget to install it or is your package.json in a different location?  storybook/no-uninstalled-addons

Maybe just match a "start with"? Or check the underlying imported file exists?