@storybook/angular 9.0.0-beta.1 → 9.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/builders/build-storybook/index.d.ts +2 -16
  2. package/dist/builders/build-storybook/index.mjs +78 -0
  3. package/dist/builders/build-storybook/index.spec.mjs +187 -0
  4. package/dist/builders/build-storybook/schema.json +2 -4
  5. package/dist/builders/start-storybook/index.d.ts +2 -14
  6. package/dist/builders/start-storybook/index.mjs +99 -0
  7. package/dist/builders/start-storybook/index.spec.mjs +186 -0
  8. package/dist/builders/start-storybook/schema.json +3 -6
  9. package/dist/builders/utils/error-handler.mjs +33 -0
  10. package/dist/builders/utils/run-compodoc.mjs +31 -0
  11. package/dist/builders/utils/run-compodoc.spec.mjs +74 -0
  12. package/dist/builders/utils/standalone-options.mjs +1 -0
  13. package/dist/client/angular-beta/AbstractRenderer.mjs +164 -0
  14. package/dist/client/angular-beta/CanvasRenderer.mjs +9 -0
  15. package/dist/client/angular-beta/ComputesTemplateFromComponent.mjs +154 -0
  16. package/dist/client/angular-beta/ComputesTemplateFromComponent.test.mjs +728 -0
  17. package/dist/client/angular-beta/DocsRenderer.mjs +35 -0
  18. package/dist/client/angular-beta/RendererFactory.mjs +50 -0
  19. package/dist/client/angular-beta/RendererFactory.test.mjs +233 -0
  20. package/dist/client/angular-beta/StorybookModule.mjs +23 -0
  21. package/dist/client/angular-beta/StorybookModule.test.mjs +319 -0
  22. package/dist/client/angular-beta/StorybookProvider.mjs +22 -0
  23. package/dist/client/angular-beta/StorybookWrapperComponent.mjs +123 -0
  24. package/dist/client/angular-beta/__testfixtures__/input.component.mjs +73 -0
  25. package/dist/client/angular-beta/__testfixtures__/test.module.mjs +17 -0
  26. package/dist/client/angular-beta/utils/BootstrapQueue.mjs +49 -0
  27. package/dist/client/angular-beta/utils/BootstrapQueue.test.mjs +162 -0
  28. package/dist/client/angular-beta/utils/NgComponentAnalyzer.mjs +84 -0
  29. package/dist/client/angular-beta/utils/NgComponentAnalyzer.test.mjs +386 -0
  30. package/dist/client/angular-beta/utils/NgModulesAnalyzer.mjs +37 -0
  31. package/dist/client/angular-beta/utils/NgModulesAnalyzer.test.mjs +22 -0
  32. package/dist/client/angular-beta/utils/PropertyExtractor.mjs +158 -0
  33. package/dist/client/angular-beta/utils/PropertyExtractor.test.mjs +175 -0
  34. package/dist/client/angular-beta/utils/StoryUID.mjs +38 -0
  35. package/dist/client/argsToTemplate.mjs +55 -0
  36. package/dist/client/argsToTemplate.test.mjs +100 -0
  37. package/dist/client/config.mjs +4 -0
  38. package/dist/client/decorateStory.mjs +45 -0
  39. package/dist/client/decorateStory.test.mjs +301 -0
  40. package/dist/client/decorators.mjs +63 -0
  41. package/dist/client/decorators.test.mjs +157 -0
  42. package/dist/client/docs/__testfixtures__/doc-button/input.mjs +201 -0
  43. package/dist/client/docs/angular-properties.test.mjs +34 -0
  44. package/dist/client/docs/compodoc.js +5 -1
  45. package/dist/client/docs/compodoc.mjs +248 -0
  46. package/dist/client/docs/compodoc.test.mjs +130 -0
  47. package/dist/client/docs/config.mjs +16 -0
  48. package/dist/client/docs/index.mjs +1 -0
  49. package/dist/client/docs/sourceDecorator.mjs +48 -0
  50. package/dist/client/docs/types.mjs +1 -0
  51. package/dist/client/globals.mjs +31 -0
  52. package/dist/client/index.mjs +9 -0
  53. package/dist/client/portable-stories.mjs +26 -0
  54. package/dist/client/preview-prod.mjs +2 -0
  55. package/dist/client/public-types.mjs +1 -0
  56. package/dist/client/render.mjs +14 -0
  57. package/dist/client/types.mjs +1 -0
  58. package/dist/node/index.mjs +3 -0
  59. package/dist/server/__mocks-ng-workspace__/minimal-config/src/main.mjs +2 -0
  60. package/dist/server/__mocks-ng-workspace__/some-config/src/main.mjs +2 -0
  61. package/dist/server/__mocks-ng-workspace__/with-angularBrowserTarget/src/main.mjs +2 -0
  62. package/dist/server/__mocks-ng-workspace__/with-lib/projects/pattern-lib/src/main.mjs +2 -0
  63. package/dist/server/__mocks-ng-workspace__/with-nx/src/main.mjs +2 -0
  64. package/dist/server/__mocks-ng-workspace__/with-nx-workspace/src/main.mjs +2 -0
  65. package/dist/server/__mocks-ng-workspace__/with-options-styles/src/main.mjs +2 -0
  66. package/dist/server/__mocks-ng-workspace__/without-projects-entry/projects/pattern-lib/src/main.mjs +2 -0
  67. package/dist/server/__mocks-ng-workspace__/without-tsConfig/src/main.mjs +2 -0
  68. package/dist/server/angular-cli-webpack.mjs +80 -0
  69. package/dist/server/framework-preset-angular-cli.mjs +81 -0
  70. package/dist/server/framework-preset-angular-docs.mjs +6 -0
  71. package/dist/server/framework-preset-angular-ivy.mjs +56 -0
  72. package/dist/server/plugins/storybook-normalize-angular-entry-plugin.mjs +52 -0
  73. package/dist/server/preset-options.mjs +1 -0
  74. package/dist/server/utils/filter-out-styling-rules.mjs +13 -0
  75. package/dist/server/utils/module-is-available.mjs +9 -0
  76. package/package.json +5 -15
@@ -0,0 +1,48 @@
1
+ import { SourceType } from 'storybook/internal/docs-tools';
2
+ import { useRef, emitTransformCode, useEffect } from 'storybook/preview-api';
3
+ import { computesTemplateSourceFromComponent } from '../../renderer';
4
+ export const skipSourceRender = (context) => {
5
+ const sourceParams = context?.parameters.docs?.source;
6
+ // always render if the user forces it
7
+ if (sourceParams?.type === SourceType.DYNAMIC) {
8
+ return false;
9
+ }
10
+ // never render if the user is forcing the block to render code, or
11
+ // if the user provides code
12
+ return sourceParams?.code || sourceParams?.type === SourceType.CODE;
13
+ };
14
+ /**
15
+ * Angular source decorator.
16
+ *
17
+ * @param storyFn Fn
18
+ * @param context StoryContext
19
+ */
20
+ export const sourceDecorator = (storyFn, context) => {
21
+ const story = storyFn();
22
+ const source = useRef(undefined);
23
+ useEffect(() => {
24
+ if (skipSourceRender(context)) {
25
+ return;
26
+ }
27
+ const { props, userDefinedTemplate } = story;
28
+ const { component, argTypes, parameters } = context;
29
+ const template = parameters.docs?.source?.excludeDecorators
30
+ ? context.originalStoryFn(context.args, context).template
31
+ : story.template;
32
+ if (component && !userDefinedTemplate) {
33
+ const sourceFromComponent = computesTemplateSourceFromComponent(component, props, argTypes);
34
+ // We might have a story with a Directive or Service defined as the component
35
+ // In these cases there might exist a template, even if we aren't able to create source from component
36
+ const newSource = sourceFromComponent || template;
37
+ if (newSource && newSource !== source.current) {
38
+ emitTransformCode(newSource, context);
39
+ source.current = newSource;
40
+ }
41
+ }
42
+ else if (template && template !== source.current) {
43
+ emitTransformCode(template, context);
44
+ source.current = template;
45
+ }
46
+ });
47
+ return story;
48
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import { global } from '@storybook/global';
2
+ /**
3
+ * This file includes polyfills needed by Angular and is loaded before the app. You can add your own
4
+ * extra polyfills to this file.
5
+ *
6
+ * This file is divided into 2 sections:
7
+ *
8
+ * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
9
+ * 2. Application imports. Files imported after ZoneJS that should be loaded before your main file.
10
+ *
11
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
12
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
13
+ * Edge> = 13 on the desktop, and iOS 10 and Chrome on mobile.
14
+ *
15
+ * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
16
+ */
17
+ /**
18
+ * Required to support Web Animations `@angular/animation`. Needed for: All but Chrome, Firefox and
19
+ * Opera. http://caniuse.com/#feat=web-animation
20
+ */
21
+ // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
22
+ // Included with Angular CLI.
23
+ /** APPLICATION IMPORTS */
24
+ /**
25
+ * Date, currency, decimal and percent pipes. Needed for: All but Chrome, Firefox, Edge, IE11 and
26
+ * Safari 10
27
+ */
28
+ // import 'intl'; // Run `npm install --save intl`.
29
+ /** Need to import at least one locale-data with intl. */
30
+ // import 'intl/locale-data/jsonp/en';
31
+ global.STORYBOOK_ENV = 'angular';
@@ -0,0 +1,9 @@
1
+ /// <reference types="webpack-env" />
2
+ import './globals';
3
+ export * from './public-types';
4
+ export * from './portable-stories';
5
+ export { moduleMetadata, componentWrapperDecorator, applicationConfig } from './decorators';
6
+ export { argsToTemplate } from './argsToTemplate';
7
+ // optimization: stop HMR propagation in webpack
8
+ if (typeof module !== 'undefined')
9
+ module?.hot?.decline();
@@ -0,0 +1,26 @@
1
+ import { setProjectAnnotations as originalSetProjectAnnotations, setDefaultProjectAnnotations, } from 'storybook/preview-api';
2
+ import * as INTERNAL_DEFAULT_PROJECT_ANNOTATIONS from './render';
3
+ /**
4
+ * Function that sets the globalConfig of your storybook. The global config is the preview module of
5
+ * your .storybook folder.
6
+ *
7
+ * It should be run a single time, so that your global config (e.g. decorators) is applied to your
8
+ * stories when using `composeStories` or `composeStory`.
9
+ *
10
+ * Example:
11
+ *
12
+ * ```jsx
13
+ * // setup-file.js
14
+ * import { setProjectAnnotations } from '@storybook/angular';
15
+ *
16
+ * import projectAnnotations from './.storybook/preview';
17
+ *
18
+ * setProjectAnnotations(projectAnnotations);
19
+ * ```
20
+ *
21
+ * @param projectAnnotations - E.g. (import projectAnnotations from '../.storybook/preview')
22
+ */
23
+ export function setProjectAnnotations(projectAnnotations) {
24
+ setDefaultProjectAnnotations(INTERNAL_DEFAULT_PROJECT_ANNOTATIONS);
25
+ return originalSetProjectAnnotations(projectAnnotations);
26
+ }
@@ -0,0 +1,2 @@
1
+ import { enableProdMode } from '@angular/core';
2
+ enableProdMode();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import '@angular/compiler';
2
+ import { RendererFactory } from './angular-beta/RendererFactory';
3
+ export const rendererFactory = new RendererFactory();
4
+ export const render = (props) => ({ props });
5
+ export async function renderToCanvas({ storyFn, showMain, forceRemount, storyContext: { component } }, element) {
6
+ showMain();
7
+ const renderer = await rendererFactory.getRendererInstance(element);
8
+ await renderer.render({
9
+ storyFnAngular: storyFn(),
10
+ component,
11
+ forced: !forceRemount,
12
+ targetDOMNode: element,
13
+ });
14
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export function defineMain(config) {
2
+ return config;
3
+ }
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,2 @@
1
+ // To avoid "No inputs were found in config file" tsc error
2
+ export const not = 'empty';
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ // Private angular devkit stuff
3
+ const { generateI18nBrowserWebpackConfigFromContext, } = require('@angular-devkit/build-angular/src/utils/webpack-browser-config');
4
+ const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
5
+ const { filterOutStylingRules } = require('./utils/filter-out-styling-rules');
6
+ const { default: StorybookNormalizeAngularEntryPlugin, } = require('./plugins/storybook-normalize-angular-entry-plugin');
7
+ const { getCommonConfig, getStylesConfig, getDevServerConfig, getTypeScriptConfig, } = require('@angular-devkit/build-angular/src/tools/webpack/configs');
8
+ /**
9
+ * Extract webpack config from angular-cli 13.x.x ⚠️ This file is in JavaScript to not use
10
+ * TypeScript. Because current storybook TypeScript version is not compatible with Angular CLI.
11
+ * FIXME: Try another way with TypeScript on future storybook version (7 maybe 🤞)
12
+ *
13
+ * @param {any} baseConfig Previous webpack config from storybook
14
+ * @param {any} options { builderOptions, builderContext }
15
+ */
16
+ exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }) => {
17
+ /** Get angular-cli Webpack config */
18
+ const { config: cliConfig } = await generateI18nBrowserWebpackConfigFromContext({
19
+ // Default options
20
+ index: 'noop-index',
21
+ main: 'noop-main',
22
+ // Options provided by user
23
+ ...builderOptions,
24
+ styles: builderOptions.styles
25
+ ?.map((style) => (typeof style === 'string' ? style : style.input))
26
+ .filter((style) => typeof style === 'string' || style.inject !== false),
27
+ outputPath: typeof builderOptions.outputPath === 'string'
28
+ ? builderOptions.outputPath
29
+ : (builderOptions.outputPath?.base ?? 'noop-out'),
30
+ // Fixed options
31
+ optimization: false,
32
+ namedChunks: false,
33
+ progress: false,
34
+ buildOptimizer: false,
35
+ aot: false,
36
+ }, builderContext, (wco) => [
37
+ getCommonConfig(wco),
38
+ getStylesConfig(wco),
39
+ getTypeScriptConfig ? getTypeScriptConfig(wco) : getDevServerConfig(wco),
40
+ ]);
41
+ if (!builderOptions.experimentalZoneless && !cliConfig.entry.polyfills?.includes('zone.js')) {
42
+ cliConfig.entry.polyfills.push('zone.js');
43
+ }
44
+ /** Merge baseConfig Webpack with angular-cli Webpack */
45
+ const entry = [
46
+ ...(cliConfig.entry.polyfills ?? []),
47
+ ...baseConfig.entry,
48
+ ...(cliConfig.entry.styles ?? []),
49
+ ];
50
+ // Don't use storybooks styling rules because we have to use rules created by @angular-devkit/build-angular
51
+ // because @angular-devkit/build-angular created rules have include/exclude for global style files.
52
+ const rulesExcludingStyles = filterOutStylingRules(baseConfig);
53
+ const module = {
54
+ ...baseConfig.module,
55
+ rules: [...cliConfig.module.rules, ...rulesExcludingStyles],
56
+ };
57
+ const plugins = [
58
+ ...(cliConfig.plugins ?? []),
59
+ ...baseConfig.plugins,
60
+ new StorybookNormalizeAngularEntryPlugin(),
61
+ ];
62
+ const resolve = {
63
+ ...baseConfig.resolve,
64
+ modules: Array.from(new Set([...baseConfig.resolve.modules, ...cliConfig.resolve.modules])),
65
+ plugins: [
66
+ new TsconfigPathsPlugin({
67
+ configFile: builderOptions.tsConfig,
68
+ mainFields: ['browser', 'module', 'main'],
69
+ }),
70
+ ],
71
+ };
72
+ return {
73
+ ...baseConfig,
74
+ entry,
75
+ module,
76
+ plugins,
77
+ resolve,
78
+ resolveLoader: cliConfig.resolveLoader,
79
+ };
80
+ };
@@ -0,0 +1,81 @@
1
+ import { logger } from 'storybook/internal/node-logger';
2
+ import { AngularLegacyBuildOptionsError } from 'storybook/internal/server-errors';
3
+ import { WebpackDefinePlugin, WebpackIgnorePlugin } from '@storybook/builder-webpack5';
4
+ import { targetFromTargetString } from '@angular-devkit/architect';
5
+ import { logging } from '@angular-devkit/core';
6
+ import { sync as findUpSync } from 'find-up';
7
+ import { getWebpackConfig as getCustomWebpackConfig } from './angular-cli-webpack';
8
+ import { moduleIsAvailable } from './utils/module-is-available';
9
+ export async function webpackFinal(baseConfig, options) {
10
+ if (!moduleIsAvailable('@angular-devkit/build-angular')) {
11
+ logger.info('=> Using base config because "@angular-devkit/build-angular" is not installed');
12
+ return baseConfig;
13
+ }
14
+ checkForLegacyBuildOptions(options);
15
+ const builderContext = getBuilderContext(options);
16
+ const builderOptions = await getBuilderOptions(options, builderContext);
17
+ const webpackConfig = await getCustomWebpackConfig(baseConfig, {
18
+ builderOptions: {
19
+ watch: options.configType === 'DEVELOPMENT',
20
+ ...builderOptions,
21
+ },
22
+ builderContext,
23
+ });
24
+ webpackConfig.plugins = webpackConfig.plugins ?? [];
25
+ webpackConfig.plugins.push(new WebpackDefinePlugin({
26
+ STORYBOOK_ANGULAR_OPTIONS: JSON.stringify({
27
+ experimentalZoneless: builderOptions.experimentalZoneless,
28
+ }),
29
+ }));
30
+ try {
31
+ require.resolve('@angular/animations');
32
+ }
33
+ catch (e) {
34
+ webpackConfig.plugins.push(new WebpackIgnorePlugin({
35
+ resourceRegExp: /@angular\/platform-browser\/animations$/,
36
+ }));
37
+ }
38
+ return webpackConfig;
39
+ }
40
+ /** Get Builder Context If storybook is not start by angular builder create dumb BuilderContext */
41
+ function getBuilderContext(options) {
42
+ return (options.angularBuilderContext ??
43
+ {
44
+ target: { project: 'noop-project', builder: '', options: {} },
45
+ workspaceRoot: process.cwd(),
46
+ getProjectMetadata: () => ({}),
47
+ getTargetOptions: () => ({}),
48
+ logger: new logging.Logger('Storybook'),
49
+ });
50
+ }
51
+ /** Get builder options Merge target options from browser target and from storybook options */
52
+ async function getBuilderOptions(options, builderContext) {
53
+ /** Get Browser Target options */
54
+ let browserTargetOptions = {};
55
+ if (options.angularBrowserTarget) {
56
+ const browserTarget = targetFromTargetString(options.angularBrowserTarget);
57
+ logger.info(`=> Using angular browser target options from "${browserTarget.project}:${browserTarget.target}${browserTarget.configuration ? `:${browserTarget.configuration}` : ''}"`);
58
+ browserTargetOptions = await builderContext.getTargetOptions(browserTarget);
59
+ }
60
+ /** Merge target options from browser target options and from storybook options */
61
+ const builderOptions = {
62
+ ...browserTargetOptions,
63
+ ...options.angularBuilderOptions,
64
+ tsConfig: options.tsConfig ??
65
+ findUpSync('tsconfig.json', { cwd: options.configDir }) ??
66
+ browserTargetOptions.tsConfig,
67
+ };
68
+ logger.info(`=> Using angular project with "tsConfig:${builderOptions.tsConfig}"`);
69
+ return builderOptions;
70
+ }
71
+ /**
72
+ * Checks if using legacy configuration that doesn't use builder and logs message referring to
73
+ * migration docs.
74
+ */
75
+ function checkForLegacyBuildOptions(options) {
76
+ if (options.angularBrowserTarget !== undefined) {
77
+ // Not use legacy way with builder (`angularBrowserTarget` is defined or null with builder and undefined without)
78
+ return;
79
+ }
80
+ throw new AngularLegacyBuildOptionsError();
81
+ }
@@ -0,0 +1,6 @@
1
+ import { hasDocsOrControls } from 'storybook/internal/docs-tools';
2
+ export const previewAnnotations = (entry = [], options) => {
3
+ if (!hasDocsOrControls(options))
4
+ return entry;
5
+ return [...entry, require.resolve('../client/docs/config')];
6
+ };
@@ -0,0 +1,56 @@
1
+ import { join } from 'node:path';
2
+ /**
3
+ * Source :
4
+ * https://github.com/angular/angular-cli/blob/ebccb5de4a455af813c5e82483db6af20666bdbd/packages/angular_devkit/build_angular/src/utils/load-esm.ts#L23
5
+ * This uses a dynamic import to load a module which may be ESM. CommonJS code can load ESM code via
6
+ * a dynamic import. Unfortunately, TypeScript will currently, unconditionally downlevel dynamic
7
+ * import into a require call. require calls cannot load ESM code and will result in a runtime
8
+ * error. To workaround this, a Function constructor is used to prevent TypeScript from changing the
9
+ * dynamic import. Once TypeScript provides support for keeping the dynamic import this workaround
10
+ * can be dropped.
11
+ *
12
+ * @param modulePath The path of the module to load.
13
+ * @returns A Promise that resolves to the dynamically imported module.
14
+ */
15
+ function loadEsmModule(modulePath) {
16
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
17
+ return new Function('modulePath', `return import(modulePath);`)(modulePath);
18
+ }
19
+ /**
20
+ * Run ngcc for converting modules to ivy format before starting storybook This step is needed in
21
+ * order to support Ivy in storybook
22
+ *
23
+ * Information about Ivy can be found here https://angular.io/guide/ivy
24
+ */
25
+ export const runNgcc = async () => {
26
+ let ngcc;
27
+ try {
28
+ ngcc = require('@angular/compiler-cli/ngcc');
29
+ }
30
+ catch (error) {
31
+ ngcc = await loadEsmModule('@angular/compiler-cli/ngcc');
32
+ }
33
+ ngcc.process({
34
+ // should be async: true but does not work due to
35
+ // https://github.com/storybookjs/storybook/pull/11157/files#r615413803
36
+ async: false,
37
+ basePath: join(process.cwd(), 'node_modules'), // absolute path to node_modules
38
+ createNewEntryPointFormats: true, // --create-ivy-entry-points
39
+ compileAllFormats: false, // --first-only
40
+ });
41
+ };
42
+ export const webpack = async (webpackConfig, options) => {
43
+ const framework = await options.presets.apply('framework');
44
+ const angularOptions = (typeof framework === 'object' ? framework.options : {});
45
+ // Default to true, if undefined
46
+ if (angularOptions.enableIvy === false) {
47
+ return webpackConfig;
48
+ }
49
+ return {
50
+ ...webpackConfig,
51
+ resolve: {
52
+ ...webpackConfig.resolve,
53
+ mainFields: ['browser', 'module', 'main'],
54
+ },
55
+ };
56
+ };
@@ -0,0 +1,52 @@
1
+ const PLUGIN_NAME = 'storybook-normalize-angular-entry-plugin';
2
+ /**
3
+ * This plugin is designed to modify the Webpack configuration for Storybook projects that use
4
+ * Angular, specifically to prevent multiple runtime bundle issues by merging 'main' and 'styles'
5
+ * entry points. It ensures that only one runtime bundle is generated to avoid
6
+ * '**webpack_require**.nmd is not a function' errors.
7
+ */
8
+ export default class StorybookNormalizeAngularEntryPlugin {
9
+ constructor(options) {
10
+ this.options = options; // Store options if future configuration is needed
11
+ }
12
+ apply(compiler) {
13
+ compiler.hooks.environment.tap(PLUGIN_NAME, () => {
14
+ // Store the original entry configuration
15
+ const originalEntry = compiler.options.entry;
16
+ // Overwrite the entry configuration to normalize it
17
+ compiler.options.entry = async () => {
18
+ let entryResult;
19
+ // Handle the case where the original entry is a function, which could be async
20
+ if (typeof originalEntry === 'function') {
21
+ try {
22
+ // Execute the function and await its result, in case it returns a promise
23
+ entryResult = await originalEntry();
24
+ }
25
+ catch (error) {
26
+ // Log the error and re-throw it to ensure it's visible and doesn't silently fail
27
+ console.error('Failed to execute the entry function:', error);
28
+ throw error;
29
+ }
30
+ }
31
+ else {
32
+ // If the original entry is not a function, use it as is
33
+ entryResult = originalEntry;
34
+ }
35
+ // Merge 'main' and 'styles' entries if both exist
36
+ if (entryResult && entryResult.main && entryResult.styles) {
37
+ // Combine and deduplicate imports from 'main' and 'styles'
38
+ return {
39
+ main: {
40
+ import: Array.from(new Set([...entryResult.main.import, ...entryResult.styles.import])),
41
+ },
42
+ };
43
+ }
44
+ // If not both 'main' and 'styles' are present, return the original or resolved entry result
45
+ return entryResult;
46
+ };
47
+ });
48
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
49
+ this.compilation = compilation;
50
+ });
51
+ }
52
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ const isStylingRule = (rule) => {
2
+ const { test } = rule;
3
+ if (!test) {
4
+ return false;
5
+ }
6
+ if (!(test instanceof RegExp)) {
7
+ return false;
8
+ }
9
+ return test.test('.css') || test.test('.scss') || test.test('.sass');
10
+ };
11
+ export const filterOutStylingRules = (config) => {
12
+ return config.module.rules.filter((rule) => !isStylingRule(rule));
13
+ };
@@ -0,0 +1,9 @@
1
+ export const moduleIsAvailable = (moduleName) => {
2
+ try {
3
+ require.resolve(moduleName);
4
+ return true;
5
+ }
6
+ catch (e) {
7
+ return false;
8
+ }
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/angular",
3
- "version": "9.0.0-beta.1",
3
+ "version": "9.0.0-beta.11",
4
4
  "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
5
5
  "keywords": [
6
6
  "storybook",
@@ -52,20 +52,15 @@
52
52
  "prep": "rimraf dist && jiti ../../../scripts/prepare/tsc.ts"
53
53
  },
54
54
  "dependencies": {
55
- "@storybook/builder-webpack5": "9.0.0-beta.1",
56
- "@storybook/core-webpack": "9.0.0-beta.1",
55
+ "@storybook/builder-webpack5": "9.0.0-beta.11",
56
+ "@storybook/core-webpack": "9.0.0-beta.11",
57
57
  "@storybook/global": "^5.0.0",
58
- "@types/react": "^18.0.37",
59
- "@types/react-dom": "^18.0.11",
60
- "@types/semver": "^7.3.4",
61
58
  "@types/webpack-env": "^1.18.0",
62
59
  "fd-package-json": "^1.2.0",
63
60
  "find-up": "^5.0.0",
64
- "semver": "^7.3.7",
65
61
  "telejson": "8.0.0",
66
62
  "ts-dedent": "^2.0.0",
67
63
  "tsconfig-paths-webpack-plugin": "^4.0.1",
68
- "util-deprecate": "^1.0.2",
69
64
  "webpack": "5"
70
65
  },
71
66
  "devDependencies": {
@@ -74,7 +69,6 @@
74
69
  "@angular-devkit/build-angular": "^19.1.1",
75
70
  "@angular-devkit/core": "^19.1.1",
76
71
  "@angular/animations": "^19.1.1",
77
- "@angular/cli": "^19.1.1",
78
72
  "@angular/common": "^19.1.1",
79
73
  "@angular/compiler": "^19.1.1",
80
74
  "@angular/compiler-cli": "^19.1.1",
@@ -82,13 +76,9 @@
82
76
  "@angular/forms": "^19.1.1",
83
77
  "@angular/platform-browser": "^19.1.1",
84
78
  "@angular/platform-browser-dynamic": "^19.1.1",
85
- "@types/cross-spawn": "^6.0.2",
86
79
  "@types/node": "^22.0.0",
87
- "@types/tmp": "^0.2.3",
88
- "cross-spawn": "^7.0.3",
89
80
  "rimraf": "^6.0.1",
90
- "tmp": "^0.2.1",
91
- "typescript": "^5.7.3",
81
+ "typescript": "^5.8.3",
92
82
  "webpack": "5",
93
83
  "zone.js": "^0.15.0"
94
84
  },
@@ -106,7 +96,7 @@
106
96
  "@angular/platform-browser": ">=18.0.0 < 20.0.0",
107
97
  "@angular/platform-browser-dynamic": ">=18.0.0 < 20.0.0",
108
98
  "rxjs": "^6.5.3 || ^7.4.0",
109
- "storybook": "^9.0.0-beta.1",
99
+ "storybook": "^9.0.0-beta.11",
110
100
  "typescript": "^4.9.0 || ^5.0.0",
111
101
  "zone.js": ">=0.14.0"
112
102
  },