@nx/webpack 17.1.0-beta.4 → 17.1.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/index.d.ts +2 -0
  2. package/index.js +5 -1
  3. package/package.json +4 -4
  4. package/src/executors/dev-server/dev-server.impl.js +18 -5
  5. package/src/executors/webpack/lib/normalize-options.d.ts +1 -2
  6. package/src/executors/webpack/lib/normalize-options.js +3 -52
  7. package/src/executors/webpack/schema.d.ts +4 -4
  8. package/src/executors/webpack/webpack.impl.js +11 -4
  9. package/src/plugins/generate-package-json-plugin.d.ts +6 -4
  10. package/src/plugins/generate-package-json-plugin.js +11 -14
  11. package/src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin.d.ts +8 -0
  12. package/src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin.js +31 -0
  13. package/src/plugins/nx-webpack-plugin/lib/apply-base-config.d.ts +3 -0
  14. package/src/plugins/nx-webpack-plugin/lib/apply-base-config.js +288 -0
  15. package/src/plugins/nx-webpack-plugin/lib/apply-web-config.d.ts +3 -0
  16. package/src/plugins/nx-webpack-plugin/lib/apply-web-config.js +355 -0
  17. package/src/plugins/nx-webpack-plugin/lib/compiler-loaders.d.ts +53 -0
  18. package/src/plugins/nx-webpack-plugin/lib/compiler-loaders.js +78 -0
  19. package/src/plugins/nx-webpack-plugin/lib/get-terser-ecma-version.d.ts +1 -0
  20. package/src/plugins/nx-webpack-plugin/lib/get-terser-ecma-version.js +35 -0
  21. package/src/plugins/nx-webpack-plugin/lib/instantiate-script-plugins.d.ts +3 -0
  22. package/src/plugins/nx-webpack-plugin/lib/instantiate-script-plugins.js +42 -0
  23. package/src/plugins/nx-webpack-plugin/lib/normalize-options.d.ts +3 -0
  24. package/src/plugins/nx-webpack-plugin/lib/normalize-options.js +116 -0
  25. package/src/plugins/nx-webpack-plugin/lib/stylesheet-loaders.d.ts +73 -0
  26. package/src/plugins/nx-webpack-plugin/lib/stylesheet-loaders.js +115 -0
  27. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin-options.d.ts +87 -0
  28. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin-options.js +2 -0
  29. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin.d.ts +18 -0
  30. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin.js +52 -0
  31. package/src/utils/with-nx.d.ts +0 -53
  32. package/src/utils/with-nx.js +14 -361
  33. package/src/utils/with-web.js +9 -488
package/index.d.ts CHANGED
@@ -14,3 +14,5 @@ export * from './src/utils/get-css-module-local-ident';
14
14
  export * from './src/utils/with-nx';
15
15
  export * from './src/utils/with-web';
16
16
  export * from './src/utils/module-federation/public-api';
17
+ export { NxWebpackPlugin } from './src/plugins/nx-webpack-plugin/nx-webpack-plugin';
18
+ export { NxTsconfigPathsWebpackPlugin } from './src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.webpackProjectGenerator = exports.configurationGenerator = void 0;
3
+ exports.NxTsconfigPathsWebpackPlugin = exports.NxWebpackPlugin = exports.webpackProjectGenerator = exports.configurationGenerator = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const configuration_1 = require("./src/generators/configuration/configuration");
6
6
  Object.defineProperty(exports, "configurationGenerator", { enumerable: true, get: function () { return configuration_1.configurationGenerator; } });
@@ -17,3 +17,7 @@ tslib_1.__exportStar(require("./src/utils/get-css-module-local-ident"), exports)
17
17
  tslib_1.__exportStar(require("./src/utils/with-nx"), exports);
18
18
  tslib_1.__exportStar(require("./src/utils/with-web"), exports);
19
19
  tslib_1.__exportStar(require("./src/utils/module-federation/public-api"), exports);
20
+ var nx_webpack_plugin_1 = require("./src/plugins/nx-webpack-plugin/nx-webpack-plugin");
21
+ Object.defineProperty(exports, "NxWebpackPlugin", { enumerable: true, get: function () { return nx_webpack_plugin_1.NxWebpackPlugin; } });
22
+ var nx_tsconfig_paths_webpack_plugin_1 = require("./src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin");
23
+ Object.defineProperty(exports, "NxTsconfigPathsWebpackPlugin", { enumerable: true, get: function () { return nx_tsconfig_paths_webpack_plugin_1.NxTsconfigPathsWebpackPlugin; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/webpack",
3
- "version": "17.1.0-beta.4",
3
+ "version": "17.1.0-rc.0",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Webpack contains executors and generators that support building applications using Webpack.",
6
6
  "repository": {
@@ -62,9 +62,9 @@
62
62
  "webpack-dev-server": "^4.9.3",
63
63
  "webpack-node-externals": "^3.0.0",
64
64
  "webpack-subresource-integrity": "^5.1.0",
65
- "@nx/devkit": "17.1.0-beta.4",
66
- "@nx/js": "17.1.0-beta.4",
67
- "@nrwl/webpack": "17.1.0-beta.4"
65
+ "@nx/devkit": "17.1.0-rc.0",
66
+ "@nx/js": "17.1.0-rc.0",
67
+ "@nrwl/webpack": "17.1.0-rc.0"
68
68
  },
69
69
  "publishConfig": {
70
70
  "access": "public"
@@ -34,11 +34,24 @@ async function* devServerExecutor(serveOptions, context) {
34
34
  if (typeof customWebpack.then === 'function') {
35
35
  customWebpack = await customWebpack;
36
36
  }
37
- config = await customWebpack(config, {
38
- options: buildOptions,
39
- context,
40
- configuration: serveOptions.buildTarget.split(':')[2],
41
- });
37
+ if (typeof customWebpack === 'function') {
38
+ // Old behavior, call the webpack function that is specific to Nx
39
+ config = await customWebpack(config, {
40
+ options: buildOptions,
41
+ context,
42
+ configuration: serveOptions.buildTarget.split(':')[2],
43
+ });
44
+ }
45
+ else if (customWebpack) {
46
+ // New behavior, use the config object as is with devServer defaults
47
+ config = {
48
+ devServer: {
49
+ ...customWebpack.devServer,
50
+ ...config.devServer,
51
+ },
52
+ ...customWebpack,
53
+ };
54
+ }
42
55
  }
43
56
  return yield* (0, rxjs_for_await_1.eachValueFrom)((0, run_webpack_1.runWebpackDevServer)(config, webpack, WebpackDevServer).pipe((0, operators_1.tap)(({ stats }) => {
44
57
  console.info(stats.toString(config.stats));
@@ -1,4 +1,3 @@
1
- import type { AssetGlobPattern, NormalizedWebpackExecutorOptions, WebpackExecutorOptions } from '../schema';
1
+ import type { NormalizedWebpackExecutorOptions, WebpackExecutorOptions } from '../schema';
2
2
  export declare function normalizeOptions(options: WebpackExecutorOptions, root: string, projectRoot: string, sourceRoot: string): NormalizedWebpackExecutorOptions;
3
3
  export declare function normalizePluginPath(pluginPath: void | string, root: string): string;
4
- export declare function normalizeAssets(assets: any[], root: string, sourceRoot: string): AssetGlobPattern[];
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.normalizeAssets = exports.normalizePluginPath = exports.normalizeOptions = void 0;
3
+ exports.normalizePluginPath = exports.normalizeOptions = void 0;
4
4
  const path_1 = require("path");
5
- const fs_1 = require("fs");
6
- const devkit_1 = require("@nx/devkit");
5
+ const normalize_options_1 = require("../../../plugins/nx-webpack-plugin/lib/normalize-options");
7
6
  function normalizeOptions(options, root, projectRoot, sourceRoot) {
8
7
  return {
9
8
  ...options,
@@ -11,12 +10,8 @@ function normalizeOptions(options, root, projectRoot, sourceRoot) {
11
10
  projectRoot,
12
11
  sourceRoot,
13
12
  target: options.target ?? 'web',
14
- main: (0, path_1.resolve)(root, options.main),
15
- outputPath: (0, path_1.resolve)(root, options.outputPath),
16
13
  outputFileName: options.outputFileName ?? 'main.js',
17
- tsConfig: (0, path_1.resolve)(root, options.tsConfig),
18
- fileReplacements: normalizeFileReplacements(root, options.fileReplacements),
19
- assets: normalizeAssets(options.assets, root, sourceRoot),
14
+ assets: (0, normalize_options_1.normalizeAssets)(options.assets, root, sourceRoot),
20
15
  webpackConfig: normalizePluginPath(options.webpackConfig, root),
21
16
  optimization: typeof options.optimization !== 'object'
22
17
  ? {
@@ -24,16 +19,9 @@ function normalizeOptions(options, root, projectRoot, sourceRoot) {
24
19
  styles: options.optimization,
25
20
  }
26
21
  : options.optimization,
27
- polyfills: options.polyfills ? (0, path_1.resolve)(root, options.polyfills) : undefined,
28
22
  };
29
23
  }
30
24
  exports.normalizeOptions = normalizeOptions;
31
- function normalizeFileReplacements(root, fileReplacements) {
32
- return fileReplacements.map((fileReplacement) => ({
33
- replace: (0, path_1.resolve)(root, fileReplacement.replace),
34
- with: (0, path_1.resolve)(root, fileReplacement.with),
35
- }));
36
- }
37
25
  function normalizePluginPath(pluginPath, root) {
38
26
  if (!pluginPath) {
39
27
  return '';
@@ -46,40 +34,3 @@ function normalizePluginPath(pluginPath, root) {
46
34
  }
47
35
  }
48
36
  exports.normalizePluginPath = normalizePluginPath;
49
- function normalizeAssets(assets, root, sourceRoot) {
50
- return assets.map((asset) => {
51
- if (typeof asset === 'string') {
52
- const assetPath = (0, devkit_1.normalizePath)(asset);
53
- const resolvedAssetPath = (0, path_1.resolve)(root, assetPath);
54
- const resolvedSourceRoot = (0, path_1.resolve)(root, sourceRoot);
55
- if (!resolvedAssetPath.startsWith(resolvedSourceRoot)) {
56
- throw new Error(`The ${resolvedAssetPath} asset path must start with the project source root: ${sourceRoot}`);
57
- }
58
- const isDirectory = (0, fs_1.statSync)(resolvedAssetPath).isDirectory();
59
- const input = isDirectory
60
- ? resolvedAssetPath
61
- : (0, path_1.dirname)(resolvedAssetPath);
62
- const output = (0, path_1.relative)(resolvedSourceRoot, (0, path_1.resolve)(root, input));
63
- const glob = isDirectory ? '**/*' : (0, path_1.basename)(resolvedAssetPath);
64
- return {
65
- input,
66
- output,
67
- glob,
68
- };
69
- }
70
- else {
71
- if (asset.output.startsWith('..')) {
72
- throw new Error('An asset cannot be written to a location outside of the output path.');
73
- }
74
- const assetPath = (0, devkit_1.normalizePath)(asset.input);
75
- const resolvedAssetPath = (0, path_1.resolve)(root, assetPath);
76
- return {
77
- ...asset,
78
- input: resolvedAssetPath,
79
- // Now we remove starting slash to make Webpack place it from the output root.
80
- output: asset.output.replace(/^\//, ''),
81
- };
82
- }
83
- });
84
- }
85
- exports.normalizeAssets = normalizeAssets;
@@ -86,8 +86,8 @@ export interface WebpackExecutorOptions {
86
86
  export interface NormalizedWebpackExecutorOptions
87
87
  extends WebpackExecutorOptions {
88
88
  outputFileName: string;
89
- assets?: AssetGlobPattern[];
90
- root?: string;
91
- projectRoot?: string;
92
- sourceRoot?: string;
89
+ assets: AssetGlobPattern[];
90
+ root: string;
91
+ projectRoot: string;
92
+ sourceRoot: string;
93
93
  }
@@ -17,7 +17,7 @@ async function getWebpackConfigs(options, projectRoot, context) {
17
17
  throw new Error(`Using "isolatedConfig" without a "webpackConfig" is not supported.`);
18
18
  }
19
19
  let customWebpack = null;
20
- if (options.webpackConfig) {
20
+ if (options.webpackConfig && options.tsConfig) {
21
21
  customWebpack = (0, custom_webpack_1.resolveCustomWebpackConfig)(options.webpackConfig, options.tsConfig.startsWith(context.root)
22
22
  ? options.tsConfig
23
23
  : (0, path_1.join)(context.root, options.tsConfig));
@@ -28,19 +28,26 @@ async function getWebpackConfigs(options, projectRoot, context) {
28
28
  const config = options.isolatedConfig
29
29
  ? {}
30
30
  : (0, get_webpack_config_1.getWebpackConfig)(context, options);
31
- if (customWebpack) {
31
+ if (typeof customWebpack === 'function') {
32
+ // Old behavior, call the Nx-specific webpack config function that user exports
32
33
  return await customWebpack(config, {
33
34
  options,
34
35
  context,
35
36
  configuration: context.configurationName, // backwards compat
36
37
  });
37
38
  }
39
+ else if (customWebpack) {
40
+ // New behavior, we want the webpack config to export object
41
+ return customWebpack;
42
+ }
38
43
  else {
39
- // If the user has no webpackConfig specified then we always have to apply
44
+ // Fallback case, if we cannot find a webpack config path
40
45
  return config;
41
46
  }
42
47
  }
43
48
  async function* webpackExecutor(_options, context) {
49
+ // Pass to NxWebpackPlugin so we can get the CLI overrides.
50
+ process.env['NX_WEBPACK_EXECUTOR_RAW_OPTIONS'] = JSON.stringify(_options);
44
51
  const metadata = context.projectsConfigurations.projects[context.projectName];
45
52
  const sourceRoot = metadata.sourceRoot;
46
53
  const options = (0, normalize_options_1.normalizeOptions)(_options, context.root, metadata.root, sourceRoot);
@@ -71,7 +78,7 @@ async function* webpackExecutor(_options, context) {
71
78
  options.tsConfig = (0, buildable_libs_utils_1.createTmpTsConfig)(options.tsConfig, context.root, metadata.root, dependencies);
72
79
  }
73
80
  // Delete output path before bundling
74
- if (options.deleteOutputPath) {
81
+ if (options.deleteOutputPath && options.outputPath) {
75
82
  (0, fs_1.deleteOutputDir)(context.root, options.outputPath);
76
83
  }
77
84
  if (options.generatePackageJson && metadata.projectType !== 'application') {
@@ -1,12 +1,14 @@
1
1
  import { type Compiler, type WebpackPluginInstance } from 'webpack';
2
- import { ExecutorContext } from '@nx/devkit';
2
+ import { type ProjectGraph } from '@nx/devkit';
3
3
  export declare class GeneratePackageJsonPlugin implements WebpackPluginInstance {
4
4
  private readonly options;
5
- private readonly context;
6
- private readonly projectGraph;
7
5
  constructor(options: {
8
6
  tsConfig: string;
9
7
  outputFileName: string;
10
- }, context: ExecutorContext);
8
+ root: string;
9
+ projectName: string;
10
+ targetName: string;
11
+ projectGraph: ProjectGraph;
12
+ });
11
13
  apply(compiler: Compiler): void;
12
14
  }
@@ -4,13 +4,10 @@ exports.GeneratePackageJsonPlugin = void 0;
4
4
  const webpack_1 = require("webpack");
5
5
  const js_1 = require("@nx/js");
6
6
  const devkit_1 = require("@nx/devkit");
7
- const js_2 = require("@nx/js");
8
7
  const pluginName = 'GeneratePackageJsonPlugin';
9
8
  class GeneratePackageJsonPlugin {
10
- constructor(options, context) {
9
+ constructor(options) {
11
10
  this.options = options;
12
- this.context = context;
13
- this.projectGraph = context.projectGraph;
14
11
  }
15
12
  apply(compiler) {
16
13
  compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
@@ -18,28 +15,28 @@ class GeneratePackageJsonPlugin {
18
15
  name: pluginName,
19
16
  stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
20
17
  }, () => {
21
- const helperDependencies = (0, js_2.getHelperDependenciesFromProjectGraph)(this.context.root, this.context.projectName, this.projectGraph);
22
- const importHelpers = !!(0, js_2.readTsConfig)(this.options.tsConfig).options
18
+ const helperDependencies = (0, js_1.getHelperDependenciesFromProjectGraph)(this.options.root, this.options.projectName, this.options.projectGraph);
19
+ const importHelpers = !!(0, js_1.readTsConfig)(this.options.tsConfig).options
23
20
  .importHelpers;
24
21
  const shouldAddHelperDependency = importHelpers &&
25
- helperDependencies.every((dep) => dep.target !== js_2.HelperDependency.tsc);
22
+ helperDependencies.every((dep) => dep.target !== js_1.HelperDependency.tsc);
26
23
  if (shouldAddHelperDependency) {
27
24
  helperDependencies.push({
28
25
  type: 'static',
29
- source: this.context.projectName,
30
- target: js_2.HelperDependency.tsc,
26
+ source: this.options.projectName,
27
+ target: js_1.HelperDependency.tsc,
31
28
  });
32
29
  }
33
- const packageJson = (0, js_1.createPackageJson)(this.context.projectName, this.projectGraph, {
34
- target: this.context.targetName,
35
- root: this.context.root,
30
+ const packageJson = (0, js_1.createPackageJson)(this.options.projectName, this.options.projectGraph, {
31
+ target: this.options.targetName,
32
+ root: this.options.root,
36
33
  isProduction: true,
37
34
  helperDependencies: helperDependencies.map((dep) => dep.target),
38
35
  });
39
36
  packageJson.main = packageJson.main ?? this.options.outputFileName;
40
37
  compilation.emitAsset('package.json', new webpack_1.sources.RawSource((0, devkit_1.serializeJson)(packageJson)));
41
- const packageManager = (0, devkit_1.detectPackageManager)(this.context.root);
42
- compilation.emitAsset((0, js_2.getLockFileName)(packageManager), new webpack_1.sources.RawSource((0, js_1.createLockFile)(packageJson, this.projectGraph, packageManager)));
38
+ const packageManager = (0, devkit_1.detectPackageManager)(this.options.root);
39
+ compilation.emitAsset((0, js_1.getLockFileName)(packageManager), new webpack_1.sources.RawSource((0, js_1.createLockFile)(packageJson, this.options.projectGraph, packageManager)));
43
40
  });
44
41
  });
45
42
  }
@@ -0,0 +1,8 @@
1
+ import { Compiler } from 'webpack';
2
+ export declare class NxTsconfigPathsWebpackPlugin {
3
+ private options;
4
+ constructor(options: {
5
+ tsConfig: string;
6
+ });
7
+ apply(compiler: Compiler): void;
8
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NxTsconfigPathsWebpackPlugin = void 0;
4
+ const path = require("path");
5
+ const tsconfig_paths_webpack_plugin_1 = require("tsconfig-paths-webpack-plugin");
6
+ const devkit_1 = require("@nx/devkit");
7
+ class NxTsconfigPathsWebpackPlugin {
8
+ constructor(options) {
9
+ this.options = options;
10
+ if (!this.options.tsConfig)
11
+ throw new Error(`Missing "tsConfig" option. Set this option in your Nx webpack plugin.`);
12
+ }
13
+ apply(compiler) {
14
+ const extensions = new Set([
15
+ ...['.ts', '.tsx', '.mjs', '.js', '.jsx'],
16
+ ...(compiler.options?.resolve?.extensions ?? []),
17
+ ]);
18
+ compiler.options.resolve = {
19
+ ...compiler.options.resolve,
20
+ plugins: compiler.options.resolve?.plugins ?? [],
21
+ };
22
+ compiler.options.resolve.plugins.push(new tsconfig_paths_webpack_plugin_1.TsconfigPathsPlugin({
23
+ configFile: !path.isAbsolute(this.options.tsConfig)
24
+ ? path.join(devkit_1.workspaceRoot, this.options.tsConfig)
25
+ : this.options.tsConfig,
26
+ extensions: Array.from(extensions),
27
+ mainFields: ['module', 'main'],
28
+ }));
29
+ }
30
+ }
31
+ exports.NxTsconfigPathsWebpackPlugin = NxTsconfigPathsWebpackPlugin;
@@ -0,0 +1,3 @@
1
+ import { Configuration, WebpackOptionsNormalized } from 'webpack';
2
+ import { NormalizedNxWebpackPluginOptions } from '../nx-webpack-plugin-options';
3
+ export declare function applyBaseConfig(options: NormalizedNxWebpackPluginOptions, config?: Partial<WebpackOptionsNormalized | Configuration>): void;
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyBaseConfig = void 0;
4
+ const path = require("path");
5
+ const license_webpack_plugin_1 = require("license-webpack-plugin");
6
+ const CopyWebpackPlugin = require("copy-webpack-plugin");
7
+ const webpack_1 = require("webpack");
8
+ const stats_json_plugin_1 = require("../../stats-json-plugin");
9
+ const generate_package_json_plugin_1 = require("../../generate-package-json-plugin");
10
+ const hash_format_1 = require("../../../utils/hash-format");
11
+ const nx_tsconfig_paths_webpack_plugin_1 = require("../../nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin");
12
+ const get_terser_ecma_version_1 = require("./get-terser-ecma-version");
13
+ const compiler_loaders_1 = require("./compiler-loaders");
14
+ const TerserPlugin = require("terser-webpack-plugin");
15
+ const nodeExternals = require("webpack-node-externals");
16
+ const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
17
+ const IGNORED_WEBPACK_WARNINGS = [
18
+ /The comment file/i,
19
+ /could not find any license/i,
20
+ ];
21
+ const extensions = ['.ts', '.tsx', '.mjs', '.js', '.jsx'];
22
+ const mainFields = ['module', 'main'];
23
+ function applyBaseConfig(options, config = {}) {
24
+ const plugins = [
25
+ new nx_tsconfig_paths_webpack_plugin_1.NxTsconfigPathsWebpackPlugin(options),
26
+ ];
27
+ const executorContext = {
28
+ projectName: options.projectName,
29
+ targetName: options.targetName,
30
+ projectGraph: options.projectGraph,
31
+ configurationName: options.configurationName,
32
+ root: options.root,
33
+ };
34
+ if (!options?.skipTypeChecking) {
35
+ plugins.push(new ForkTsCheckerWebpackPlugin({
36
+ typescript: {
37
+ configFile: path.isAbsolute(options.tsConfig)
38
+ ? options.tsConfig
39
+ : path.join(options.root, options.tsConfig),
40
+ memoryLimit: options.memoryLimit || 2018,
41
+ },
42
+ }));
43
+ }
44
+ const entries = [];
45
+ if (options.main) {
46
+ const mainEntry = options.outputFileName
47
+ ? path.parse(options.outputFileName).name
48
+ : 'main';
49
+ entries.push({
50
+ name: mainEntry,
51
+ import: [path.resolve(options.root, options.main)],
52
+ });
53
+ }
54
+ if (options.additionalEntryPoints) {
55
+ for (const { entryName, entryPath } of options.additionalEntryPoints) {
56
+ entries.push({
57
+ name: entryName,
58
+ import: [path.resolve(options.root, entryPath)],
59
+ });
60
+ }
61
+ }
62
+ if (options.polyfills) {
63
+ entries.push({
64
+ name: 'polyfills',
65
+ import: [path.resolve(options.root, options.polyfills)],
66
+ });
67
+ }
68
+ config.entry ??= {};
69
+ entries.forEach((entry) => {
70
+ config.entry[entry.name] = { import: entry.import };
71
+ });
72
+ if (options.progress) {
73
+ plugins.push(new webpack_1.ProgressPlugin({ profile: options.verbose }));
74
+ }
75
+ if (options.extractLicenses) {
76
+ plugins.push(new license_webpack_plugin_1.LicenseWebpackPlugin({
77
+ stats: {
78
+ warnings: false,
79
+ errors: false,
80
+ },
81
+ perChunkOutput: false,
82
+ outputFilename: `3rdpartylicenses.txt`,
83
+ }));
84
+ }
85
+ if (Array.isArray(options.assets) && options.assets.length > 0) {
86
+ plugins.push(new CopyWebpackPlugin({
87
+ patterns: options.assets.map((asset) => {
88
+ return {
89
+ context: asset.input,
90
+ // Now we remove starting slash to make Webpack place it from the output root.
91
+ to: asset.output,
92
+ from: asset.glob,
93
+ globOptions: {
94
+ ignore: [
95
+ '.gitkeep',
96
+ '**/.DS_Store',
97
+ '**/Thumbs.db',
98
+ ...(asset.ignore ?? []),
99
+ ],
100
+ dot: true,
101
+ },
102
+ };
103
+ }),
104
+ }));
105
+ }
106
+ if (options.generatePackageJson && executorContext) {
107
+ plugins.push(new generate_package_json_plugin_1.GeneratePackageJsonPlugin(options));
108
+ }
109
+ if (options.statsJson) {
110
+ plugins.push(new stats_json_plugin_1.StatsJsonPlugin());
111
+ }
112
+ const externals = [];
113
+ if (options.target === 'node' && options.externalDependencies === 'all') {
114
+ const modulesDir = `${options.root}/node_modules`;
115
+ externals.push(nodeExternals({ modulesDir }));
116
+ }
117
+ else if (Array.isArray(options.externalDependencies)) {
118
+ externals.push(function (ctx, callback) {
119
+ if (options.externalDependencies.includes(ctx.request)) {
120
+ // not bundled
121
+ return callback(null, `commonjs ${ctx.request}`);
122
+ }
123
+ // bundled
124
+ callback();
125
+ });
126
+ }
127
+ const hashFormat = (0, hash_format_1.getOutputHashFormat)(options.outputHashing);
128
+ config.context = path.join(options.root, options.projectRoot);
129
+ config.target ??= options.target;
130
+ config.node = false;
131
+ config.mode =
132
+ // When the target is Node avoid any optimizations, such as replacing `process.env.NODE_ENV` with build time value.
133
+ config.target === 'node'
134
+ ? 'none'
135
+ : // Otherwise, make sure it matches `process.env.NODE_ENV`.
136
+ // When mode is development or production, webpack will automatically
137
+ // configure DefinePlugin to replace `process.env.NODE_ENV` with the
138
+ // build-time value. Thus, we need to make sure it's the same value to
139
+ // avoid conflicts.
140
+ //
141
+ // When the NODE_ENV is something else (e.g. test), then set it to none
142
+ // to prevent extra behavior from webpack.
143
+ process.env.NODE_ENV === 'development' ||
144
+ process.env.NODE_ENV === 'production'
145
+ ? process.env.NODE_ENV
146
+ : 'none';
147
+ // When target is Node, the Webpack mode will be set to 'none' which disables in memory caching and causes a full rebuild on every change.
148
+ // So to mitigate this we enable in memory caching when target is Node and in watch mode.
149
+ config.cache =
150
+ options.target === 'node' && options.watch ? { type: 'memory' } : undefined;
151
+ config.devtool =
152
+ options.sourceMap === 'hidden'
153
+ ? 'hidden-source-map'
154
+ : options.sourceMap
155
+ ? 'source-map'
156
+ : false;
157
+ config.output = {
158
+ ...config.output,
159
+ path: config.output?.path ??
160
+ (options.outputPath
161
+ ? path.join(options.root, options.outputPath)
162
+ : undefined),
163
+ filename: config.output?.filename ?? options.outputHashing
164
+ ? `[name]${hashFormat.script}.js`
165
+ : '[name].js',
166
+ chunkFilename: config.output?.chunkFilename ?? options.outputHashing
167
+ ? `[name]${hashFormat.chunk}.js`
168
+ : '[name].js',
169
+ hashFunction: config.output?.hashFunction ?? 'xxhash64',
170
+ // Disabled for performance
171
+ pathinfo: config.output?.pathinfo ?? false,
172
+ // Use CJS for Node since it has the widest support.
173
+ scriptType: config.output?.scriptType ?? options.target === 'node'
174
+ ? undefined
175
+ : 'module',
176
+ };
177
+ config.watch = options.watch;
178
+ config.watchOptions = {
179
+ poll: options.poll,
180
+ };
181
+ config.profile = options.statsJson;
182
+ config.resolve = {
183
+ ...config.resolve,
184
+ extensions: [...extensions, ...(config?.resolve?.extensions ?? [])],
185
+ alias: options.fileReplacements.reduce((aliases, replacement) => ({
186
+ ...aliases,
187
+ [replacement.replace]: replacement.with,
188
+ }), {}),
189
+ mainFields,
190
+ };
191
+ config.externals = externals;
192
+ config.optimization = {
193
+ ...config.optimization,
194
+ sideEffects: true,
195
+ minimize: typeof options.optimization === 'object'
196
+ ? !!options.optimization.scripts
197
+ : !!options.optimization,
198
+ minimizer: [
199
+ options.compiler !== 'swc'
200
+ ? new TerserPlugin({
201
+ parallel: true,
202
+ terserOptions: {
203
+ keep_classnames: true,
204
+ ecma: (0, get_terser_ecma_version_1.getTerserEcmaVersion)(path.join(options.root, options.projectRoot)),
205
+ safari10: true,
206
+ format: {
207
+ ascii_only: true,
208
+ comments: false,
209
+ webkit: true,
210
+ },
211
+ },
212
+ extractComments: false,
213
+ })
214
+ : new TerserPlugin({
215
+ minify: TerserPlugin.swcMinify,
216
+ // `terserOptions` options will be passed to `swc`
217
+ terserOptions: {
218
+ module: true,
219
+ mangle: false,
220
+ },
221
+ }),
222
+ ],
223
+ runtimeChunk: false,
224
+ concatenateModules: true,
225
+ };
226
+ config.performance = {
227
+ ...config.performance,
228
+ hints: false,
229
+ };
230
+ config.experiments = { ...config.experiments, cacheUnaffected: true };
231
+ config.ignoreWarnings = [
232
+ (x) => IGNORED_WEBPACK_WARNINGS.some((r) => typeof x === 'string' ? r.test(x) : r.test(x.message)),
233
+ ];
234
+ config.module = {
235
+ ...config.module,
236
+ // Enabled for performance
237
+ unsafeCache: true,
238
+ rules: [
239
+ ...(config?.module?.rules ?? []),
240
+ options.sourceMap && {
241
+ test: /\.js$/,
242
+ enforce: 'pre',
243
+ loader: require.resolve('source-map-loader'),
244
+ },
245
+ {
246
+ // There's an issue resolving paths without fully specified extensions
247
+ // See: https://github.com/graphql/graphql-js/issues/2721
248
+ // TODO(jack): Add a flag to turn this option on like Next.js does via experimental flag.
249
+ // See: https://github.com/vercel/next.js/pull/29880
250
+ test: /\.m?jsx?$/,
251
+ resolve: {
252
+ fullySpecified: false,
253
+ },
254
+ },
255
+ // There's an issue when using buildable libs and .js files (instead of .ts files),
256
+ // where the wrong type is used (commonjs vs esm) resulting in export-imports throwing errors.
257
+ // See: https://github.com/nrwl/nx/issues/10990
258
+ {
259
+ test: /\.js$/,
260
+ type: 'javascript/auto',
261
+ },
262
+ (0, compiler_loaders_1.createLoaderFromCompiler)(options),
263
+ ].filter((r) => !!r),
264
+ };
265
+ config.stats = {
266
+ hash: true,
267
+ timings: false,
268
+ cached: false,
269
+ cachedAssets: false,
270
+ modules: false,
271
+ warnings: true,
272
+ errors: true,
273
+ colors: !options.verbose && !options.statsJson,
274
+ chunks: !options.verbose,
275
+ assets: !!options.verbose,
276
+ chunkOrigins: !!options.verbose,
277
+ chunkModules: !!options.verbose,
278
+ children: !!options.verbose,
279
+ reasons: !!options.verbose,
280
+ version: !!options.verbose,
281
+ errorDetails: !!options.verbose,
282
+ moduleTrace: !!options.verbose,
283
+ usedExports: !!options.verbose,
284
+ };
285
+ config.plugins ??= [];
286
+ config.plugins.push(...plugins);
287
+ }
288
+ exports.applyBaseConfig = applyBaseConfig;
@@ -0,0 +1,3 @@
1
+ import { Configuration, WebpackOptionsNormalized } from 'webpack';
2
+ import { NormalizedNxWebpackPluginOptions } from '../nx-webpack-plugin-options';
3
+ export declare function applyWebConfig(options: NormalizedNxWebpackPluginOptions, config?: Partial<WebpackOptionsNormalized | Configuration>): void;