Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(react): storybook plugin fixes #14493

Merged
merged 1 commit into from
Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@
"@nrwl/workspace": "file:../workspace",
"@phenomnomnominal/tsquery": "4.1.1",
"chalk": "^4.1.0",
"minimatch": "3.0.5",
"semver": "7.3.4"
"minimatch": "3.0.5"
},
"publishConfig": {
"access": "public"
Expand Down
145 changes: 32 additions & 113 deletions packages/react/plugins/storybook/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import {
ExecutorContext,
joinPathFragments,
logger,
readJsonFile,
workspaceRoot,
} from '@nrwl/devkit';
import { ExecutorContext, logger } from '@nrwl/devkit';
import { composePlugins } from '@nrwl/webpack/src/utils/config';
import { NormalizedWebpackExecutorOptions } from '@nrwl/webpack/src/executors/webpack/schema';
import { checkAndCleanWithSemver } from '@nrwl/workspace/src/utilities/version-utils';
import { join } from 'path';
import { gte } from 'semver';
import { Configuration, DefinePlugin, WebpackPluginInstance } from 'webpack';
import * as mergeWebpack from 'webpack-merge';
import {
Configuration,
DefinePlugin,
ResolvePluginInstance,
WebpackPluginInstance,
} from 'webpack';
import { mergePlugins } from './merge-plugins';
import { withReact } from '../with-react';

Expand Down Expand Up @@ -57,29 +53,6 @@ function getClientEnvironment(mode) {
return { stringified };
}

export const babelDefault = (): Record<
string,
// eslint-disable-next-line @typescript-eslint/ban-types
(string | [string, object])[]
> => {
// Add babel plugin for styled-components or emotion.
// We don't have a good way to know when a project uses one or the other, so
// add the plugin only if the other style package isn't used.
const packageJson = readJsonFile(join(workspaceRoot, 'package.json'));
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
const hasStyledComponents = !!deps['styled-components'];

const plugins = [];
if (hasStyledComponents) {
plugins.push(['styled-components', { ssr: false }]);
}

return {
presets: [],
plugins: [...plugins],
};
};

export const core = (prev, options) => ({
...prev,
disableWebpackDefaults: true,
Expand Down Expand Up @@ -118,16 +91,13 @@ export const webpack = async (
styles: true,
vendors: false,
},
styles: [],
styles: options.styles ?? [],
optimization: {},
tsConfig: tsconfigPath,
extractCss: storybookWebpackConfig.mode === 'production',
target: 'web',
};

const isScriptOptimizeOn = storybookWebpackConfig.mode !== 'development';
const extractCss = storybookWebpackConfig.mode === 'production';

// ESM build for modern browsers.
let baseWebpackConfig: Configuration = {};
const configure = composePlugins(
Expand All @@ -140,81 +110,30 @@ export const webpack = async (
context: {} as ExecutorContext, // The context is not used here.
});

// Check whether the project .babelrc uses @emotion/babel-plugin. There's currently
// a Storybook issue (https://github.com/storybookjs/storybook/issues/13277) which apparently
// doesn't work with `@emotion/*` >= v11
// this is a workaround to fix that
let resolvedEmotionAliases = {};
const packageJson = readJsonFile(join(workspaceRoot, 'package.json'));
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };

const emotionReactVersion = deps['@emotion/react'];
if (
emotionReactVersion &&
gte(
checkAndCleanWithSemver('@emotion/react', emotionReactVersion),
'11.0.0'
)
) {
try {
const babelrc = readJsonFile(
options.babelrcPath ||
joinPathFragments(options.configDir, '../', '.babelrc')
);
if (babelrc?.plugins?.includes('@emotion/babel-plugin')) {
resolvedEmotionAliases = {
resolve: {
alias: {
'@emotion/core': joinPathFragments(
workspaceRoot,
'node_modules',
'@emotion/react'
),
'@emotion/styled': joinPathFragments(
workspaceRoot,
'node_modules',
'@emotion/styled'
),
'emotion-theming': joinPathFragments(
workspaceRoot,
'node_modules',
'@emotion/react'
),
},
},
};
}
} catch (error) {
// silently ignore if the .babelrc doesn't exist
}
}
return mergeWebpack.merge(
{
...storybookWebpackConfig,
module: {
...storybookWebpackConfig.module,
rules: [
...storybookWebpackConfig.module.rules,
...finalConfig.module.rules,
],
},
resolve: {
...storybookWebpackConfig.resolve,
plugins: mergePlugins(
...((storybookWebpackConfig.resolve.plugins ??
[]) as unknown as WebpackPluginInstance[]),
...((finalConfig.resolve
.plugins as unknown as WebpackPluginInstance[]) ?? [])
),
},
return {
...storybookWebpackConfig,
module: {
...storybookWebpackConfig.module,
rules: [
...storybookWebpackConfig.module.rules,
...finalConfig.module.rules,
],
},
resolve: {
...storybookWebpackConfig.resolve,
plugins: mergePlugins(
new DefinePlugin(
getClientEnvironment(storybookWebpackConfig.mode).stringified
),
...(storybookWebpackConfig.plugins ?? []),
...(finalConfig.plugins ?? [])
),
...((storybookWebpackConfig.resolve.plugins ??
[]) as ResolvePluginInstance[]),
...((finalConfig.resolve
.plugins as unknown as ResolvePluginInstance[]) ?? [])
) as ResolvePluginInstance[],
},
resolvedEmotionAliases
);
plugins: mergePlugins(
new DefinePlugin(
getClientEnvironment(storybookWebpackConfig.mode).stringified
),
...(storybookWebpackConfig.plugins ?? []),
...(finalConfig.plugins ?? [])
) as WebpackPluginInstance[],
};
};
12 changes: 8 additions & 4 deletions packages/react/plugins/storybook/merge-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { RuleSetRule, WebpackPluginInstance } from 'webpack';
import {
ResolvePluginInstance,
RuleSetRule,
WebpackPluginInstance,
} from 'webpack';

export const mergeRules = (...args: RuleSetRule[]) =>
args.reduce((rules, rule) => {
Expand All @@ -14,8 +18,8 @@ export const mergeRules = (...args: RuleSetRule[]) =>
}, [] as WebpackPluginInstance[]);

export const mergePlugins = (
...args: WebpackPluginInstance[]
): WebpackPluginInstance[] =>
...args: (WebpackPluginInstance | ResolvePluginInstance)[]
): (WebpackPluginInstance | ResolvePluginInstance)[] =>
args.reduce((plugins, plugin) => {
if (
plugins.some(
Expand All @@ -26,4 +30,4 @@ export const mergePlugins = (
return plugins;
}
return [...plugins, plugin];
}, [] as WebpackPluginInstance[]);
}, [] as (WebpackPluginInstance | ResolvePluginInstance)[]);