storybook: [Bug]: NgModule is imported twice
Describe the bug
When an NgModule
follows the forRoot
pattern (https://angular.io/guide/singleton-services#prevent-reimport-of-the-greetingmodule), the module appears to be loaded twice and produces a runtime error indicating that the module was already loaded.
TestModule is already loaded. Import it in the AppModule only
Error: TestModule is already loaded. Import it in the AppModule only
at new TestModule (http://localhost:6006/app-test-stories.iframe.bundle.js:61:13)
at Object.TestModule_Factory [as useFactory] (ng:///TestModule/ɵfac.js:4:10)
at Object.factory (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:43968:32)
at R3Injector.hydrate (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:43886:29)
at R3Injector.get (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:43787:23)
at injectInjectorOnly (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:36619:29)
at ɵɵinject (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:36623:59)
at useValue (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:43585:25)
at R3Injector.resolveInjectorInitializers (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:43827:9)
at new EnvironmentNgModuleRefAdapter (http://localhost:6006/vendors-node_modules_storybook_addon-docs_angular_index_js-node_modules_storybook_addon-essen-170b5a.iframe.bundle.js:55368:14)
Note this pattern works fine in Angular 15 environment.
To Reproduce
// test.module.ts
import {
ModuleWithProviders,
NgModule,
Optional,
SkipSelf,
} from '@angular/core';
@NgModule()
export class TestModule {
constructor(@Optional() @SkipSelf() parentModule?: TestModule) {
if (parentModule) {
throw new Error(
'TestModule is already loaded. Import it in the AppModule only'
);
}
}
static forRoot(): ModuleWithProviders<TestModule> {
return {
ngModule: TestModule,
providers: [],
};
}
}
// test.stories.ts
import { Component } from '@angular/core';
import { moduleMetadata, type Meta, type StoryFn } from '@storybook/angular';
import { TestModule } from './test.module';
@Component({
selector: 'app-test',
template: ``,
})
class TestComponent {}
export default {
title: 'Module Test',
component: TestComponent,
decorators: [moduleMetadata({ imports: [TestModule.forRoot()] })],
} as Meta;
const Template: StoryFn<TestComponent> = (args: TestComponent) => ({
props: args,
});
export const Test = Template.bind({});
System
Environment Info:
System:
OS: Windows 10 10.0.22621
CPU: (24) x64 AMD Ryzen 9 3900X 12-Core Processor
Binaries:
Node: 18.14.2 - C:\dev\nodejs\node.EXE
npm: 9.5.0 - C:\dev\nodejs\npm.CMD
Browsers:
Chrome: 110.0.5481.104
Edge: Spartan (44.22621.1265.0), Chromium (110.0.1587.57)
npmPackages:
@storybook/addon-actions: 7.0.0-beta.55 => 7.0.0-beta.55
@storybook/addon-essentials: 7.0.0-beta.55 => 7.0.0-beta.55
@storybook/addon-interactions: 7.0.0-beta.55 => 7.0.0-beta.55
@storybook/addon-links: 7.0.0-beta.55 => 7.0.0-beta.55
@storybook/angular: 7.0.0-beta.55 => 7.0.0-beta.55
@storybook/builder-webpack5: 7.0.0-beta.55 => 7.0.0-beta.55
@storybook/testing-library: ^0.0.13 => 0.0.13
Additional context
Is it possible that the @SkipSelf
is not being respected on the Module constructor parameter? Possibly related to this? https://github.com/storybookjs/storybook/issues/21243
Is it appropriate to import forRoot
modules in the Story metadata? Do we need a “special” property for root imports perhaps?
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 20 (11 by maintainers)
@jinder Please follow the migration guide: https://github.com/storybookjs/storybook/blob/v7.0.0-rc.11/MIGRATION.md#angular-application-providers-and-modulewithproviders