feat(webpack): add isolatedConfig option to skip automatically applying Nx plugins (#14618)

This commit is contained in:
Jack Hsu 2023-01-26 10:32:34 -05:00 committed by GitHub
parent a61cbb5319
commit cd92d102d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 47 additions and 30 deletions

View File

@ -331,6 +331,11 @@
"description": "Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or `<https://webpack.github.io/analyse>`.", "description": "Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or `<https://webpack.github.io/analyse>`.",
"default": false "default": false
}, },
"isolatedConfig": {
"type": "boolean",
"description": "Do not apply Nx webpack plugins automatically. Plugins need to be applied in the project's webpack.config.js file (e.g. withNx, withReact, etc.).",
"default": false
},
"extractLicenses": { "extractLicenses": {
"type": "boolean", "type": "boolean",
"description": "Extract all licenses in a separate file, in the case of production builds only.", "description": "Extract all licenses in a separate file, in the case of production builds only.",

View File

@ -170,9 +170,10 @@ describe('Web Components Applications', () => {
updateFile( updateFile(
`apps/${appName}/webpack.config.js`, `apps/${appName}/webpack.config.js`,
` `
module.exports = (config, context) => { const { composePlugins, withNx, withWeb } = require('@nrwl/webpack');
module.exports = composePlugins(withNx(), withWeb(), (config, context) => {
return config; return config;
}; });
` `
); );
runCLI(`build ${appName} --outputHashing none`); runCLI(`build ${appName} --outputHashing none`);
@ -184,9 +185,10 @@ describe('Web Components Applications', () => {
updateFile( updateFile(
`apps/${appName}/webpack.config.js`, `apps/${appName}/webpack.config.js`,
` `
module.exports = async (config, context) => { const { composePlugins, withNx, withWeb } = require('@nrwl/webpack');
module.exports = composePlugins(withNx(), withWeb(), async (config, context) => {
return config; return config;
}; });
` `
); );
runCLI(`build ${appName} --outputHashing none`); runCLI(`build ${appName} --outputHashing none`);
@ -198,9 +200,10 @@ describe('Web Components Applications', () => {
updateFile( updateFile(
`apps/${appName}/webpack.config.js`, `apps/${appName}/webpack.config.js`,
` `
module.exports = Promise.resolve((config, context) => { const { composePlugins, withNx, withWeb } = require('@nrwl/webpack');
module.exports = composePlugins(withNx(), withWeb(), Promise.resolve((config, context) => {
return config; return config;
}); }));
` `
); );
runCLI(`build ${appName} --outputHashing none`); runCLI(`build ${appName} --outputHashing none`);

View File

@ -55,6 +55,7 @@ describe('app', () => {
outputPath: 'dist/my-node-app', outputPath: 'dist/my-node-app',
main: 'my-node-app/src/main.ts', main: 'my-node-app/src/main.ts',
tsConfig: 'my-node-app/tsconfig.app.json', tsConfig: 'my-node-app/tsconfig.app.json',
isolatedConfig: true,
webpackConfig: 'my-node-app/webpack.config.js', webpackConfig: 'my-node-app/webpack.config.js',
assets: ['my-node-app/src/assets'], assets: ['my-node-app/src/assets'],
}, },

View File

@ -66,6 +66,7 @@ function getWebpackBuildConfig(
), ),
tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
assets: [joinPathFragments(project.sourceRoot, 'assets')], assets: [joinPathFragments(project.sourceRoot, 'assets')],
isolatedConfig: true,
webpackConfig: joinPathFragments( webpackConfig: joinPathFragments(
options.appProjectRoot, options.appProjectRoot,
'webpack.config.js' 'webpack.config.js'

View File

@ -1,18 +1,13 @@
import type { Configuration } from 'webpack'; import type { Configuration } from 'webpack';
import { NormalizedWebpackExecutorOptions } from '@nrwl/webpack';
import { ExecutorContext } from 'nx/src/config/misc-interfaces';
const processed = new Set(); const processed = new Set();
export function withReact() { export function withReact() {
return function configure( return function configure(config: Configuration, _ctx?: any): Configuration {
config: Configuration, const { withWeb } = require('@nrwl/webpack');
_ctx?: {
options: NormalizedWebpackExecutorOptions;
context: ExecutorContext;
}
): Configuration {
if (processed.has(config)) return config; if (processed.has(config)) return config;
config = withWeb()(config, _ctx);
config.module.rules.push({ config.module.rules.push({
test: /\.svg$/, test: /\.svg$/,

View File

@ -315,6 +315,7 @@ describe('app', () => {
scripts: [], scripts: [],
styles: ['apps/my-app/src/styles.css'], styles: ['apps/my-app/src/styles.css'],
tsConfig: 'apps/my-app/tsconfig.app.json', tsConfig: 'apps/my-app/tsconfig.app.json',
isolatedConfig: true,
webpackConfig: 'apps/my-app/webpack.config.js', webpackConfig: 'apps/my-app/webpack.config.js',
}); });
expect(targetConfig.build.configurations.production).toEqual({ expect(targetConfig.build.configurations.production).toEqual({

View File

@ -67,6 +67,7 @@ function createBuildTarget(options: NormalizedSchema): TargetConfiguration {
), ),
], ],
scripts: [], scripts: [],
isolatedConfig: true,
webpackConfig: joinPathFragments( webpackConfig: joinPathFragments(
options.appProjectRoot, options.appProjectRoot,
'webpack.config.js' 'webpack.config.js'

View File

@ -107,6 +107,7 @@ export async function setupSsrGenerator(tree: Tree, options: Schema) {
compiler: 'babel', compiler: 'babel',
externalDependencies: 'all', externalDependencies: 'all',
outputHashing: 'none', outputHashing: 'none',
isolatedConfig: true,
webpackConfig: joinPathFragments(projectRoot, 'webpack.config.js'), webpackConfig: joinPathFragments(projectRoot, 'webpack.config.js'),
}, },
configurations: { configurations: {

View File

@ -82,6 +82,7 @@ async function setupBundler(tree: Tree, options: NormalizedSchema) {
tsConfig, tsConfig,
compiler: options.compiler ?? 'babel', compiler: options.compiler ?? 'babel',
devServer: true, devServer: true,
isolatedConfig: true,
webpackConfig: joinPathFragments( webpackConfig: joinPathFragments(
options.appProjectRoot, options.appProjectRoot,
'webpack.config.js' 'webpack.config.js'

View File

@ -54,6 +54,7 @@ export interface WebpackExecutorOptions {
generateIndexHtml?: boolean; generateIndexHtml?: boolean;
generatePackageJson?: boolean; generatePackageJson?: boolean;
index?: string; index?: string;
isolatedConfig?: boolean;
main: string; main: string;
memoryLimit?: number; memoryLimit?: number;
namedChunks?: boolean; namedChunks?: boolean;

View File

@ -252,6 +252,11 @@
"description": "Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or `<https://webpack.github.io/analyse>`.", "description": "Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or `<https://webpack.github.io/analyse>`.",
"default": false "default": false
}, },
"isolatedConfig": {
"type": "boolean",
"description": "Do not apply Nx webpack plugins automatically. Plugins need to be applied in the project's webpack.config.js file (e.g. withNx, withReact, etc.).",
"default": false
},
"extractLicenses": { "extractLicenses": {
"type": "boolean", "type": "boolean",
"description": "Extract all licenses in a separate file, in the case of production builds only.", "description": "Extract all licenses in a separate file, in the case of production builds only.",

View File

@ -27,15 +27,11 @@ async function getWebpackConfigs(
options: NormalizedWebpackExecutorOptions, options: NormalizedWebpackExecutorOptions,
context: ExecutorContext context: ExecutorContext
): Promise<Configuration> { ): Promise<Configuration> {
const metadata = context.projectsConfigurations.projects[context.projectName]; if (options.isolatedConfig && !options.webpackConfig) {
const projectRoot = metadata.root; throw new Error(
const isScriptOptimizeOn = `Using "isolatedConfig" without a "webpackConfig" is not supported.`
typeof options.optimization === 'boolean' );
? options.optimization }
: options.optimization && options.optimization.scripts
? options.optimization.scripts
: false;
let customWebpack = null; let customWebpack = null;
if (options.webpackConfig) { if (options.webpackConfig) {
@ -49,15 +45,21 @@ async function getWebpackConfigs(
} }
} }
const config = getWebpackConfig(context, options); const config = options.isolatedConfig
? {}
: getWebpackConfig(context, options);
if (customWebpack) { if (customWebpack) {
return await customWebpack(config, { return await customWebpack(
options, {},
context, {
configuration: context.configurationName, // backwards compat options,
}); context,
configuration: context.configurationName, // backwards compat
}
);
} else { } else {
// If the user has no webpackConfig specified then we always have to apply
return config; return config;
} }
} }