storybook: [Bug]: Unable to index files: Duplicate stories with id: example-button--primary

Describe the bug

Given that Storybook by default includes node_modules when indexing stories, plus the fact that Storybook ships example stories in its node_modules, it might cause indexing errors in some user projects when they specify very broad story globs in their main.js file, resulting in the following error:

image

Storybook 6 also included node_modules, but would fail differently:

image

To Reproduce

Create a new Storybook project/sandbox, then replace the stories glob to be more broad, rather than specifying the src scope:

const config = {
-  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
+  stories: ['../**/*.mdx', '../**/*.stories.@(js|jsx|ts|tsx)']
}

Same issue applies for the new entry format:

stories: [{
    directory: '../',
    files: '**/*.@(mdx|stories.@(js|jsx|ts|tsx))'
}]

Here’s a link to the reproduction

System

No response

Additional context

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 8
  • Comments: 26 (6 by maintainers)

Most upvoted comments

Looks like I’ve got similar issue image

The problem was in stories prop. I do not have src folder and thus I included all folders from root level stories: ['../**/*.stories.@(js|jsx|ts|tsx)'],. But on that level I also have node_modules and storybook tried to add stories from it as well

people upgrading from 6.5 are also upgrading to SSV7, and that’s what’s causing the change in behavior.

If you, like me, had no idea what this means then here is the tl;dr:

Add the following to your storybook config:

  features: {
    storyStoreV7: false,
  },

Details here: https://storybook.js.org/docs/react/configure/overview#on-demand-story-loading

Looks like I’ve got similar issue image

The problem was in stories prop. I do not have src folder and thus I included all folders from root level stories: ['../**/*.stories.@(js|jsx|ts|tsx)'],. But on that level I also have node_modules and storybook tried to add stories from it as well

THANK YOU!! 🎉

Ta-da!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.1.0-alpha.29 containing PR #22873 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb@next upgrade --prerelease

I saw the same issue, i am using the nextjs framework. What I found, is that if my story files where anywhere but under ./stories/ it would throw this error

For example: stories: ["…/stories//*.mdx", "…/stories//.stories.@(js|jsx|ts|tsx)"] works fine ['…/**/.stories.mdx’, ‘…/**/*.stories.@(js|jsx|ts|tsx)’] <- this would throw the duplication error.

Hope that helps

Hey there @morganney, thanks for sharing your use case. This issue was happening because Storybook included node_modules by default in its indexing, and it could end up clashing if your stories matched the same id of example stories from node_modules. This is not the case anymore, which is why this issue is closed.

It seems like in your use case you want to create story files that do not follow a convention (which existed since the beginning of Storybook, and it’s the only way we display and recommend in our documentation), and want Storybook to be able to identify those files as Storybook specific. You have the first use case I’ve ever seen where a user wants to define story files as *.tsx instead of *.(stories|story).tsx.

To give you some context, in previous versions of Storybook, before storyStoreV7, the way you created stories was imperative, where you have to call Storybook’s apis. In that case, even if you told Storybook that any *.tsx is a story, it would only do something if those files contained those Storybook apis (though it would be quite bad for performance because Storybook would have to evaluate non-related files as well).

In Storybook 7, the way you create stories is declarative, with a meta (default export) and stories (named exports). These are statically analyzed by Storybook’s default indexers, and Storybook will only know that they are stories because they follow a convention. Had Storybook not had such convention, it would treat any file that has both named + default exports (which is common in React components, for instance) as a story file, and that would easily cause side effects and problems.

I am not sure why one would not want to follow the convention, which:

  • helps team members understand the purpose of the file without having to look into its contents;
  • aligns with any material online, be it blog posts, our documentation, youtube videos etc;
  • works with our eslint-plugin, which can be quite helpful in Storybook projects;
  • works with tool integrations that help visualize such files as stories (e.g. display Storybook icons) image

But if you really want to do this (though I do not recommend), you can look into our docs to create a custom story indexer, to treat the files the way you’d want:

https://storybook.js.org/docs/react/configure/sidebar-and-urls#story-indexers

Hopefully this helps!

You have the first use case I’ve ever seen where a user wants to define story files as *.tsx instead of *.(stories|story).tsx.

I’ve used storybook for years and never once named my story files with .stories|story, the glob just worked. This is the first version I’ve used that seems to want to enforce the naming convention.

I am not sure why one would not want to follow the convention

Because I should be able to use my own conventions. Why support a glob at all then?

Anyway, as usual with every storybook install I’ve undergone, I’ve found a workaround for unexpected gotchas from anything but a straightforward install.

Hey @jimmy-dee that’s great info! Could you provide us a minimal repro of the issue? We now have a website to make it easier to create repros: https://storybook.new/

Thank you!