storybook: [Bug]: Storybook 7.5.3 -> Type [component] is part of the declarations of 2 modules: [module] and StorybookComponentModule!
Describe the bug
I’m migrating our solution from mdx (1.x) stories to a new modern way (using stories.ts files).
My first attempt is to migrate a few stories about external customized components (es Kendo Components) to straightforward stories.
So basically I have a story like:
import { type Meta, type StoryObj, moduleMetadata } from '@storybook/angular';
import { DropDownListComponent, DropDownListModule } from '@progress/kendo-angular-dropdowns';
// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction
const meta: Meta<DropDownListComponent> = {
title: 'Kendo/DropDownList',
component: DropDownListComponent,
decorators: [
moduleMetadata({
imports: [DropDownListModule]})
],
tags: ['autodocs'],
render: (args: DropDownListComponent) => ({
props: {
...args,
},
})
};
export default meta;
type Story = StoryObj<DropDownListComponent>;
// More on writing stories with args: https://storybook.js.org/docs/angular/writing-stories/args
export const Normal: Story = {
args: {
data: ['X-Small', 'Small', 'Medium', 'Large', 'X-Large', '2X-Large']
},
};
Unfortunately, I got the error:
Error: Type DropDownListComponent is part of the declarations of 2 modules: DropDownListModule and StorybookComponentModule! Please consider moving DropDownListComponent to a higher module that imports DropDownListModule and StorybookComponentModule. You can also create a new NgModule that exports and includes DropDownListComponent then import that NgModule in DropDownListModule and StorybookComponentModule.
To Reproduce
Please clone repo:
https://github.com/meriturva/Storybook2ModulesError
just run: npm run storybook
and go to page: http://localhost:6006/?path=/docs/kendo-dropdownlist--docs
System
No response
Additional context
The same issue is already described:
https://github.com/storybookjs/storybook/issues/23669 https://github.com/storybookjs/storybook/issues/22282 https://github.com/storybookjs/storybook/issues/19289
but no one in version 7.5x
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Comments: 16 (10 by maintainers)
I think I see the problem, but I would need to debug further to know if this can be fixed, without affecting the more common use case.
You are creating a story for a dependency’s component, which is not what Storybook expects. Storybook expects you to be adding stories for your project’s components. Storybook iterates the NgModules, to see if you imported a module that already declared the component, when creating the Story’s NgModule, so the Story’s NgModule doesn’t declare it a second time. Without looking into it more, I don’t know why, but the reflection utility that is parsing the metadata is returning the declarations as
declarations: [[DropDownListComponent]]
forDropDownListModule
and Storybook is expectingdeclarations: [DropDownListComponent]
. I will take a look and see if we can update the code that searches for declarations to handle components from dependencies, but Storybook isn’t expecting users to document external dependencies components. Even if the multiple declarations error is fixed, you still won’t get any of the benefits, such as auto-generated controls for inputs and actions for outputs, since that info is parsed from the source files.This is typically is solved by using the dependency component in a component from your project, like dependencies should be used.
Workaround if you still want to do it directly, even though I don’t recommend it: You are probably missing out on most of the benefits of specifying a
component
in yourMeta
that isn’t from your sources, since the types data is currently gathered bycompodoc
and it isn’t generating for anything innode_modules
. So, you could exclude thecomponent
property and just render the component yourself.The following is how I made your code work:
@meriturva The
class
property should be excluded in the first story, because theclass
property is undefined inargs
. In your case, you are passingargs
and withoutclass
defined the function has no way of knowing about it. Even if the property was known, such as the prop being in theincludes
option, the following line is where it would be filtered out: https://github.com/storybookjs/storybook/blob/837936a2b258fdc4a095c67b4d1c0fb9304cb5d1/code/frameworks/angular/src/client/argsToTemplate.ts#L64That sort of limitation is why I haven’t actually switched to
argsToTemplate
in my project, yet. I had started working on a smarter implementation a few years ago, but never finished it. I sort of felt like I was overthinking the problem, but I started using it again last weekend and I am trying to come up with something using more than just theargs
and is still simple to use. My implementation has different limitations that I want to try and avoid before I would propose it as a solution, though, so I wouldn’t say I have something better, yet.The error is resolved together with the initial Angular problem. Storybook 7.6.0-alpha.5 will incorporate the changes as soon as it is released