@nx/webpack 24.0.0-beta.2 → 24.0.0-beta.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 (61) hide show
  1. package/dist/index.d.ts +0 -1
  2. package/dist/index.js +0 -1
  3. package/dist/internal.d.ts +3 -0
  4. package/dist/internal.js +7 -1
  5. package/dist/ready-check.d.ts +1 -0
  6. package/dist/ready-check.js +9 -0
  7. package/dist/ready-signal.d.ts +1 -0
  8. package/dist/ready-signal.js +5 -0
  9. package/dist/src/executors/dev-server/dev-server.impl.js +38 -30
  10. package/dist/src/generators/configuration/configuration.js +14 -132
  11. package/dist/src/generators/configuration/schema.d.ts +0 -1
  12. package/dist/src/generators/convert-config-to-webpack-plugin/convert-config-to-webpack-plugin.js +82 -49
  13. package/dist/src/generators/convert-config-to-webpack-plugin/lib/extract-webpack-options.d.ts +1 -0
  14. package/dist/src/generators/convert-config-to-webpack-plugin/lib/extract-webpack-options.js +31 -2
  15. package/dist/src/generators/convert-config-to-webpack-plugin/schema.json +2 -2
  16. package/dist/src/generators/convert-to-inferred/convert-to-inferred.js +5 -4
  17. package/dist/src/generators/convert-to-inferred/utils/build-post-target-transformer.js +13 -5
  18. package/dist/src/generators/convert-to-inferred/utils/serve-post-target-transformer.js +8 -14
  19. package/dist/src/generators/init/init.js +45 -54
  20. package/dist/src/generators/init/schema.d.ts +0 -1
  21. package/dist/src/migrations/update-24-0-0/finish-inferred-conversion.md +11 -0
  22. package/dist/src/migrations/update-24-0-0/inventory.d.ts +9 -0
  23. package/dist/src/migrations/update-24-0-0/inventory.js +53 -0
  24. package/dist/src/migrations/update-24-0-0/migrate-compose-plugins.d.ts +10 -0
  25. package/dist/src/migrations/update-24-0-0/migrate-compose-plugins.js +60 -0
  26. package/dist/src/migrations/update-24-0-0/migrate-compose-plugins.md +98 -0
  27. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.d.ts +6 -0
  28. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.js +36 -0
  29. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.md +92 -0
  30. package/dist/src/plugins/nx-webpack-plugin/lib/normalize-options.d.ts +6 -0
  31. package/dist/src/plugins/nx-webpack-plugin/lib/normalize-options.js +29 -24
  32. package/dist/src/plugins/nx-webpack-plugin/nx-app-webpack-plugin.d.ts +2 -0
  33. package/dist/src/plugins/nx-webpack-plugin/nx-app-webpack-plugin.js +18 -1
  34. package/dist/src/plugins/plugin.js +24 -0
  35. package/dist/src/plugins/use-legacy-nx-plugin/use-legacy-nx-plugin.js +3 -0
  36. package/dist/src/utils/config.d.ts +8 -12
  37. package/dist/src/utils/config.js +15 -68
  38. package/dist/src/utils/deprecation.d.ts +1 -6
  39. package/dist/src/utils/deprecation.js +4 -27
  40. package/dist/src/utils/dev-server-ready-check.d.ts +48 -0
  41. package/dist/src/utils/dev-server-ready-check.js +325 -0
  42. package/dist/src/utils/dev-server-ready-signal.d.ts +29 -0
  43. package/dist/src/utils/dev-server-ready-signal.js +60 -0
  44. package/dist/src/utils/e2e-web-server-info-utils.d.ts +1 -1
  45. package/dist/src/utils/e2e-web-server-info-utils.js +2 -2
  46. package/dist/src/utils/webpack/read-webpack-options.d.ts +1 -1
  47. package/dist/src/utils/webpack/read-webpack-options.js +4 -4
  48. package/dist/src/utils/with-nx.d.ts +5 -9
  49. package/dist/src/utils/with-nx.js +5 -32
  50. package/dist/src/utils/with-web.d.ts +5 -9
  51. package/dist/src/utils/with-web.js +5 -24
  52. package/executors.json +0 -10
  53. package/migrations.json +13 -0
  54. package/package.json +20 -4
  55. package/dist/src/executors/webpack/lib/run-webpack.d.ts +0 -3
  56. package/dist/src/executors/webpack/lib/run-webpack.js +0 -36
  57. package/dist/src/executors/webpack/schema.json +0 -459
  58. package/dist/src/executors/webpack/webpack.impl.d.ts +0 -13
  59. package/dist/src/executors/webpack/webpack.impl.js +0 -117
  60. package/dist/src/utils/has-plugin.d.ts +0 -2
  61. package/dist/src/utils/has-plugin.js +0 -10
@@ -0,0 +1,325 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseServeFlags = parseServeFlags;
4
+ exports.parseServeArgv = parseServeArgv;
5
+ exports.getDevServerAddress = getDevServerAddress;
6
+ exports.waitForAddresses = waitForAddresses;
7
+ exports.readTaskOptions = readTaskOptions;
8
+ exports.enterTaskCwd = enterTaskCwd;
9
+ exports.waitForWebpackDevServer = waitForWebpackDevServer;
10
+ const internal_1 = require("@nx/devkit/internal");
11
+ const module_1 = require("module");
12
+ const net_1 = require("net");
13
+ const path_1 = require("path");
14
+ const SHORT_FLAGS = {
15
+ c: 'config',
16
+ m: 'merge',
17
+ e: 'extends',
18
+ };
19
+ const VARIADIC_FLAGS = new Set(['config', 'config-name', 'env', 'extends']);
20
+ // The flags read here that webpack-cli accepts as `--name=value`, the form
21
+ // run-commands gives named options
22
+ const NAMED_FLAGS = ['port', 'host', 'config', 'config-name', 'extends'];
23
+ /**
24
+ * The flags `webpack-cli serve` gets from the target's options, in the order
25
+ * run-commands passes them: named options, `args`, then overrides.
26
+ */
27
+ function parseServeFlags(options) {
28
+ const flags = {
29
+ configNames: [],
30
+ configs: [],
31
+ merge: false,
32
+ env: {},
33
+ extends: [],
34
+ };
35
+ const set = (name, value) => {
36
+ if (name === 'port')
37
+ flags.port = value;
38
+ else if (name === 'host')
39
+ flags.host = value;
40
+ else if (name === 'config-name')
41
+ flags.configNames.push(value);
42
+ else if (name === 'config')
43
+ flags.configs.push(value);
44
+ else if (name === 'extends')
45
+ flags.extends.push(value);
46
+ else if (name === 'env')
47
+ parseEnv(value, flags.env);
48
+ };
49
+ const argv = getServeArgv(options);
50
+ const isValue = (arg) => arg && !arg.startsWith('-');
51
+ for (let i = 0; i < argv.length; i++) {
52
+ const [, long, inline] = argv[i].match(/^--([^=]+)(?:=(.*))?$/) ?? [];
53
+ const [, short, attached] = long
54
+ ? []
55
+ : (argv[i].match(/^-(.)(.+)?$/) ?? []);
56
+ const name = long ?? SHORT_FLAGS[short];
57
+ if (!name)
58
+ continue;
59
+ if (name === 'merge') {
60
+ flags.merge = true;
61
+ continue;
62
+ }
63
+ const value = inline ?? attached ?? (isValue(argv[i + 1]) ? argv[++i] : undefined);
64
+ if (value === undefined)
65
+ continue;
66
+ set(name, value);
67
+ // Commander continues a variadic list only after a value in its own arg
68
+ if (inline === undefined &&
69
+ attached === undefined &&
70
+ VARIADIC_FLAGS.has(name)) {
71
+ while (isValue(argv[i + 1]))
72
+ set(name, argv[++i]);
73
+ }
74
+ }
75
+ return flags;
76
+ }
77
+ /**
78
+ * The `argv` webpack-cli passes to a function config: its commander options,
79
+ * with `env` set by the caller. Values stay strings except `--port`, which
80
+ * webpack-cli converts to a number when it is numeric.
81
+ */
82
+ function parseServeArgv(options, env) {
83
+ const argv = {};
84
+ const tokens = getServeArgv(options);
85
+ const isValue = (arg) => arg && !arg.startsWith('-');
86
+ for (let i = 0; i < tokens.length; i++) {
87
+ const [, long, inline] = tokens[i].match(/^--([^=]+)(?:=(.*))?$/) ?? [];
88
+ const [, short, attached] = long
89
+ ? []
90
+ : (tokens[i].match(/^-(.)(.+)?$/) ?? []);
91
+ const flag = long ?? SHORT_FLAGS[short];
92
+ if (!flag)
93
+ continue;
94
+ const negated = flag.startsWith('no-');
95
+ const name = (negated ? flag.slice(3) : flag).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
96
+ if (negated) {
97
+ argv[name] = false;
98
+ continue;
99
+ }
100
+ const values = [];
101
+ const first = inline ?? attached ?? (isValue(tokens[i + 1]) ? tokens[++i] : undefined);
102
+ if (first !== undefined) {
103
+ values.push(first);
104
+ if (inline === undefined &&
105
+ attached === undefined &&
106
+ VARIADIC_FLAGS.has(flag)) {
107
+ while (isValue(tokens[i + 1]))
108
+ values.push(tokens[++i]);
109
+ }
110
+ }
111
+ if (flag === 'env')
112
+ continue;
113
+ if (VARIADIC_FLAGS.has(flag)) {
114
+ argv[name] = [...(argv[name] ?? []), ...values];
115
+ }
116
+ else if (values.length === 0) {
117
+ argv[name] = true;
118
+ }
119
+ else {
120
+ const value = values[0];
121
+ argv[name] =
122
+ flag === 'port' && value.trim() !== '' && !isNaN(Number(value))
123
+ ? Number(value)
124
+ : value;
125
+ }
126
+ }
127
+ return { ...argv, env };
128
+ }
129
+ function getServeArgv(options) {
130
+ const args = (0, internal_1.splitShellArgs)(Array.isArray(options.args)
131
+ ? options.args.join(' ')
132
+ : typeof options.args === 'string'
133
+ ? options.args
134
+ : '');
135
+ const unparsed = Array.isArray(options.__unparsed__)
136
+ ? options.__unparsed__.map(String)
137
+ : [];
138
+ // run-commands drops a named option that overrides set, or that args set to
139
+ // another value
140
+ const named = NAMED_FLAGS.filter((name) => {
141
+ const value = options[name];
142
+ const fromArgs = flagValues(args, name);
143
+ return (['string', 'number', 'boolean'].includes(typeof value) &&
144
+ flagValues(unparsed, name).length === 0 &&
145
+ (fromArgs.length === 0 ||
146
+ (fromArgs.length === 1 && fromArgs[0] === String(value))));
147
+ }).map((name) => `--${name}=${options[name]}`);
148
+ // run-commands keeps `--env` for itself and drops it from the overrides,
149
+ // with the value it parsed for it
150
+ const env = flagValues(unparsed, 'env');
151
+ const envValue = String(env.length === 1 ? env[0] : env);
152
+ const overrides = unparsed.filter((arg, i) => !/^--env(=|$|\.[^=]*=)/.test(arg) &&
153
+ !(unparsed[i - 1] === '--env' && arg === envValue));
154
+ return [...named, ...args, ...overrides];
155
+ }
156
+ // The values yargs-parser reads for `--name`, as strings
157
+ function flagValues(argv, name) {
158
+ const values = [];
159
+ argv.forEach((arg, i) => {
160
+ if (arg === `--no-${name}`)
161
+ values.push(false);
162
+ else if (arg.startsWith(`--${name}=`)) {
163
+ values.push(arg.slice(name.length + 3));
164
+ }
165
+ else if (arg === `--${name}`) {
166
+ const next = argv[i + 1];
167
+ values.push(next && !next.startsWith('-') ? next : true);
168
+ }
169
+ });
170
+ return values;
171
+ }
172
+ // webpack-cli's `--env` parser, edge cases included
173
+ function parseEnv(value, env) {
174
+ const [allKeys, val] = value.split(/[=](.+)/, 2);
175
+ const splitKeys = allKeys.split(/\.(?!$)/);
176
+ let prevRef = env;
177
+ for (let [index, someKey] of splitKeys.entries()) {
178
+ if (someKey.endsWith('=')) {
179
+ someKey = someKey.slice(0, -1);
180
+ prevRef[someKey] = undefined;
181
+ continue;
182
+ }
183
+ if (!prevRef[someKey] || typeof prevRef[someKey] === 'string') {
184
+ prevRef[someKey] = {};
185
+ }
186
+ if (index === splitKeys.length - 1) {
187
+ prevRef[someKey] = typeof val === 'string' ? val : true;
188
+ }
189
+ prevRef = prevRef[someKey];
190
+ }
191
+ }
192
+ /**
193
+ * Where a dev server listens, or null when it picks its port or listens on a
194
+ * socket. Returns null for those, since nothing can be probed ahead of them.
195
+ */
196
+ function getDevServerAddress(devServer, flags, basePort) {
197
+ if (devServer?.ipc)
198
+ return null;
199
+ const port = flags.port ?? devServer?.port ?? basePort ?? 8080;
200
+ if (port === 'auto' || String(port) === '0')
201
+ return null;
202
+ const number = Number(port);
203
+ if (!Number.isInteger(number) || number <= 0)
204
+ return null;
205
+ const configured = flags.host ?? devServer?.host;
206
+ const host = typeof configured === 'string' ? (0, internal_1.resolveStartupHost)(configured) : undefined;
207
+ return host && !LOOPBACK_HOSTS.has(host)
208
+ ? { port: number, host }
209
+ : { port: number };
210
+ }
211
+ // The probe reaches these on loopback. `local-ip` and friends resolve to an
212
+ // interface address first, the way the dev server resolves them.
213
+ const LOOPBACK_HOSTS = new Set(['localhost', '0.0.0.0', '::']);
214
+ /** Resolves once every address accepts a TCP connection. */
215
+ async function waitForAddresses(addresses) {
216
+ await Promise.all(addresses.map(waitForAddress));
217
+ }
218
+ async function waitForAddress({ port, host }) {
219
+ const hosts = host ? [host] : ['127.0.0.1', '::1'];
220
+ while (!(await Promise.any(hosts.map((h) => connects(port, h))).catch(() => false))) {
221
+ await new Promise((r) => setTimeout(r, 250));
222
+ }
223
+ }
224
+ function connects(port, host) {
225
+ return new Promise((resolve, reject) => {
226
+ const socket = (0, net_1.createConnection)({ port, host });
227
+ socket.once('connect', () => {
228
+ socket.destroy();
229
+ resolve(true);
230
+ });
231
+ socket.once('error', (e) => {
232
+ socket.destroy();
233
+ reject(e);
234
+ });
235
+ });
236
+ }
237
+ function readTaskOptions() {
238
+ try {
239
+ return JSON.parse(process.env.NX_TASK_OPTIONS ?? '{}');
240
+ }
241
+ catch {
242
+ return {};
243
+ }
244
+ }
245
+ // The serve command runs from the target's cwd, so its config does too
246
+ function enterTaskCwd(options) {
247
+ if (options.cwd)
248
+ process.chdir((0, path_1.resolve)(options.cwd));
249
+ }
250
+ async function loadConfigExport(path) {
251
+ if (/\.(ts|mts|cts)$/.test(path)) {
252
+ const { getRootTsConfigPath } = require('@nx/js');
253
+ const { resolveUserDefinedWebpackConfig } = require('./webpack/resolve-user-defined-webpack-config');
254
+ return resolveUserDefinedWebpackConfig(path, getRootTsConfigPath());
255
+ }
256
+ const config = await (0, internal_1.loadConfigFile)(path);
257
+ // webpack-cli also unwraps a default export's own `default`
258
+ return config && typeof config === 'object' && 'default' in config
259
+ ? config.default
260
+ : config;
261
+ }
262
+ // webpack-cli merges with its own webpack-merge, and runs from the task's cwd
263
+ function loadWebpackMerge() {
264
+ const cliRequire = (0, module_1.createRequire)(require.resolve('webpack-cli', { paths: [process.cwd()] }));
265
+ return cliRequire('webpack-merge').merge;
266
+ }
267
+ /**
268
+ * The readyWhen of the inferred serve targets when the config doesn't load the
269
+ * signal plugin. Runs in the env and with the options of the serve task, reads
270
+ * the config the way `webpack-cli serve` does, and waits for each dev server it
271
+ * starts.
272
+ */
273
+ async function waitForWebpackDevServer(configPath) {
274
+ const options = readTaskOptions();
275
+ const flags = parseServeFlags(options);
276
+ // The config's file name, in the cwd of the serve task
277
+ const absoluteConfigPath = (0, path_1.resolve)(options.cwd ?? '.', configPath);
278
+ enterTaskCwd(options);
279
+ // Skips NxAppWebpackPlugin's option normalization, which nothing here uses
280
+ global.NX_GRAPH_CREATION = true;
281
+ const { readWebpackOptions } = require('./webpack/read-webpack-options');
282
+ const env = { WEBPACK_SERVE: true, ...flags.env };
283
+ const argv = parseServeArgv(options, env);
284
+ const load = async (path) => readWebpackOptions(await loadConfigExport((0, path_1.resolve)(path)), env, argv);
285
+ let configs = (await Promise.all((flags.configs.length > 0 ? flags.configs : [absoluteConfigPath]).map(load)))
286
+ .flat()
287
+ .filter((config) => flags.configNames.length === 0 ||
288
+ flags.configNames.includes(config.name));
289
+ let webpackMerge;
290
+ const merge = (...configs) => (webpackMerge ??= loadWebpackMerge())(...configs);
291
+ const resolveExtends = async (config, extendsPaths, seen) => {
292
+ delete config.extends;
293
+ const paths = extendsPaths.map((path) => (0, path_1.resolve)(path));
294
+ if (paths.some((path) => seen.includes(path))) {
295
+ throw new Error('Recursive configuration detected.');
296
+ }
297
+ const extended = (await Promise.all(paths.map(load))).flat();
298
+ if (extended.length > 0)
299
+ config = merge(...extended, config);
300
+ return config.extends
301
+ ? resolveExtends(config, [config.extends].flat(), [...seen, ...paths])
302
+ : config;
303
+ };
304
+ configs = await Promise.all(configs.map((config) => flags.extends.length > 0
305
+ ? resolveExtends(config, flags.extends, [])
306
+ : config.extends
307
+ ? resolveExtends(config, [config.extends].flat(), [])
308
+ : config));
309
+ if (flags.merge) {
310
+ if (configs.length < 2) {
311
+ throw new Error('At least two configurations are required for merge.');
312
+ }
313
+ configs = [configs.reduce((merged, config) => merge(merged, config), {})];
314
+ }
315
+ // webpack-cli starts a dev server for every config with devServer, or for
316
+ // the first config when none has one
317
+ const withDevServer = configs.filter((config) => config.devServer);
318
+ const servers = withDevServer.length > 0 ? withDevServer : configs.slice(0, 1);
319
+ const addresses = servers
320
+ .filter((config) => config.devServer !== false)
321
+ .map((config) => getDevServerAddress(config.devServer, flags, process.env.WEBPACK_DEV_SERVER_BASE_PORT));
322
+ if (addresses.some((address) => address === null))
323
+ return;
324
+ await waitForAddresses(addresses);
325
+ }
@@ -0,0 +1,29 @@
1
+ import type { AddressInfo } from 'net';
2
+ import type { Compiler } from 'webpack';
3
+ export declare const READY_SIGNAL_PLUGIN: unique symbol;
4
+ /** Whether the dev server of this config will report its readiness. */
5
+ export declare function sendsReadySignal(config: {
6
+ devServer?: unknown;
7
+ plugins?: unknown[];
8
+ }): boolean;
9
+ /**
10
+ * Reports the dev server's address to an Nx task whose readyWhen is `signal`.
11
+ * `webpack-cli serve` reads `devServer` from the compiler after plugins apply,
12
+ * so wrapping `onListening` here reaches the server it starts.
13
+ */
14
+ export declare function applyDevServerReadySignal(compiler: Compiler): void;
15
+ /** Reports the dev server's address to an Nx task whose readyWhen is `signal`. */
16
+ export declare class NxReadySignalPlugin {
17
+ readonly [READY_SIGNAL_PLUGIN] = true;
18
+ apply(compiler: Compiler): void;
19
+ }
20
+ export declare function getDevServerUrl(server: {
21
+ server?: {
22
+ address(): AddressInfo | string | null;
23
+ };
24
+ options?: {
25
+ server?: string | {
26
+ type?: string;
27
+ };
28
+ };
29
+ }): string | undefined;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.NxReadySignalPlugin = exports.READY_SIGNAL_PLUGIN = void 0;
5
+ exports.sendsReadySignal = sendsReadySignal;
6
+ exports.applyDevServerReadySignal = applyDevServerReadySignal;
7
+ exports.getDevServerUrl = getDevServerUrl;
8
+ // Set on the plugins that report readiness, so inference can find them in a
9
+ // config it has loaded
10
+ exports.READY_SIGNAL_PLUGIN = Symbol.for('@nx/ready-signal-plugin');
11
+ /** Whether the dev server of this config will report its readiness. */
12
+ function sendsReadySignal(config) {
13
+ return (typeof config.devServer === 'object' &&
14
+ !!config.devServer &&
15
+ !!config.plugins?.some((plugin) => plugin?.[exports.READY_SIGNAL_PLUGIN]));
16
+ }
17
+ /**
18
+ * Reports the dev server's address to an Nx task whose readyWhen is `signal`.
19
+ * `webpack-cli serve` reads `devServer` from the compiler after plugins apply,
20
+ * so wrapping `onListening` here reaches the server it starts.
21
+ */
22
+ function applyDevServerReadySignal(compiler) {
23
+ const devServer = compiler.options.devServer;
24
+ if (!devServer || !process.env.NX_READY_SIGNAL_SOCKET) {
25
+ return;
26
+ }
27
+ const { signalTaskReady } = require('@nx/devkit');
28
+ const onListening = devServer.onListening;
29
+ devServer.onListening = (server) => {
30
+ onListening?.(server);
31
+ signalTaskReady({ url: getDevServerUrl(server) });
32
+ };
33
+ }
34
+ /** Reports the dev server's address to an Nx task whose readyWhen is `signal`. */
35
+ class NxReadySignalPlugin {
36
+ constructor() {
37
+ this[_a] = true;
38
+ }
39
+ apply(compiler) {
40
+ applyDevServerReadySignal(compiler);
41
+ }
42
+ }
43
+ exports.NxReadySignalPlugin = NxReadySignalPlugin;
44
+ _a = exports.READY_SIGNAL_PLUGIN;
45
+ function getDevServerUrl(server) {
46
+ const address = server.server?.address();
47
+ if (!address || typeof address === 'string') {
48
+ return undefined;
49
+ }
50
+ const type = typeof server.options?.server === 'string'
51
+ ? server.options.server
52
+ : server.options?.server?.type;
53
+ const protocol = type && type !== 'http' ? 'https' : 'http';
54
+ const host = address.address === '::' || address.address === '0.0.0.0'
55
+ ? 'localhost'
56
+ : address.family === 'IPv6'
57
+ ? `[${address.address}]`
58
+ : address.address;
59
+ return `${protocol}://${host}:${address.port}/`;
60
+ }
@@ -1,2 +1,2 @@
1
1
  import { type Tree } from '@nx/devkit';
2
- export declare function getWebpackE2EWebServerInfo(tree: Tree, projectName: string, configFilePath: string, isPluginBeingAdded: boolean, e2ePortOverride?: number): Promise<import("@nx/devkit/internal").E2EWebServerDetails>;
2
+ export declare function getWebpackE2EWebServerInfo(tree: Tree, projectName: string, configFilePath: string, e2ePortOverride?: number): Promise<import("@nx/devkit/internal").E2EWebServerDetails>;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getWebpackE2EWebServerInfo = getWebpackE2EWebServerInfo;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const internal_1 = require("@nx/devkit/internal");
6
- async function getWebpackE2EWebServerInfo(tree, projectName, configFilePath, isPluginBeingAdded, e2ePortOverride) {
6
+ async function getWebpackE2EWebServerInfo(tree, projectName, configFilePath, e2ePortOverride) {
7
7
  const nxJson = (0, devkit_1.readNxJson)(tree);
8
8
  let e2ePort = e2ePortOverride ?? 4200;
9
9
  const servePort = (0, internal_1.readTargetDefaultsForTarget)('serve', nxJson.targetDefaults)
@@ -26,5 +26,5 @@ async function getWebpackE2EWebServerInfo(tree, projectName, configFilePath, isP
26
26
  defaultE2ECiBaseUrl: `http://localhost:${e2ePort}`,
27
27
  defaultE2EPort: e2ePort,
28
28
  e2EPortIsExplicit: e2ePortOverride != null,
29
- }, isPluginBeingAdded);
29
+ });
30
30
  }
@@ -8,4 +8,4 @@ import type { Configuration } from 'webpack';
8
8
  *
9
9
  * @param webpackConfig
10
10
  */
11
- export declare function readWebpackOptions(webpackConfig: unknown): Promise<Configuration[]>;
11
+ export declare function readWebpackOptions(webpackConfig: unknown, env?: Record<string, unknown>, argv?: Record<string, unknown>): Promise<Configuration[]>;
@@ -13,7 +13,9 @@ const internal_1 = require("@nx/devkit/internal");
13
13
  *
14
14
  * @param webpackConfig
15
15
  */
16
- async function readWebpackOptions(webpackConfig) {
16
+ async function readWebpackOptions(webpackConfig,
17
+ // A function config gets the production build's env unless told otherwise
18
+ env = { production: true }, argv = {}) {
17
19
  const configs = [];
18
20
  const resolveConfig = async (config) => {
19
21
  if ((0, config_1.isNxWebpackComposablePlugin)(config)) {
@@ -39,9 +41,7 @@ async function readWebpackOptions(webpackConfig) {
39
41
  });
40
42
  }
41
43
  else if (typeof config === 'function') {
42
- const resolved = await config({
43
- production: true, // we want the production build options
44
- }, {});
44
+ const resolved = await config(env, argv);
45
45
  // If the resolved configuration is an array, resolve each configuration
46
46
  return Array.isArray(resolved)
47
47
  ? (await Promise.all(resolved.map(resolveConfig))).flat()
@@ -1,12 +1,8 @@
1
- import { NxComposableWebpackPlugin } from './config';
2
- import { NxAppWebpackPluginOptions } from '../plugins/nx-webpack-plugin/nx-app-webpack-plugin-options';
1
+ import type { NxComposableWebpackPlugin } from './config';
2
+ import type { NxAppWebpackPluginOptions } from '../plugins/nx-webpack-plugin/nx-app-webpack-plugin-options';
3
3
  export type WithNxOptions = Partial<NxAppWebpackPluginOptions>;
4
4
  /**
5
- * @deprecated Will be removed in Nx v24. Use `NxAppWebpackPlugin` from
6
- * `@nx/webpack/app-plugin` in a standard webpack config and run
7
- * `nx g @nx/webpack:convert-to-inferred`. See
8
- * https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.
9
- * @param {WithNxOptions} pluginOptions
10
- * @returns {NxWebpackPlugin}
5
+ * @deprecated Use `NxAppWebpackPlugin` from `@nx/webpack/app-plugin`.
6
+ * This inert stub will be removed in Nx v25.
11
7
  */
12
- export declare function withNx(pluginOptions?: WithNxOptions): NxComposableWebpackPlugin;
8
+ export declare function withNx(_options?: WithNxOptions): NxComposableWebpackPlugin;
@@ -1,40 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.withNx = withNx;
4
- const normalize_options_1 = require("../plugins/nx-webpack-plugin/lib/normalize-options");
5
4
  const deprecation_1 = require("./deprecation");
6
- const processed = new Set();
5
+ // TODO(v25): remove the inert config-helper stubs in this file.
7
6
  /**
8
- * @deprecated Will be removed in Nx v24. Use `NxAppWebpackPlugin` from
9
- * `@nx/webpack/app-plugin` in a standard webpack config and run
10
- * `nx g @nx/webpack:convert-to-inferred`. See
11
- * https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.
12
- * @param {WithNxOptions} pluginOptions
13
- * @returns {NxWebpackPlugin}
7
+ * @deprecated Use `NxAppWebpackPlugin` from `@nx/webpack/app-plugin`.
8
+ * This inert stub will be removed in Nx v25.
14
9
  */
15
- function withNx(pluginOptions = {}) {
10
+ function withNx(_options = {}) {
16
11
  (0, deprecation_1.warnWebpackComposeHelpersDeprecation)();
17
- return function configure(config, { options, context }) {
18
- if (processed.has(config))
19
- return config;
20
- // Lazy-required so importing this module does not load the webpack bundler.
21
- const { applyBaseConfig } = require('../plugins/nx-webpack-plugin/lib/apply-base-config');
22
- applyBaseConfig({
23
- ...options,
24
- ...pluginOptions,
25
- target: options.target ?? 'web',
26
- assets: options.assets
27
- ? options.assets
28
- : pluginOptions.assets
29
- ? (0, normalize_options_1.normalizeAssets)(pluginOptions.assets, options.root, options.sourceRoot, options.projectRoot)
30
- : [],
31
- root: context.root,
32
- projectName: context.projectName,
33
- targetName: context.targetName,
34
- configurationName: context.configurationName,
35
- projectGraph: context.projectGraph,
36
- }, config);
37
- processed.add(config);
38
- return config;
39
- };
12
+ return (config) => config;
40
13
  }
@@ -1,5 +1,5 @@
1
- import { NxComposableWebpackPlugin } from './config';
2
- import { ExtraEntryPointClass, NormalizedWebpackExecutorOptions } from '../executors/webpack/schema';
1
+ import type { NxComposableWebpackPlugin } from './config';
2
+ import type { ExtraEntryPointClass, NormalizedWebpackExecutorOptions } from '../executors/webpack/schema';
3
3
  export interface WithWebOptions {
4
4
  baseHref?: string;
5
5
  crossOrigin?: 'none' | 'anonymous' | 'use-credentials';
@@ -20,11 +20,7 @@ export interface WithWebOptions {
20
20
  }
21
21
  export type MergedOptions = Omit<NormalizedWebpackExecutorOptions, keyof WithWebOptions> & WithWebOptions;
22
22
  /**
23
- * @deprecated Will be removed in Nx v24. Use `NxAppWebpackPlugin` from
24
- * `@nx/webpack/app-plugin` in a standard webpack config and run
25
- * `nx g @nx/webpack:convert-to-inferred`. See
26
- * https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.
27
- * @param {WithWebOptions} pluginOptions
28
- * @returns {NxWebpackPlugin}
23
+ * @deprecated Use `NxAppWebpackPlugin` from `@nx/webpack/app-plugin`.
24
+ * This inert stub will be removed in Nx v25.
29
25
  */
30
- export declare function withWeb(pluginOptions?: WithWebOptions): NxComposableWebpackPlugin;
26
+ export declare function withWeb(_options?: WithWebOptions): NxComposableWebpackPlugin;
@@ -2,31 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.withWeb = withWeb;
4
4
  const deprecation_1 = require("./deprecation");
5
- const processed = new Set();
5
+ // TODO(v25): remove the inert config-helper stubs in this file.
6
6
  /**
7
- * @deprecated Will be removed in Nx v24. Use `NxAppWebpackPlugin` from
8
- * `@nx/webpack/app-plugin` in a standard webpack config and run
9
- * `nx g @nx/webpack:convert-to-inferred`. See
10
- * https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.
11
- * @param {WithWebOptions} pluginOptions
12
- * @returns {NxWebpackPlugin}
7
+ * @deprecated Use `NxAppWebpackPlugin` from `@nx/webpack/app-plugin`.
8
+ * This inert stub will be removed in Nx v25.
13
9
  */
14
- function withWeb(pluginOptions = {}) {
10
+ function withWeb(_options = {}) {
15
11
  (0, deprecation_1.warnWebpackComposeHelpersDeprecation)();
16
- return function configure(config, { options, context }) {
17
- if (processed.has(config))
18
- return config;
19
- // Lazy-required so importing this module does not load the webpack bundler.
20
- const { applyWebConfig } = require('../plugins/nx-webpack-plugin/lib/apply-web-config');
21
- applyWebConfig({
22
- ...options,
23
- ...pluginOptions,
24
- projectName: context.projectName,
25
- targetName: context.targetName,
26
- configurationName: context.configurationName,
27
- projectGraph: context.projectGraph,
28
- }, config);
29
- processed.add(config);
30
- return config;
31
- };
12
+ return (config) => config;
32
13
  }
package/executors.json CHANGED
@@ -1,15 +1,5 @@
1
1
  {
2
2
  "executors": {
3
- "webpack": {
4
- "implementation": "./dist/src/executors/webpack/webpack.impl",
5
- "schema": "./dist/src/executors/webpack/schema.json",
6
- "description": "Run webpack build."
7
- },
8
- "dev-server": {
9
- "implementation": "./dist/src/executors/dev-server/dev-server.impl",
10
- "schema": "./dist/src/executors/dev-server/schema.json",
11
- "description": "Serve a web application."
12
- },
13
3
  "ssr-dev-server": {
14
4
  "implementation": "./dist/src/executors/ssr-dev-server/ssr-dev-server.impl",
15
5
  "schema": "./dist/src/executors/ssr-dev-server/schema.json",
package/migrations.json CHANGED
@@ -30,6 +30,19 @@
30
30
  "description": "Rename imports of `createNodesV2` from `@nx/webpack/plugin` to the canonical `createNodes` export.",
31
31
  "implementation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes",
32
32
  "documentation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes.md"
33
+ },
34
+ "remove-deprecated-executors": {
35
+ "version": "24.0.0-beta.3",
36
+ "description": "Converts targets using the removed `@nx/webpack` executors to inferred tasks; an AI prompt finishes the targets the converter cannot convert safely and validates the project graph.",
37
+ "implementation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors",
38
+ "prompt": "./dist/src/migrations/update-24-0-0/finish-inferred-conversion.md",
39
+ "documentation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors.md"
40
+ },
41
+ "update-24-0-0-migrate-compose-plugins": {
42
+ "version": "24.0.0-beta.3",
43
+ "description": "Converts webpack configs that use the removed `composePlugins`, `withNx`, `withWeb` and `withReact` helpers with `@nx/webpack:convert-config-to-webpack-plugin`, then hands an AI prompt the projects it could not convert and the `.old` configs it left behind.",
44
+ "implementation": "./dist/src/migrations/update-24-0-0/migrate-compose-plugins",
45
+ "prompt": "./dist/src/migrations/update-24-0-0/migrate-compose-plugins.md"
33
46
  }
34
47
  },
35
48
  "packageJsonUpdates": {