diff --git a/e2e/webpack/src/webpack.test.ts b/e2e/webpack/src/webpack.test.ts index cdaaacd44cac7..75b39e95319cf 100644 --- a/e2e/webpack/src/webpack.test.ts +++ b/e2e/webpack/src/webpack.test.ts @@ -1,4 +1,5 @@ import { + checkFilesExist, cleanupProject, fileExists, listFiles, @@ -262,6 +263,34 @@ describe('Webpack Plugin', () => { fileExists(`dist/apps/${appName}/package.json`); }); + + it('should resolve assets from executors as relative to workspace root', () => { + const appName = uniq('app'); + runCLI(`generate @nx/web:app ${appName} --bundler webpack`); + updateFile('shared/docs/TEST.md', 'TEST'); + updateJson(`apps/${appName}/project.json`, (json) => { + json.targets.build = { + executor: '@nx/webpack:webpack', + outputs: ['{options.outputPath}'], + options: { + assets: [ + { + input: 'shared/docs', + glob: 'TEST.md', + output: '.', + }, + ], + outputPath: `dist/apps/${appName}`, + webpackConfig: `apps/${appName}/webpack.config.js`, + }, + }; + return json; + }); + + runCLI(`build ${appName}`); + + checkFilesExist(`dist/apps/${appName}/TEST.md`); + }); }); function readMainFile(dir: string): string { diff --git a/packages/webpack/src/executors/webpack/lib/normalize-options.ts b/packages/webpack/src/executors/webpack/lib/normalize-options.ts index b2677c537b961..df6b0198897a7 100644 --- a/packages/webpack/src/executors/webpack/lib/normalize-options.ts +++ b/packages/webpack/src/executors/webpack/lib/normalize-options.ts @@ -37,7 +37,8 @@ export function normalizeOptions( options.assets, root, sourceRoot, - projectRoot + projectRoot, + false // executor assets are relative to workspace root for consistency ); } return normalizedOptions as NormalizedWebpackExecutorOptions; diff --git a/packages/webpack/src/plugins/nx-webpack-plugin/lib/normalize-options.ts b/packages/webpack/src/plugins/nx-webpack-plugin/lib/normalize-options.ts index 17529eb5f314d..f28779f79d687 100644 --- a/packages/webpack/src/plugins/nx-webpack-plugin/lib/normalize-options.ts +++ b/packages/webpack/src/plugins/nx-webpack-plugin/lib/normalize-options.ts @@ -51,14 +51,16 @@ export function normalizeOptions( } Object.assign( combinedPluginAndMaybeExecutorOptions, - buildTargetOptions, - options // plugin options take precedence + options, + // executor options take precedence (especially for overriding with CLI args) + buildTargetOptions ); } else { Object.assign( combinedPluginAndMaybeExecutorOptions, - originalTargetOptions, - options // plugin options take precedence + options, + // executor options take precedence (especially for overriding with CLI args) + originalTargetOptions ); } @@ -121,7 +123,8 @@ export function normalizeAssets( assets: any[], root: string, sourceRoot: string, - projectRoot: string + projectRoot: string, + resolveRelativePathsToProjectRoot = true ): AssetGlobPattern[] { return assets.map((asset) => { if (typeof asset === 'string') { @@ -155,7 +158,7 @@ export function normalizeAssets( const assetPath = normalizePath(asset.input); let resolvedAssetPath = resolve(root, assetPath); - if (asset.input.startsWith('.')) { + if (resolveRelativePathsToProjectRoot && asset.input.startsWith('.')) { const resolvedProjectRoot = resolve(root, projectRoot); resolvedAssetPath = resolve(resolvedProjectRoot, assetPath); }