diff --git a/e2e/web/src/web.test.ts b/e2e/web/src/web.test.ts index e9bc5aaf15..5313ee636a 100644 --- a/e2e/web/src/web.test.ts +++ b/e2e/web/src/web.test.ts @@ -289,14 +289,17 @@ describe('CLI - Environment Variables', () => { updateFile(main2, `${newCode2}\n${content2}`); - runCLI(`run-many --target build --all --outputHashing=none`, { - env: { - ...process.env, - NODE_ENV: 'test', - NX_BUILD: '52', - NX_API: 'QA', - }, - }); + 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"];' ); diff --git a/packages/react/plugins/with-react.ts b/packages/react/plugins/with-react.ts index 26c6265046..c5092768f8 100644 --- a/packages/react/plugins/with-react.ts +++ b/packages/react/plugins/with-react.ts @@ -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, diff --git a/packages/webpack/src/utils/with-web.ts b/packages/webpack/src/utils/with-web.ts index a7845f0da2..4116e998f6 100644 --- a/packages/webpack/src/utils/with-web.ts +++ b/packages/webpack/src/utils/with-web.ts @@ -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,