Skip to content

Commit

Permalink
Merge pull request #20043 from storybookjs/valentin/fix-angular-15-in…
Browse files Browse the repository at this point in the history
…compatibility-sb-6.5.x

Fix "__webpack_require__.nmd is not a function issue" in Angular 15
  • Loading branch information
shilman committed Dec 1, 2022
2 parents 7e114fa + d04eed3 commit 0cd57ba
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 8 deletions.
Expand Up @@ -9,8 +9,10 @@ const {
getTypeScriptConfig,
} = require('@angular-devkit/build-angular/src/webpack/configs');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

const { filterOutStylingRules } = require('./utils/filter-out-styling-rules');
const {
default: StorybookNormalizeAngularEntryPlugin,
} = require('./plugins/storybook-normalize-angular-entry-plugin');

/**
* Extract webpack config from angular-cli 13.x.x
Expand Down Expand Up @@ -66,7 +68,11 @@ exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }
rules: [...cliConfig.module.rules, ...rulesExcludingStyles],
};

const plugins = [...(cliConfig.plugins ?? []), ...baseConfig.plugins];
const plugins = [
...(cliConfig.plugins ?? []),
...baseConfig.plugins,
new StorybookNormalizeAngularEntryPlugin(),
];

const resolve = {
...baseConfig.resolve,
Expand Down
4 changes: 2 additions & 2 deletions app/angular/src/server/framework-preset-angular-cli.ts
Expand Up @@ -8,7 +8,7 @@ import dedent from 'ts-dedent';
import { logging, JsonObject } from '@angular-devkit/core';
import { moduleIsAvailable } from './utils/module-is-available';
import { getWebpackConfig as getWebpackConfig12_2_x } from './angular-cli-webpack-12.2.x';
import { getWebpackConfig as getWebpackConfig13_x_x } from './angular-cli-webpack-13.x.x';
import { getWebpackConfig as getCustomWebpackConfig } from './angular-cli-webpack';
import { getWebpackConfig as getWebpackConfigOlder } from './angular-cli-webpack-older';
import { PresetOptions } from './options';
import {
Expand Down Expand Up @@ -44,7 +44,7 @@ export async function webpackFinal(baseConfig: webpack.Configuration, options: P
const builderOptions = await getBuilderOptions(_options, builderContext);
const legacyDefaultOptions = await getLegacyDefaultBuildOptions(_options);

return getWebpackConfig13_x_x(_baseConfig, {
return getCustomWebpackConfig(_baseConfig, {
builderOptions: {
watch: options.configType === 'DEVELOPMENT',
...legacyDefaultOptions,
Expand Down
@@ -0,0 +1,49 @@
const PLUGIN_NAME = 'storybook-normalize-angular-entry-plugin';

/**
* Angular's webpack plugin @angular-devkit/build-angular/src/webpack/plugins/styles-webpack-plugin.js
* transforms the original webpackOptions.entry point array into a structure like this:
*
* ```js
* {
* main: {
* import: [...]
* },
*
* styles: {
* import: [...]
* },
* }
* ```
*
* Storybook throws an __webpack_require__.nmd is not a function error, when another runtime bundle (styles~runtime.iframe.bundle.js) is loaded.
* To prevent this error, we have to normalize the entry point to only generate one runtime bundle (main~runtime.iframe.bundle.js).
*/
export default class StorybookNormalizeAngularEntryPlugin {
constructor(options) {
this.options = options;
}

apply(compiler) {
const webpackOptions = compiler.options;
const entry =
typeof webpackOptions.entry === 'function' ? webpackOptions.entry() : webpackOptions.entry;

webpackOptions.entry = async () => {
const entryResult = await entry;

if (entryResult.main && entryResult.styles) {
return {
main: {
import: Array.from(new Set([...entryResult.main.import, ...entryResult.styles.import])),
},
};
}

return entry;
};
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
this.compilation = compilation;
});
}
}
2 changes: 1 addition & 1 deletion lib/channels/src/index.ts
Expand Up @@ -41,7 +41,7 @@ export class Channel {

private data: Record<string, any> = {};

private readonly transport: ChannelTransport;
private readonly transport: ChannelTransport | undefined = undefined;

constructor({ transport, async = false }: ChannelArgs = {}) {
this.isAsync = async;
Expand Down
12 changes: 9 additions & 3 deletions lib/router/src/utils.ts
Expand Up @@ -81,8 +81,14 @@ const validateArgs = (key = '', value: unknown): boolean => {
COLOR_REGEXP.test(value)
);
}
if (Array.isArray(value)) return value.every((v) => validateArgs(key, v));
if (isPlainObject(value)) return Object.entries(value).every(([k, v]) => validateArgs(k, v));
if (Array.isArray(value)) {
return value.every((v) => validateArgs(key, v));
}

if (isPlainObject(value)) {
return Object.entries(value as Record<string, any>).every(([k, v]) => validateArgs(k, v));
}

return false;
};

Expand All @@ -96,7 +102,7 @@ const encodeSpecialValues = (value: unknown): any => {
}
if (Array.isArray(value)) return value.map(encodeSpecialValues);
if (isPlainObject(value)) {
return Object.entries(value).reduce(
return Object.entries(value as Record<string, any>).reduce(
(acc, [key, val]) => Object.assign(acc, { [key]: encodeSpecialValues(val) }),
{}
);
Expand Down

0 comments on commit 0cd57ba

Please sign in to comment.