fix(webpack): use webpack-merge for plugins to preserve values, fix React SVG loader (#14695)

This commit is contained in:
Dan Roujinsky 2023-01-31 17:09:58 +02:00 committed by GitHub
parent a10dc40f18
commit e92097c5d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 37 deletions

View File

@ -289,14 +289,17 @@ describe('CLI - Environment Variables', () => {
updateFile(main2, `${newCode2}\n${content2}`);
runCLI(`run-many --target build --all --outputHashing=none`, {
runCLI(
`run-many --target build --all --outputHashing=none --optimization=false`,
{
env: {
...process.env,
NODE_ENV: 'test',
NX_BUILD: '52',
NX_API: 'QA',
},
});
}
);
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
'const envVars = ["test", "52", "QA", "ws-base", "ws-env-local", "ws-local-env", "app-base", "app-env-local", "app-local-env", "shared-in-app-env-local"];'
);

View File

@ -1,18 +1,63 @@
import type { Configuration } from 'webpack';
import type { WithWebOptions } from '@nrwl/webpack';
import type { NxWebpackExecutionContext } from '@nrwl/webpack';
const processed = new Set();
interface WithReactOptions extends WithWebOptions {}
function addHotReload(config: Configuration) {
if (config.mode === 'development' && config['devServer']?.hot) {
// add `react-refresh/babel` to babel loader plugin
const babelLoader = config.module.rules.find(
(rule) =>
typeof rule !== 'string' &&
rule.loader?.toString().includes('babel-loader')
);
if (babelLoader && typeof babelLoader !== 'string') {
babelLoader.options['plugins'] = [
...(babelLoader.options['plugins'] || []),
[
require.resolve('react-refresh/babel'),
{
skipEnvCheck: true,
},
],
];
}
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
config.plugins.push(new ReactRefreshPlugin());
}
}
// We remove potentially conflicting rules that target SVGs because we use @svgr/webpack loader
// See https://github.com/nrwl/nx/issues/14383
function removeSvgLoaderIfPresent(config: Configuration) {
const svgLoaderIdx = config.module.rules.findIndex(
(rule) => typeof rule === 'object' && rule.test.toString().includes('svg')
);
if (svgLoaderIdx === -1) return;
config.module.rules.splice(svgLoaderIdx, 1);
}
export function withReact(pluginOptions: WithReactOptions = {}) {
return function configure(config: Configuration, _ctx?: any): Configuration {
return function configure(
config: Configuration,
context: NxWebpackExecutionContext
): Configuration {
const { withWeb } = require('@nrwl/webpack');
if (processed.has(config)) return config;
// Apply web config for CSS, JSX, index.html handling, etc.
config = withWeb(pluginOptions)(config, _ctx);
config = withWeb(pluginOptions)(config, context);
addHotReload(config);
removeSvgLoaderIfPresent(config);
config.module.rules.push({
test: /\.svg$/,
@ -35,28 +80,6 @@ export function withReact(pluginOptions: WithReactOptions = {}) {
],
});
if (config.mode === 'development' && config['devServer']?.hot) {
// add `react-refresh/babel` to babel loader plugin
const babelLoader = config.module.rules.find(
(rule) =>
typeof rule !== 'string' &&
rule.loader?.toString().includes('babel-loader')
);
if (babelLoader && typeof babelLoader !== 'string') {
babelLoader.options['plugins'] = [
...(babelLoader.options['plugins'] || []),
[
require.resolve('react-refresh/babel'),
{
skipEnvCheck: true,
},
],
];
}
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
config.plugins.push(new ReactRefreshPlugin());
}
// enable webpack node api
config.node = {
__dirname: true,

View File

@ -25,6 +25,7 @@ import CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
import MiniCssExtractPlugin = require('mini-css-extract-plugin');
import autoprefixer = require('autoprefixer');
import postcssImports = require('postcss-import');
import { NxWebpackExecutionContext } from '@nrwl/webpack/src/utils/config';
interface PostcssOptions {
(loader: any): any;
@ -58,10 +59,7 @@ export type MergedOptions = Omit<
export function withWeb(pluginOptions: WithWebOptions = {}) {
return function configure(
config: Configuration,
{
options: executorOptions,
context,
}: { options: NormalizedWebpackExecutorOptions; context: ExecutorContext }
{ options: executorOptions, context }: NxWebpackExecutionContext
): Configuration {
if (processed.has(config)) return config;
@ -367,7 +365,7 @@ export function withWeb(pluginOptions: WithWebOptions = {}) {
config.optimization = {
...config.optimization,
minimizer,
minimizer: [...config.optimization.minimizer, ...minimizer],
emitOnErrors: false,
moduleIds: 'deterministic' as const,
runtimeChunk: mergedOptions.runtimeChunk ? ('single' as const) : false,