@nx/webpack 17.0.2 → 17.0.4

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 (80) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +9 -4
  3. package/generators.json +2 -2
  4. package/index.d.ts +3 -1
  5. package/index.js +7 -2
  6. package/migrations.json +6 -0
  7. package/package.json +6 -5
  8. package/plugin.d.ts +1 -0
  9. package/plugin.js +5 -0
  10. package/src/executors/dev-server/dev-server.impl.js +31 -17
  11. package/src/executors/dev-server/lib/get-dev-server-config.d.ts +2 -3
  12. package/src/executors/dev-server/lib/get-dev-server-config.js +18 -26
  13. package/src/executors/dev-server/schema.d.ts +8 -8
  14. package/src/executors/webpack/lib/normalize-options.d.ts +1 -2
  15. package/src/executors/webpack/lib/normalize-options.js +9 -53
  16. package/src/executors/webpack/schema.d.ts +10 -7
  17. package/src/executors/webpack/schema.json +30 -50
  18. package/src/executors/webpack/webpack.impl.js +36 -16
  19. package/src/generators/configuration/configuration.d.ts +3 -2
  20. package/src/generators/configuration/configuration.js +95 -23
  21. package/src/generators/configuration/schema.d.ts +1 -0
  22. package/src/generators/configuration/schema.json +1 -1
  23. package/src/generators/init/init.d.ts +1 -0
  24. package/src/generators/init/init.js +48 -23
  25. package/src/generators/init/schema.d.ts +4 -2
  26. package/src/generators/init/schema.json +18 -13
  27. package/src/migrations/update-17-2-1/webpack-config-setup.d.ts +2 -0
  28. package/src/migrations/update-17-2-1/webpack-config-setup.js +31 -0
  29. package/src/plugins/generate-package-json-plugin.d.ts +6 -4
  30. package/src/plugins/generate-package-json-plugin.js +11 -14
  31. package/src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin.d.ts +8 -0
  32. package/src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin.js +31 -0
  33. package/src/plugins/nx-webpack-plugin/lib/apply-base-config.d.ts +5 -0
  34. package/src/plugins/nx-webpack-plugin/lib/apply-base-config.js +318 -0
  35. package/src/plugins/nx-webpack-plugin/lib/apply-web-config.d.ts +5 -0
  36. package/src/plugins/nx-webpack-plugin/lib/apply-web-config.js +372 -0
  37. package/src/plugins/nx-webpack-plugin/lib/compiler-loaders.d.ts +53 -0
  38. package/src/plugins/nx-webpack-plugin/lib/compiler-loaders.js +78 -0
  39. package/src/plugins/nx-webpack-plugin/lib/get-terser-ecma-version.d.ts +1 -0
  40. package/src/plugins/nx-webpack-plugin/lib/get-terser-ecma-version.js +35 -0
  41. package/src/plugins/nx-webpack-plugin/lib/instantiate-script-plugins.d.ts +3 -0
  42. package/src/plugins/nx-webpack-plugin/lib/instantiate-script-plugins.js +42 -0
  43. package/src/plugins/nx-webpack-plugin/lib/normalize-options.d.ts +4 -0
  44. package/src/plugins/nx-webpack-plugin/lib/normalize-options.js +148 -0
  45. package/src/plugins/nx-webpack-plugin/lib/stylesheet-loaders.d.ts +73 -0
  46. package/src/plugins/nx-webpack-plugin/lib/stylesheet-loaders.js +117 -0
  47. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin-options.d.ts +216 -0
  48. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin-options.js +2 -0
  49. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin.d.ts +17 -0
  50. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin.js +48 -0
  51. package/src/plugins/plugin.d.ts +9 -0
  52. package/src/plugins/plugin.js +132 -0
  53. package/src/utils/config.d.ts +11 -6
  54. package/src/utils/config.js +48 -13
  55. package/src/utils/ensure-dependencies.d.ts +6 -0
  56. package/src/utils/ensure-dependencies.js +28 -0
  57. package/src/utils/get-client-environment.js +4 -1
  58. package/src/utils/has-plugin.d.ts +2 -0
  59. package/src/utils/has-plugin.js +11 -0
  60. package/src/utils/module-federation/dependencies.js +15 -3
  61. package/src/utils/module-federation/get-remotes-for-host.js +2 -2
  62. package/src/utils/module-federation/remotes.js +1 -1
  63. package/src/utils/module-federation/secondary-entry-points.js +1 -1
  64. package/src/utils/module-federation/typescript.js +14 -9
  65. package/src/utils/versions.d.ts +1 -0
  66. package/src/utils/versions.js +2 -1
  67. package/src/utils/webpack/deprecated-stylus-loader.js +2 -2
  68. package/src/utils/webpack/interpolate-env-variables-to-index.js +4 -1
  69. package/src/utils/webpack/plugins/postcss-cli-resources.js +2 -2
  70. package/src/utils/webpack/read-webpack-options.d.ts +10 -0
  71. package/src/utils/webpack/read-webpack-options.js +41 -0
  72. package/src/utils/webpack/resolve-user-defined-webpack-config.d.ts +3 -0
  73. package/src/utils/webpack/{custom-webpack.js → resolve-user-defined-webpack-config.js} +14 -8
  74. package/src/utils/with-nx.d.ts +4 -58
  75. package/src/utils/with-nx.js +22 -362
  76. package/src/utils/with-web.d.ts +2 -2
  77. package/src/utils/with-web.js +9 -488
  78. package/src/executors/webpack/lib/get-webpack-config.d.ts +0 -5
  79. package/src/executors/webpack/lib/get-webpack-config.js +0 -16
  80. package/src/utils/webpack/custom-webpack.d.ts +0 -2
@@ -27,8 +27,7 @@
27
27
  "compiler": {
28
28
  "type": "string",
29
29
  "description": "The compiler to use.",
30
- "enum": ["babel", "swc", "tsc"],
31
- "default": "babel"
30
+ "enum": ["babel", "swc", "tsc"]
32
31
  },
33
32
  "outputPath": {
34
33
  "type": "string",
@@ -40,8 +39,7 @@
40
39
  "type": "string",
41
40
  "alias": "platform",
42
41
  "description": "Target platform for the build, same as the Webpack target option.",
43
- "enum": ["node", "web", "webworker"],
44
- "default": "web"
42
+ "enum": ["node", "web", "webworker"]
45
43
  },
46
44
  "deleteOutputPath": {
47
45
  "type": "boolean",
@@ -50,8 +48,7 @@
50
48
  },
51
49
  "watch": {
52
50
  "type": "boolean",
53
- "description": "Enable re-building when files change.",
54
- "default": false
51
+ "description": "Enable re-building when files change."
55
52
  },
56
53
  "baseHref": {
57
54
  "type": "string",
@@ -63,22 +60,18 @@
63
60
  },
64
61
  "vendorChunk": {
65
62
  "type": "boolean",
66
- "description": "Use a separate bundle containing only vendor libraries.",
67
- "default": true
63
+ "description": "Use a separate bundle containing only vendor libraries."
68
64
  },
69
65
  "commonChunk": {
70
66
  "type": "boolean",
71
- "description": "Use a separate bundle containing code used across multiple bundles.",
72
- "default": true
67
+ "description": "Use a separate bundle containing code used across multiple bundles."
73
68
  },
74
69
  "runtimeChunk": {
75
70
  "type": "boolean",
76
- "description": "Use a separate bundle containing the runtime.",
77
- "default": true
71
+ "description": "Use a separate bundle containing the runtime."
78
72
  },
79
73
  "sourceMap": {
80
74
  "description": "Output sourcemaps. Use 'hidden' for use with error reporting tools without generating sourcemap comment.",
81
- "default": true,
82
75
  "oneOf": [
83
76
  {
84
77
  "type": "boolean"
@@ -90,13 +83,11 @@
90
83
  },
91
84
  "progress": {
92
85
  "type": "boolean",
93
- "description": "Log progress to the console while building.",
94
- "default": false
86
+ "description": "Log progress to the console while building."
95
87
  },
96
88
  "assets": {
97
89
  "type": "array",
98
90
  "description": "List of static application assets.",
99
- "default": [],
100
91
  "items": {
101
92
  "$ref": "#/definitions/assetPattern"
102
93
  }
@@ -112,26 +103,22 @@
112
103
  "description": "External Scripts which will be included before the main application entry.",
113
104
  "items": {
114
105
  "$ref": "#/definitions/extraEntryPoint"
115
- },
116
- "default": []
106
+ }
117
107
  },
118
108
  "styles": {
119
109
  "type": "array",
120
110
  "description": "External Styles which will be included with the application",
121
111
  "items": {
122
112
  "$ref": "#/definitions/extraEntryPoint"
123
- },
124
- "default": []
113
+ }
125
114
  },
126
115
  "namedChunks": {
127
116
  "type": "boolean",
128
- "description": "Names the produced bundles according to their entry file.",
129
- "default": true
117
+ "description": "Names the produced bundles according to their entry file."
130
118
  },
131
119
  "outputHashing": {
132
120
  "type": "string",
133
121
  "description": "Define the output filename cache-busting hashing mode.",
134
- "default": "none",
135
122
  "enum": ["none", "all", "media", "bundles"]
136
123
  },
137
124
  "stylePreprocessorOptions": {
@@ -143,8 +130,7 @@
143
130
  "type": "array",
144
131
  "items": {
145
132
  "type": "string"
146
- },
147
- "default": []
133
+ }
148
134
  }
149
135
  },
150
136
  "additionalProperties": false
@@ -175,13 +161,11 @@
175
161
  },
176
162
  "generatePackageJson": {
177
163
  "type": "boolean",
178
- "description": "Generates a `package.json` and pruned lock file with the project's `node_module` dependencies populated for installing in a container. If a `package.json` exists in the project's directory, it will be reused with dependencies populated.",
179
- "default": false
164
+ "description": "Generates a `package.json` and pruned lock file with the project's `node_module` dependencies populated for installing in a container. If a `package.json` exists in the project's directory, it will be reused with dependencies populated."
180
165
  },
181
166
  "transformers": {
182
167
  "type": "array",
183
168
  "description": "List of TypeScript Compiler Transfomers Plugins.",
184
- "default": [],
185
169
  "aliases": ["tsPlugins"],
186
170
  "items": {
187
171
  "$ref": "#/definitions/transformerPattern"
@@ -223,18 +207,15 @@
223
207
  }
224
208
  }
225
209
  ],
226
- "description": "Dependencies to keep external to the bundle. (`all` (default), `none`, or an array of module names)",
227
- "default": "all"
210
+ "description": "Dependencies to keep external to the bundle. (`all` (default), `none`, or an array of module names)"
228
211
  },
229
212
  "extractCss": {
230
213
  "type": "boolean",
231
- "description": "Extract CSS into a `.css` file.",
232
- "default": true
214
+ "description": "Extract CSS into a `.css` file."
233
215
  },
234
216
  "subresourceIntegrity": {
235
217
  "type": "boolean",
236
- "description": "Enables the use of subresource integrity validation.",
237
- "default": false
218
+ "description": "Enables the use of subresource integrity validation."
238
219
  },
239
220
  "polyfills": {
240
221
  "type": "string",
@@ -244,28 +225,30 @@
244
225
  },
245
226
  "verbose": {
246
227
  "type": "boolean",
247
- "description": "Emits verbose output",
248
- "default": false
228
+ "description": "Emits verbose output"
249
229
  },
250
230
  "statsJson": {
251
231
  "type": "boolean",
252
- "description": "Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or `<https://webpack.github.io/analyse>`.",
253
- "default": false
232
+ "description": "Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or `<https://webpack.github.io/analyse>`."
254
233
  },
255
234
  "isolatedConfig": {
256
235
  "type": "boolean",
257
236
  "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.).",
237
+ "default": true,
238
+ "x-deprecated": "Automatic configuration of Webpack is deprecated in favor of an explicit 'webpack.config.js' file. This option will be removed in Nx 19. See https://nx.dev/recipes/webpack/webpack-config-setup."
239
+ },
240
+ "standardWebpackConfigFunction": {
241
+ "type": "boolean",
242
+ "description": "Set to true if the webpack config exports a standard webpack function, not an Nx-specific one. See: https://webpack.js.org/configuration/configuration-types/#exporting-a-function",
258
243
  "default": false
259
244
  },
260
245
  "extractLicenses": {
261
246
  "type": "boolean",
262
- "description": "Extract all licenses in a separate file, in the case of production builds only.",
263
- "default": false
247
+ "description": "Extract all licenses in a separate file, in the case of production builds only."
264
248
  },
265
249
  "memoryLimit": {
266
250
  "type": "number",
267
- "description": "Memory limit for type checking service process in `MB`.",
268
- "default": 2048
251
+ "description": "Memory limit for type checking service process in `MB`."
269
252
  },
270
253
  "fileReplacements": {
271
254
  "description": "Replace files with other files in the build.",
@@ -286,18 +269,16 @@
286
269
  },
287
270
  "additionalProperties": false,
288
271
  "required": ["replace", "with"]
289
- },
290
- "default": []
272
+ }
291
273
  },
292
274
  "buildLibsFromSource": {
293
275
  "type": "boolean",
294
- "description": "Read buildable libraries from source instead of building them separately.",
276
+ "description": "Read buildable libraries from source instead of building them separately. If set to `false`, the `tsConfig` option must also be set to remap paths.",
295
277
  "default": true
296
278
  },
297
279
  "generateIndexHtml": {
298
280
  "type": "boolean",
299
- "description": "Generates `index.html` file to the output path. This can be turned off if using a webpack plugin to generate HTML such as `html-webpack-plugin`.",
300
- "default": true
281
+ "description": "Generates `index.html` file to the output path. This can be turned off if using a webpack plugin to generate HTML such as `html-webpack-plugin`."
301
282
  },
302
283
  "postcssConfig": {
303
284
  "type": "string",
@@ -312,8 +293,7 @@
312
293
  },
313
294
  "babelUpwardRootMode": {
314
295
  "type": "boolean",
315
- "description": "Whether to set rootmode to upward. See https://babeljs.io/docs/en/options#rootmode",
316
- "default": false
296
+ "description": "Whether to set rootmode to upward. See https://babeljs.io/docs/en/options#rootmode"
317
297
  },
318
298
  "babelConfig": {
319
299
  "type": "string",
@@ -321,7 +301,7 @@
321
301
  "x-completion-type": "file"
322
302
  }
323
303
  },
324
- "required": ["tsConfig", "main"],
304
+ "required": [],
325
305
  "definitions": {
326
306
  "assetPattern": {
327
307
  "oneOf": [
@@ -7,40 +7,52 @@ const rxjs_1 = require("rxjs");
7
7
  const operators_1 = require("rxjs/operators");
8
8
  const path_1 = require("path");
9
9
  const buildable_libs_utils_1 = require("@nx/js/src/utils/buildable-libs-utils");
10
- const get_webpack_config_1 = require("./lib/get-webpack-config");
11
10
  const run_webpack_1 = require("./lib/run-webpack");
12
11
  const fs_1 = require("../../utils/fs");
13
- const custom_webpack_1 = require("../../utils/webpack/custom-webpack");
12
+ const resolve_user_defined_webpack_config_1 = require("../../utils/webpack/resolve-user-defined-webpack-config");
14
13
  const normalize_options_1 = require("./lib/normalize-options");
15
- async function getWebpackConfigs(options, projectRoot, context) {
14
+ const config_1 = require("../../utils/config");
15
+ const with_nx_1 = require("../../utils/with-nx");
16
+ const js_1 = require("@nx/js");
17
+ const with_web_1 = require("../../utils/with-web");
18
+ async function getWebpackConfigs(options, context) {
16
19
  if (options.isolatedConfig && !options.webpackConfig) {
17
20
  throw new Error(`Using "isolatedConfig" without a "webpackConfig" is not supported.`);
18
21
  }
19
- let customWebpack = null;
22
+ let userDefinedWebpackConfig = null;
20
23
  if (options.webpackConfig) {
21
- customWebpack = (0, custom_webpack_1.resolveCustomWebpackConfig)(options.webpackConfig, options.tsConfig.startsWith(context.root)
22
- ? options.tsConfig
23
- : (0, path_1.join)(context.root, options.tsConfig));
24
- if (typeof customWebpack.then === 'function') {
25
- customWebpack = await customWebpack;
24
+ userDefinedWebpackConfig = (0, resolve_user_defined_webpack_config_1.resolveUserDefinedWebpackConfig)(options.webpackConfig, (0, js_1.getRootTsConfigPath)());
25
+ if (typeof userDefinedWebpackConfig.then === 'function') {
26
+ userDefinedWebpackConfig = await userDefinedWebpackConfig;
26
27
  }
27
28
  }
28
29
  const config = options.isolatedConfig
29
30
  ? {}
30
- : (0, get_webpack_config_1.getWebpackConfig)(context, options);
31
- if (customWebpack) {
32
- return await customWebpack(config, {
31
+ : (options.target === 'web'
32
+ ? (0, config_1.composePluginsSync)((0, with_nx_1.withNx)(options), (0, with_web_1.withWeb)(options))
33
+ : (0, with_nx_1.withNx)(options))({}, { options, context });
34
+ if (typeof userDefinedWebpackConfig === 'function' &&
35
+ ((0, config_1.isNxWebpackComposablePlugin)(userDefinedWebpackConfig) ||
36
+ !options.standardWebpackConfigFunction)) {
37
+ // Old behavior, call the Nx-specific webpack config function that user exports
38
+ return await userDefinedWebpackConfig(config, {
33
39
  options,
34
40
  context,
35
41
  configuration: context.configurationName, // backwards compat
36
42
  });
37
43
  }
44
+ else if (userDefinedWebpackConfig) {
45
+ // New behavior, we want the webpack config to export object
46
+ return userDefinedWebpackConfig;
47
+ }
38
48
  else {
39
- // If the user has no webpackConfig specified then we always have to apply
49
+ // Fallback case, if we cannot find a webpack config path
40
50
  return config;
41
51
  }
42
52
  }
43
53
  async function* webpackExecutor(_options, context) {
54
+ // Default to production build.
55
+ process.env['NODE_ENV'] ||= 'production';
44
56
  const metadata = context.projectsConfigurations.projects[context.projectName];
45
57
  const sourceRoot = metadata.sourceRoot;
46
58
  const options = (0, normalize_options_1.normalizeOptions)(_options, context.root, metadata.root, sourceRoot);
@@ -52,6 +64,12 @@ async function* webpackExecutor(_options, context) {
52
64
  process.env.NODE_ENV ||= isScriptOptimizeOn
53
65
  ? 'production'
54
66
  : 'development';
67
+ process.env.NX_BUILD_LIBS_FROM_SOURCE = `${options.buildLibsFromSource}`;
68
+ process.env.NX_BUILD_TARGET = (0, devkit_1.targetToTargetString)({
69
+ project: context.projectName,
70
+ target: context.targetName,
71
+ configuration: context.configurationName,
72
+ });
55
73
  if (options.compiler === 'swc') {
56
74
  try {
57
75
  require.resolve('swc-loader');
@@ -61,7 +79,6 @@ async function* webpackExecutor(_options, context) {
61
79
  devkit_1.logger.error(`Missing SWC dependencies: @swc/core, swc-loader. Make sure you install them first.`);
62
80
  return {
63
81
  success: false,
64
- outfile: (0, path_1.resolve)(context.root, options.outputPath, options.outputFileName),
65
82
  options,
66
83
  };
67
84
  }
@@ -69,16 +86,17 @@ async function* webpackExecutor(_options, context) {
69
86
  if (!options.buildLibsFromSource && context.targetName) {
70
87
  const { dependencies } = (0, buildable_libs_utils_1.calculateProjectBuildableDependencies)(context.taskGraph, context.projectGraph, context.root, context.projectName, context.targetName, context.configurationName);
71
88
  options.tsConfig = (0, buildable_libs_utils_1.createTmpTsConfig)(options.tsConfig, context.root, metadata.root, dependencies);
89
+ process.env.NX_TSCONFIG_PATH = options.tsConfig;
72
90
  }
73
91
  // Delete output path before bundling
74
- if (options.deleteOutputPath) {
92
+ if (options.deleteOutputPath && options.outputPath) {
75
93
  (0, fs_1.deleteOutputDir)(context.root, options.outputPath);
76
94
  }
77
95
  if (options.generatePackageJson && metadata.projectType !== 'application') {
78
96
  devkit_1.logger.warn((0, devkit_1.stripIndents) `The project ${context.projectName} is using the 'generatePackageJson' option which is deprecated for library projects. It should only be used for applications.
79
97
  For libraries, configure the project to use the '@nx/dependency-checks' ESLint rule instead (https://nx.dev/packages/eslint-plugin/documents/dependency-checks).`);
80
98
  }
81
- const configs = await getWebpackConfigs(options, metadata.root, context);
99
+ const configs = await getWebpackConfigs(options, context);
82
100
  return yield* (0, rxjs_for_await_1.eachValueFrom)((0, rxjs_1.of)(configs).pipe((0, operators_1.mergeMap)((config) => (Array.isArray(config) ? (0, rxjs_1.from)(config) : (0, rxjs_1.of)(config))),
83
101
  // Run build sequentially and bail when first one fails.
84
102
  (0, operators_1.mergeScan)((acc, config) => {
@@ -94,6 +112,8 @@ async function* webpackExecutor(_options, context) {
94
112
  // Collect build results as an array.
95
113
  (0, operators_1.bufferCount)(Array.isArray(configs) ? configs.length : 1), (0, operators_1.switchMap)(async (results) => {
96
114
  const success = results.every((result) => Boolean(result) && !result.hasErrors());
115
+ // TODO(jack): This should read output from webpack config if provided.
116
+ // The outfile is only used by NestJS, where `@nx/js:node` executor requires it to run the file.
97
117
  return {
98
118
  success,
99
119
  outfile: (0, path_1.resolve)(context.root, options.outputPath, options.outputFileName),
@@ -1,4 +1,5 @@
1
- import type { Tree } from '@nx/devkit';
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
2
  import { ConfigurationGeneratorSchema } from './schema';
3
- export declare function configurationGenerator(tree: Tree, options: ConfigurationGeneratorSchema): Promise<import("@nx/devkit").GeneratorCallback>;
3
+ export declare function configurationGenerator(tree: Tree, options: ConfigurationGeneratorSchema): Promise<GeneratorCallback>;
4
+ export declare function configurationGeneratorInternal(tree: Tree, options: ConfigurationGeneratorSchema): Promise<GeneratorCallback>;
4
5
  export default configurationGenerator;
@@ -1,24 +1,44 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.configurationGenerator = void 0;
3
+ exports.configurationGeneratorInternal = exports.configurationGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const init_1 = require("../init/init");
6
- async function configurationGenerator(tree, options) {
7
- const task = await (0, init_1.webpackInitGenerator)(tree, {
6
+ const has_plugin_1 = require("../../utils/has-plugin");
7
+ const add_build_target_defaults_1 = require("@nx/devkit/src/generators/add-build-target-defaults");
8
+ const ensure_dependencies_1 = require("../../utils/ensure-dependencies");
9
+ function configurationGenerator(tree, options) {
10
+ return configurationGeneratorInternal(tree, { addPlugin: false, ...options });
11
+ }
12
+ exports.configurationGenerator = configurationGenerator;
13
+ async function configurationGeneratorInternal(tree, options) {
14
+ const tasks = [];
15
+ const nxJson = (0, devkit_1.readNxJson)(tree);
16
+ const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
17
+ nxJson.useInferencePlugins !== false;
18
+ options.addPlugin ??= addPluginDefault;
19
+ const initTask = await (0, init_1.webpackInitGenerator)(tree, {
8
20
  ...options,
9
21
  skipFormat: true,
10
22
  });
23
+ tasks.push(initTask);
24
+ const depsTask = (0, ensure_dependencies_1.ensureDependencies)(tree, {
25
+ compiler: options.compiler === 'babel' ? undefined : options.compiler,
26
+ });
27
+ tasks.push(depsTask);
11
28
  checkForTargetConflicts(tree, options);
12
- addBuildTarget(tree, options);
13
- if (options.devServer) {
14
- addServeTarget(tree, options);
29
+ if (!(0, has_plugin_1.hasPlugin)(tree)) {
30
+ addBuildTarget(tree, options);
31
+ if (options.devServer) {
32
+ addServeTarget(tree, options);
33
+ }
15
34
  }
35
+ createWebpackConfig(tree, options);
16
36
  if (!options.skipFormat) {
17
37
  await (0, devkit_1.formatFiles)(tree);
18
38
  }
19
- return task;
39
+ return (0, devkit_1.runTasksInSerial)(...tasks);
20
40
  }
21
- exports.configurationGenerator = configurationGenerator;
41
+ exports.configurationGeneratorInternal = configurationGeneratorInternal;
22
42
  function checkForTargetConflicts(tree, options) {
23
43
  if (options.skipValidation)
24
44
  return;
@@ -30,7 +50,7 @@ function checkForTargetConflicts(tree, options) {
30
50
  throw new Error(`Project "${project.name}" already has a serve target. Pass --skipValidation to ignore this error.`);
31
51
  }
32
52
  }
33
- function addBuildTarget(tree, options) {
53
+ function createWebpackConfig(tree, options) {
34
54
  const project = (0, devkit_1.readProjectConfiguration)(tree, options.project);
35
55
  const buildOptions = {
36
56
  target: options.target,
@@ -40,20 +60,28 @@ function addBuildTarget(tree, options) {
40
60
  tsConfig: options.tsConfig ?? (0, devkit_1.joinPathFragments)(project.root, 'tsconfig.app.json'),
41
61
  webpackConfig: (0, devkit_1.joinPathFragments)(project.root, 'webpack.config.js'),
42
62
  };
43
- if (options.webpackConfig) {
44
- buildOptions.webpackConfig = options.webpackConfig;
45
- }
46
- if (options.babelConfig) {
47
- buildOptions.babelConfig = options.babelConfig;
48
- }
49
- else if (options.compiler === 'babel') {
50
- // If no babel config file is provided then write a default one, otherwise build will fail.
51
- (0, devkit_1.writeJson)(tree, (0, devkit_1.joinPathFragments)(project.root, '.babelrc'), {
52
- presets: ['@nx/js/babel'],
53
- });
54
- }
55
63
  if (options.target === 'web') {
56
- tree.write((0, devkit_1.joinPathFragments)(project.root, 'webpack.config.js'), `
64
+ tree.write((0, devkit_1.joinPathFragments)(project.root, 'webpack.config.js'), (0, has_plugin_1.hasPlugin)(tree)
65
+ ? `
66
+ const { NxWebpackPlugin } = require('@nx/webpack');
67
+ const { join } = require('path');
68
+
69
+ module.exports = {
70
+ output: {
71
+ path: join(__dirname, '${(0, devkit_1.offsetFromRoot)(project.root)}${buildOptions.outputPath}'),
72
+ },
73
+ plugins: [
74
+ new NxWebpackPlugin({
75
+ target: '${buildOptions.target}',
76
+ tsConfig: '${buildOptions.tsConfig}',
77
+ compiler: '${buildOptions.compiler}',
78
+ main: '${buildOptions.main}',
79
+ outputHashing: '${buildOptions.target !== 'web' ? 'none' : 'all'}',
80
+ })
81
+ ],
82
+ }
83
+ `
84
+ : `
57
85
  const { composePlugins, withNx, withWeb } = require('@nx/webpack');
58
86
 
59
87
  // Nx plugins for webpack.
@@ -65,7 +93,27 @@ module.exports = composePlugins(withNx(), withWeb(), (config) => {
65
93
  `);
66
94
  }
67
95
  else {
68
- tree.write((0, devkit_1.joinPathFragments)(project.root, 'webpack.config.js'), `
96
+ tree.write((0, devkit_1.joinPathFragments)(project.root, 'webpack.config.js'), (0, has_plugin_1.hasPlugin)(tree)
97
+ ? `
98
+ const { NxWebpackPlugin } = require('@nx/webpack');
99
+ const { join } = require('path');
100
+
101
+ module.exports = {
102
+ output: {
103
+ path: join(__dirname, '${(0, devkit_1.offsetFromRoot)(project.root)}${buildOptions.outputPath}'),
104
+ },
105
+ plugins: [
106
+ new NxWebpackPlugin({
107
+ target: '${buildOptions.target}',
108
+ tsConfig: '${buildOptions.tsConfig}',
109
+ compiler: '${buildOptions.compiler}',
110
+ main: '${buildOptions.main}',
111
+ outputHashing: '${buildOptions.target !== 'web' ? 'none' : 'all'}',
112
+ })
113
+ ],
114
+ }
115
+ `
116
+ : `
69
117
  const { composePlugins, withNx } = require('@nx/webpack');
70
118
 
71
119
  // Nx plugins for webpack.
@@ -76,6 +124,30 @@ module.exports = composePlugins(withNx(), (config) => {
76
124
  });
77
125
  `);
78
126
  }
127
+ }
128
+ function addBuildTarget(tree, options) {
129
+ (0, add_build_target_defaults_1.addBuildTargetDefaults)(tree, '@nx/webpack:webpack');
130
+ const project = (0, devkit_1.readProjectConfiguration)(tree, options.project);
131
+ const buildOptions = {
132
+ target: options.target,
133
+ outputPath: (0, devkit_1.joinPathFragments)('dist', project.root),
134
+ compiler: options.compiler ?? 'swc',
135
+ main: options.main ?? (0, devkit_1.joinPathFragments)(project.root, 'src/main.ts'),
136
+ tsConfig: options.tsConfig ?? (0, devkit_1.joinPathFragments)(project.root, 'tsconfig.app.json'),
137
+ webpackConfig: (0, devkit_1.joinPathFragments)(project.root, 'webpack.config.js'),
138
+ };
139
+ if (options.webpackConfig) {
140
+ buildOptions.webpackConfig = options.webpackConfig;
141
+ }
142
+ if (options.babelConfig) {
143
+ buildOptions.babelConfig = options.babelConfig;
144
+ }
145
+ else if (options.compiler === 'babel') {
146
+ // If no babel config file is provided then write a default one, otherwise build will fail.
147
+ (0, devkit_1.writeJson)(tree, (0, devkit_1.joinPathFragments)(project.root, '.babelrc'), {
148
+ presets: ['@nx/js/babel'],
149
+ });
150
+ }
79
151
  (0, devkit_1.updateProjectConfiguration)(tree, options.project, {
80
152
  ...project,
81
153
  targets: {
@@ -10,4 +10,5 @@ export interface ConfigurationGeneratorSchema {
10
10
  target?: 'node' | 'web' | 'webworker';
11
11
  webpackConfig?: string;
12
12
  babelConfig?: string;
13
+ addPlugin?: boolean;
13
14
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "$id": "NxWebpackProject",
4
4
  "cli": "nx",
5
5
  "title": "Add Webpack Configuration to a project",
@@ -1,4 +1,5 @@
1
1
  import { GeneratorCallback, Tree } from '@nx/devkit';
2
2
  import { Schema } from './schema';
3
3
  export declare function webpackInitGenerator(tree: Tree, schema: Schema): Promise<GeneratorCallback>;
4
+ export declare function webpackInitGeneratorInternal(tree: Tree, schema: Schema): Promise<GeneratorCallback>;
4
5
  export default webpackInitGenerator;
@@ -1,35 +1,60 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.webpackInitGenerator = void 0;
3
+ exports.webpackInitGeneratorInternal = exports.webpackInitGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
- const add_swc_dependencies_1 = require("@nx/js/src/utils/swc/add-swc-dependencies");
5
+ const update_package_scripts_1 = require("@nx/devkit/src/utils/update-package-scripts");
6
+ const plugin_1 = require("../../plugins/plugin");
6
7
  const versions_1 = require("../../utils/versions");
7
- async function webpackInitGenerator(tree, schema) {
8
- const tasks = [];
9
- const devDependencies = {
10
- '@nx/webpack': versions_1.nxVersion,
11
- };
12
- if (schema.compiler === 'swc') {
13
- devDependencies['swc-loader'] = versions_1.swcLoaderVersion;
14
- const addSwcTask = (0, add_swc_dependencies_1.addSwcDependencies)(tree);
15
- tasks.push(addSwcTask);
8
+ function webpackInitGenerator(tree, schema) {
9
+ return webpackInitGeneratorInternal(tree, { addPlugin: false, ...schema });
10
+ }
11
+ exports.webpackInitGenerator = webpackInitGenerator;
12
+ async function webpackInitGeneratorInternal(tree, schema) {
13
+ const nxJson = (0, devkit_1.readNxJson)(tree);
14
+ const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
15
+ nxJson.useInferencePlugins !== false;
16
+ schema.addPlugin ??= addPluginDefault;
17
+ if (schema.addPlugin) {
18
+ addPlugin(tree);
16
19
  }
17
- if (schema.compiler === 'tsc') {
18
- devDependencies['tslib'] = versions_1.tsLibVersion;
20
+ let installTask = () => { };
21
+ if (!schema.skipPackageJson) {
22
+ const devDependencies = {
23
+ '@nx/webpack': versions_1.nxVersion,
24
+ '@nx/web': versions_1.nxVersion,
25
+ };
26
+ if (schema.addPlugin) {
27
+ devDependencies['webpack-cli'] = versions_1.webpackCliVersion;
28
+ }
29
+ installTask = (0, devkit_1.addDependenciesToPackageJson)(tree, {}, devDependencies, undefined, schema.keepExistingVersions);
19
30
  }
20
- if (schema.uiFramework === 'react') {
21
- devDependencies['@pmmmwh/react-refresh-webpack-plugin'] =
22
- versions_1.reactRefreshWebpackPluginVersion;
23
- devDependencies['@svgr/webpack'] = versions_1.svgrWebpackVersion;
24
- devDependencies['react-refresh'] = versions_1.reactRefreshVersion;
25
- devDependencies['url-loader'] = versions_1.urlLoaderVersion;
31
+ if (schema.updatePackageScripts) {
32
+ await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
26
33
  }
27
34
  if (!schema.skipFormat) {
28
35
  await (0, devkit_1.formatFiles)(tree);
29
36
  }
30
- const baseInstalTask = (0, devkit_1.addDependenciesToPackageJson)(tree, {}, devDependencies);
31
- tasks.push(baseInstalTask);
32
- return (0, devkit_1.runTasksInSerial)(...tasks);
37
+ return installTask;
38
+ }
39
+ exports.webpackInitGeneratorInternal = webpackInitGeneratorInternal;
40
+ function addPlugin(tree) {
41
+ const nxJson = (0, devkit_1.readNxJson)(tree);
42
+ nxJson.plugins ??= [];
43
+ for (const plugin of nxJson.plugins) {
44
+ if (typeof plugin === 'string'
45
+ ? plugin === '@nx/webpack/plugin'
46
+ : plugin.plugin === '@nx/webpack/plugin') {
47
+ return;
48
+ }
49
+ }
50
+ nxJson.plugins.push({
51
+ plugin: '@nx/webpack/plugin',
52
+ options: {
53
+ buildTargetName: 'build',
54
+ serveTargetName: 'serve',
55
+ previewTargetName: 'preview',
56
+ },
57
+ });
58
+ (0, devkit_1.updateNxJson)(tree, nxJson);
33
59
  }
34
- exports.webpackInitGenerator = webpackInitGenerator;
35
60
  exports.default = webpackInitGenerator;
@@ -1,5 +1,7 @@
1
1
  export interface Schema {
2
- compiler?: 'babel' | 'swc' | 'tsc';
3
- uiFramework?: 'react' | 'none';
4
2
  skipFormat?: boolean;
3
+ skipPackageJson?: boolean;
4
+ keepExistingVersions?: boolean;
5
+ updatePackageScripts?: boolean;
6
+ addPlugin?: boolean;
5
7
  }