@nx/next 24.0.0-beta.1 → 24.0.0-beta.3
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.
- package/dist/plugins/component-testing.js +19 -62
- package/dist/plugins/with-nx.d.ts +14 -10
- package/dist/plugins/with-nx.js +24 -255
- package/dist/src/generators/application/application.js +1 -2
- package/dist/src/generators/application/files/common/next.config.js__tmpl__ +0 -22
- package/dist/src/generators/application/lib/add-e2e.js +5 -6
- package/dist/src/generators/application/lib/add-linting.js +0 -1
- package/dist/src/generators/application/lib/add-project.js +1 -46
- package/dist/src/generators/application/lib/add-vitest.js +0 -1
- package/dist/src/generators/application/lib/normalize-options.js +0 -4
- package/dist/src/generators/application/schema.d.ts +0 -1
- package/dist/src/generators/custom-server/custom-server.js +6 -25
- package/dist/src/generators/custom-server/files/server/main.ts__tmpl__ +3 -3
- package/dist/src/generators/custom-server/files/tsconfig.server.json__tmpl__ +1 -1
- package/dist/src/generators/cypress-component-configuration/cypress-component-configuration.js +1 -14
- package/dist/src/generators/cypress-component-configuration/schema.d.ts +0 -1
- package/dist/src/generators/init/init.js +14 -28
- package/dist/src/generators/init/schema.d.ts +0 -1
- package/dist/src/generators/library/lib/add-rollup-server-entry.js +7 -16
- package/dist/src/generators/library/lib/normalize-options.js +0 -5
- package/dist/src/generators/library/library.js +1 -2
- package/dist/src/generators/library/schema.d.ts +0 -1
- package/dist/src/migrations/update-24-0-0/finish-inferred-conversion.md +12 -0
- package/dist/src/migrations/update-24-0-0/migrate-config-helpers.md +80 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.d.ts +6 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.js +18 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.md +89 -0
- package/dist/src/utils/compose-plugins.d.ts +6 -1
- package/dist/src/utils/compose-plugins.js +20 -29
- package/dist/src/utils/deprecation.d.ts +0 -5
- package/dist/src/utils/deprecation.js +9 -31
- package/executors.json +1 -12
- package/migrations.json +12 -0
- package/package.json +13 -13
- package/dist/src/executors/build/build.impl.d.ts +0 -5
- package/dist/src/executors/build/build.impl.js +0 -154
- package/dist/src/executors/build/lib/check-project.d.ts +0 -1
- package/dist/src/executors/build/lib/check-project.js +0 -11
- package/dist/src/executors/build/lib/create-next-config-file.d.ts +0 -14
- package/dist/src/executors/build/lib/create-next-config-file.js +0 -171
- package/dist/src/executors/build/lib/update-package-json.d.ts +0 -3
- package/dist/src/executors/build/lib/update-package-json.js +0 -31
- package/dist/src/executors/build/schema.json +0 -98
- package/dist/src/executors/server/custom-server.impl.d.ts +0 -6
- package/dist/src/executors/server/custom-server.impl.js +0 -37
- package/dist/src/executors/server/schema.json +0 -85
- package/dist/src/executors/server/server.impl.d.ts +0 -6
- package/dist/src/executors/server/server.impl.js +0 -115
- package/dist/src/utils/runtime-version-utils.d.ts +0 -7
- package/dist/src/utils/runtime-version-utils.js +0 -28
|
@@ -15,21 +15,13 @@ async function customServerGenerator(host, options) {
|
|
|
15
15
|
const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
|
|
16
16
|
? p === '@nx/next/plugin'
|
|
17
17
|
: p.plugin === '@nx/next/plugin');
|
|
18
|
-
if (
|
|
19
|
-
devkit_1.logger.error(`
|
|
18
|
+
if (!hasPlugin) {
|
|
19
|
+
devkit_1.logger.error(`The "@nx/next/plugin" plugin is not registered in nx.json. Did you generate ${options.project} with "nx g @nx/next:app"?`);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
// In Nx 18 next artifacts are inside the project root .next/ & dist/ (for custom server)
|
|
23
23
|
const outputPath = `dist/${project.root}-server`;
|
|
24
24
|
const root = project.root;
|
|
25
|
-
if ((!root ||
|
|
26
|
-
!outputPath ||
|
|
27
|
-
!project.targets?.build?.configurations?.development ||
|
|
28
|
-
!project.targets?.build?.configurations?.production) &&
|
|
29
|
-
!hasPlugin) {
|
|
30
|
-
devkit_1.logger.error(`Project ${options.project} has invalid config. Did you generate it with "nx g @nx/next:app"?`);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
25
|
if (project.targets?.['build-custom-server'] ||
|
|
34
26
|
project.targets?.['serve-custom-server']) {
|
|
35
27
|
devkit_1.logger.warn(`Project ${options.project} has custom server targets already: build-custom-server, serve-custom-server. Remove these targets from project and try again.`);
|
|
@@ -37,14 +29,11 @@ async function customServerGenerator(host, options) {
|
|
|
37
29
|
}
|
|
38
30
|
// In Nx 18 next artifacts are inside the project root .next/ & dist/ (for custom server)
|
|
39
31
|
// So we need ensure the mapping is correct from dist to the project root
|
|
40
|
-
const projectPathFromDist =
|
|
41
|
-
? `../../${(0, devkit_1.offsetFromRoot)(project.root)}${project.root}`
|
|
42
|
-
: `${(0, devkit_1.offsetFromRoot)(`dist/${project.root}`)}${project.root}`;
|
|
32
|
+
const projectPathFromDist = `../../${(0, devkit_1.offsetFromRoot)(project.root)}${project.root}`;
|
|
43
33
|
const offset = (0, devkit_1.offsetFromRoot)(project.root);
|
|
44
34
|
const isTsSolution = (0, internal_2.isUsingTsSolutionSetup)(host);
|
|
45
35
|
(0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, 'files'), project.root, {
|
|
46
36
|
...options,
|
|
47
|
-
hasPlugin,
|
|
48
37
|
projectPathFromDist,
|
|
49
38
|
offsetFromRoot: offset,
|
|
50
39
|
projectRoot: project.root,
|
|
@@ -53,17 +42,9 @@ async function customServerGenerator(host, options) {
|
|
|
53
42
|
: './tsconfig.json',
|
|
54
43
|
tmpl: '',
|
|
55
44
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
project.targets.serve.configurations.development.customServerTarget = `${options.project}:serve-custom-server:development`;
|
|
60
|
-
project.targets.serve.configurations.production.customServerTarget = `${options.project}:serve-custom-server:production`;
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
project.targets['build'] = {
|
|
64
|
-
dependsOn: ['^build', 'build-custom-server'],
|
|
65
|
-
};
|
|
66
|
-
}
|
|
45
|
+
project.targets['build'] = {
|
|
46
|
+
dependsOn: ['^build', 'build-custom-server'],
|
|
47
|
+
};
|
|
67
48
|
project.targets['build-custom-server'] = {
|
|
68
49
|
executor: options.compiler === 'tsc' ? '@nx/js:tsc' : '@nx/js:swc',
|
|
69
50
|
defaultConfiguration: 'production',
|
|
@@ -11,12 +11,12 @@ import * as path from 'path';
|
|
|
11
11
|
import next from 'next';
|
|
12
12
|
|
|
13
13
|
// Next.js server options:
|
|
14
|
-
// -
|
|
15
|
-
// - The fallback
|
|
14
|
+
// - `NX_NEXT_DIR` overrides the Next.js app directory.
|
|
15
|
+
// - The fallback resolves the app directory from the built server's location.
|
|
16
16
|
// - Feel free to change this to suit your needs.
|
|
17
17
|
|
|
18
18
|
const dev = process.env.NODE_ENV === 'development';
|
|
19
|
-
const dir = process.env.NX_NEXT_DIR ||
|
|
19
|
+
const dir = process.env.NX_NEXT_DIR || path.join(__dirname, '<%- projectPathFromDist %>');
|
|
20
20
|
|
|
21
21
|
// HTTP Server options:
|
|
22
22
|
// - Feel free to change this to suit your needs.
|
package/dist/src/generators/cypress-component-configuration/cypress-component-configuration.js
CHANGED
|
@@ -10,10 +10,7 @@ const path_1 = require("path");
|
|
|
10
10
|
const versions_1 = require("../../utils/versions");
|
|
11
11
|
const assert_supported_next_version_1 = require("../../utils/assert-supported-next-version");
|
|
12
12
|
function cypressComponentConfiguration(tree, options) {
|
|
13
|
-
return cypressComponentConfigurationInternal(tree,
|
|
14
|
-
addPlugin: false,
|
|
15
|
-
...options,
|
|
16
|
-
});
|
|
13
|
+
return cypressComponentConfigurationInternal(tree, options);
|
|
17
14
|
}
|
|
18
15
|
async function cypressComponentConfigurationInternal(tree, options) {
|
|
19
16
|
(0, assert_supported_next_version_1.assertSupportedNextVersion)(tree);
|
|
@@ -24,24 +21,14 @@ async function cypressComponentConfigurationInternal(tree, options) {
|
|
|
24
21
|
skipFormat: true,
|
|
25
22
|
framework: 'next',
|
|
26
23
|
jsx: true,
|
|
27
|
-
addPlugin: options.addPlugin,
|
|
28
24
|
}));
|
|
29
25
|
const { webpackInitGenerator } = (0, devkit_1.ensurePackage)('@nx/webpack', versions_1.nxVersion);
|
|
30
26
|
tasks.push(await webpackInitGenerator(tree, {
|
|
31
27
|
skipFormat: true,
|
|
32
|
-
addPlugin: options.addPlugin,
|
|
33
28
|
}));
|
|
34
29
|
const { ensureDependencies, } = require('@nx/webpack/internal');
|
|
35
30
|
tasks.push(ensureDependencies(tree, { compiler: 'swc', uiFramework: 'react' }));
|
|
36
31
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
37
|
-
if (projectConfig.targets?.['component-test']?.executor ===
|
|
38
|
-
'@nx/cypress:cypress') {
|
|
39
|
-
projectConfig.targets['component-test'].options = {
|
|
40
|
-
...projectConfig.targets['component-test'].options,
|
|
41
|
-
skipServe: true,
|
|
42
|
-
};
|
|
43
|
-
(0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
|
|
44
|
-
}
|
|
45
32
|
await addFiles(tree, projectConfig, options);
|
|
46
33
|
if (!options.skipFormat) {
|
|
47
34
|
await (0, devkit_1.formatFiles)(tree);
|
|
@@ -33,37 +33,23 @@ async function updateDependencies(host, schema) {
|
|
|
33
33
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
34
34
|
}
|
|
35
35
|
function nextInitGenerator(tree, schema) {
|
|
36
|
-
return nextInitGeneratorInternal(tree,
|
|
36
|
+
return nextInitGeneratorInternal(tree, schema);
|
|
37
37
|
}
|
|
38
38
|
async function nextInitGeneratorInternal(host, schema) {
|
|
39
39
|
(0, assert_supported_next_version_1.assertSupportedNextVersion)(host);
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'next-serve-static',
|
|
54
|
-
],
|
|
55
|
-
buildDepsTargetName: [
|
|
56
|
-
'build-deps',
|
|
57
|
-
'next:build-deps',
|
|
58
|
-
'next-build-deps',
|
|
59
|
-
],
|
|
60
|
-
watchDepsTargetName: [
|
|
61
|
-
'watch-deps',
|
|
62
|
-
'next:watch-deps',
|
|
63
|
-
'next-watch-deps',
|
|
64
|
-
],
|
|
65
|
-
}, schema.updatePackageScripts);
|
|
66
|
-
}
|
|
40
|
+
const { createNodesV2, } = require('../../plugins/plugin');
|
|
41
|
+
await (0, internal_1.addPlugin)(host, await (0, devkit_1.createProjectGraphAsync)(), '@nx/next/plugin', createNodesV2, {
|
|
42
|
+
startTargetName: ['start', 'next:start', 'next-start'],
|
|
43
|
+
buildTargetName: ['build', 'next:build', 'next-build'],
|
|
44
|
+
devTargetName: ['dev', 'next:dev', 'next-dev'],
|
|
45
|
+
serveStaticTargetName: [
|
|
46
|
+
'serve-static',
|
|
47
|
+
'next:serve-static',
|
|
48
|
+
'next-serve-static',
|
|
49
|
+
],
|
|
50
|
+
buildDepsTargetName: ['build-deps', 'next:build-deps', 'next-build-deps'],
|
|
51
|
+
watchDepsTargetName: ['watch-deps', 'next:watch-deps', 'next-watch-deps'],
|
|
52
|
+
}, schema.updatePackageScripts);
|
|
67
53
|
(0, add_gitignore_entry_1.addGitIgnoreEntry)(host);
|
|
68
54
|
let installTask = () => { };
|
|
69
55
|
if (!schema.skipPackageJson) {
|
|
@@ -10,22 +10,13 @@ const devkit_1 = require("@nx/devkit");
|
|
|
10
10
|
function addRollupServerEntry(tree, options) {
|
|
11
11
|
const serverEntry = `src/server.${options.js ? 'js' : 'ts'}`;
|
|
12
12
|
const rollupConfigPath = (0, devkit_1.joinPathFragments)(options.projectRoot, 'rollup.config.cjs');
|
|
13
|
-
if (tree.exists(rollupConfigPath)) {
|
|
14
|
-
|
|
15
|
-
const updated = content.replace(/^(\s*)main: .*\n/m, (line, indent) => line + `${indent}additionalEntryPoints: ['./${serverEntry}'],\n`);
|
|
16
|
-
if (updated === content) {
|
|
17
|
-
throw new Error(`Could not add the server entry to ${rollupConfigPath}: "main" option not found.`);
|
|
18
|
-
}
|
|
19
|
-
tree.write(rollupConfigPath, updated);
|
|
20
|
-
return;
|
|
13
|
+
if (!tree.exists(rollupConfigPath)) {
|
|
14
|
+
throw new Error(`Could not add the server entry: ${rollupConfigPath} not found.`);
|
|
21
15
|
}
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
25
|
-
throw new Error(`Could not add the server entry to
|
|
16
|
+
const content = tree.read(rollupConfigPath, 'utf-8');
|
|
17
|
+
const updated = content.replace(/^(\s*)main: .*\n/m, (line, indent) => line + `${indent}additionalEntryPoints: ['./${serverEntry}'],\n`);
|
|
18
|
+
if (updated === content) {
|
|
19
|
+
throw new Error(`Could not add the server entry to ${rollupConfigPath}: "main" option not found.`);
|
|
26
20
|
}
|
|
27
|
-
|
|
28
|
-
(0, devkit_1.joinPathFragments)(options.projectRoot, serverEntry),
|
|
29
|
-
];
|
|
30
|
-
(0, devkit_1.updateProjectConfiguration)(tree, options.projectName, project);
|
|
21
|
+
tree.write(rollupConfigPath, updated);
|
|
31
22
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.normalizeOptions = normalizeOptions;
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
5
4
|
const internal_1 = require("@nx/devkit/internal");
|
|
6
5
|
const internal_2 = require("@nx/js/internal");
|
|
7
6
|
async function normalizeOptions(host, options) {
|
|
@@ -12,10 +11,6 @@ async function normalizeOptions(host, options) {
|
|
|
12
11
|
directory: options.directory,
|
|
13
12
|
importPath: options.importPath,
|
|
14
13
|
});
|
|
15
|
-
const nxJson = (0, devkit_1.readNxJson)(host);
|
|
16
|
-
const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
17
|
-
nxJson.useInferencePlugins !== false;
|
|
18
|
-
options.addPlugin ??= addPlugin;
|
|
19
14
|
const isUsingTsSolutionConfig = (0, internal_2.isUsingTsSolutionSetup)(host);
|
|
20
15
|
return {
|
|
21
16
|
...options,
|
|
@@ -15,7 +15,6 @@ const versions_1 = require("../../utils/versions");
|
|
|
15
15
|
const internal_2 = require("@nx/js/internal");
|
|
16
16
|
async function libraryGenerator(host, rawOptions) {
|
|
17
17
|
return await libraryGeneratorInternal(host, {
|
|
18
|
-
addPlugin: false,
|
|
19
18
|
useProjectJson: true,
|
|
20
19
|
...rawOptions,
|
|
21
20
|
});
|
|
@@ -23,7 +22,7 @@ async function libraryGenerator(host, rawOptions) {
|
|
|
23
22
|
async function libraryGeneratorInternal(host, rawOptions) {
|
|
24
23
|
(0, assert_supported_next_version_1.assertSupportedNextVersion)(host);
|
|
25
24
|
const tasks = [];
|
|
26
|
-
const addTsPlugin = (0, internal_2.shouldConfigureTsSolutionSetup)(host
|
|
25
|
+
const addTsPlugin = (0, internal_2.shouldConfigureTsSolutionSetup)(host);
|
|
27
26
|
const jsInitTask = await (0, js_1.initGenerator)(host, {
|
|
28
27
|
js: rawOptions.js,
|
|
29
28
|
addTsPlugin,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Replace removed @nx/next executors with inferred tasks
|
|
2
|
+
|
|
3
|
+
Nx 24 removed `@nx/next:build`, `@nx/next:server` (including old `@nrwl` aliases).
|
|
4
|
+
|
|
5
|
+
Before changing anything, check for leftover work: a project target, a package.json target or a `targetDefaults` entry still uses a removed executor, or the advisory context reports a conversion error. If none applies, make no changes and stop. Treat each advisory-context item as pending work.
|
|
6
|
+
|
|
7
|
+
1. Inspect all affected projects and workspace defaults. Repair config-loading errors first. Do not restore executor registrations or install older Nx packages.
|
|
8
|
+
2. Move executor options into next.config and Next CLI flags. Preserve webpack callbacks, transpilePackages, workspace libraries, assets, output directory, environment settings and the intended Webpack/Turbopack mode. Build every migrated Next application unless expensive validation was explicitly skipped.
|
|
9
|
+
3. Register `@nx/next/plugin` with options/includes that preserve custom target names and mixed inferred/explicit projects. Replace remaining removed-executor targets, including those in package.json and filtered targetDefaults. Transfer their behavior before removing obsolete defaults. Preserve configurations, dependencies, cache inputs/outputs and environment behavior. Do not silently delete unsupported options or unrelated targets. Migrate old @nrwl aliases too.
|
|
10
|
+
4. Run project graph creation with the daemon and graph cache disabled (`NX_DAEMON=false NX_CACHE_PROJECT_GRAPH=false`), using the workspace package manager. Inspect resolved project targets and verify each migrated entrypoint exists and is inferred (a thin alias to an inferred target is acceptable). Resolve graph errors before completing this migration, even if task validation was skipped. Configs must load for subsequent migrations.
|
|
11
|
+
5. By default run relevant real builds/tests with task cache disabled, including alternate configurations. Honor an existing preference to skip expensive task validation; otherwise offer that option when validation is slow. Skipping expensive tasks never skips conversion or the graph check. Report each skipped task as unverified. Never weaken assertions or change application behavior to make checks pass.
|
|
12
|
+
6. Report converted projects, graph validation, task results and any skipped checks. Unconverted targets or a broken graph mean the migration is incomplete. Investigate task failures and distinguish missing environment prerequisites from conversion regressions; do not claim a working workspace with unresolved regressions.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Migrate Next.js config helpers
|
|
2
|
+
|
|
3
|
+
Remove `withNx` and `composePlugins` from Next.js configurations. Compatibility
|
|
4
|
+
exports are inert stubs so old imports do not strand graph creation. Helper behavior was removed in Nx 24. Preserve
|
|
5
|
+
application behavior; successful config loading is not proof of equivalence.
|
|
6
|
+
|
|
7
|
+
## Inspect before changing
|
|
8
|
+
|
|
9
|
+
Find all `next.config.*` files and imported configuration helpers, including
|
|
10
|
+
aliased imports from `@nx/next` and `@nx/next/plugins/with-nx`. Read project targets,
|
|
11
|
+
configuration overrides, package scripts, tsconfigs, and workspace package exports.
|
|
12
|
+
Record the installed Next version and whether each command uses webpack or
|
|
13
|
+
Turbopack. Preserve both; do not switch bundlers or upgrade Next as part of this
|
|
14
|
+
migration. Handle explicit and inferred targets without changing their types. Nx 24
|
|
15
|
+
removed the `@nx/next` build and serve executors, and a separate migration converts
|
|
16
|
+
their targets, so do not add them back.
|
|
17
|
+
|
|
18
|
+
Record existing output locations, build/serve/export commands, and custom behavior.
|
|
19
|
+
Build a baseline before edits if possible; otherwise use an isolated checkout of
|
|
20
|
+
the old lockfile. Do not downgrade the working workspace or silently skip validation.
|
|
21
|
+
|
|
22
|
+
## Unwrap the configuration
|
|
23
|
+
|
|
24
|
+
Preserve the original export form and Next's config-function contract, including
|
|
25
|
+
phase, defaultConfig, async results, and the order of third-party wrappers. Replace
|
|
26
|
+
Nx composition with direct composition of the remaining wrappers. Inspect wrapper
|
|
27
|
+
APIs rather than assume every wrapper accepts the same arguments or returns an
|
|
28
|
+
object. Do not discard custom webpack callbacks or overwrite other wrappers.
|
|
29
|
+
|
|
30
|
+
Remove the `nx` property from the final Next config only after accounting for every
|
|
31
|
+
option it contains. Merely deleting `withNx` does not migrate those options.
|
|
32
|
+
`@nx/next:convert-to-inferred` does not finish this job: its existing config rewrite
|
|
33
|
+
preserves `withNx` and moves executor options into `nx`.
|
|
34
|
+
|
|
35
|
+
## Preserve required behavior
|
|
36
|
+
|
|
37
|
+
Test whether each behavior is needed on this workspace's installed Next version
|
|
38
|
+
and existing bundler. Prefer native options. If no native equivalent preserves the
|
|
39
|
+
behavior, inline the necessary implementation in a local, user-owned config helper.
|
|
40
|
+
The user will maintain that code; do not import Nx's deprecated wrapper or private
|
|
41
|
+
implementation as the replacement.
|
|
42
|
+
|
|
43
|
+
- **Workspace libraries:** verify both tsconfig paths and package-manager workspace
|
|
44
|
+
dependencies, including TypeScript/JSX sources and package exports. Add explicit
|
|
45
|
+
`transpilePackages` entries only where required, merging existing entries. Do not
|
|
46
|
+
assume all workspace libraries are transpiled without configuration.
|
|
47
|
+
- **Output paths:** preserve build output and standalone deployment expectations,
|
|
48
|
+
explicit `distDir`, the `outputPath` the removed executor set, and any
|
|
49
|
+
`NX_NEXT_OUTPUT_PATH` behavior. Keep development output compatible with the
|
|
50
|
+
existing bundler. Check Nx's declared cache outputs still cover actual files.
|
|
51
|
+
- **Static export:** preserve `output: 'export'`, the export destination, and the
|
|
52
|
+
commands that serve it. Do not replace a static export with a server deployment.
|
|
53
|
+
- **File replacements/assets:** account for options in both targets and `nx` config.
|
|
54
|
+
Preserve workspace-relative paths, configuration selection, copy destinations,
|
|
55
|
+
and ignores. Use native facilities or inline the required code, then check output.
|
|
56
|
+
- **ESM imports:** test `.js` specifiers pointing to TypeScript sources. Keep or
|
|
57
|
+
inline `extensionAlias` only where the installed webpack setup needs it; do not
|
|
58
|
+
assume a webpack option affects Turbopack.
|
|
59
|
+
- **CSS/SCSS modules:** test imports from shared libraries under the existing
|
|
60
|
+
bundler. Remove obsolete loader patches only after verifying native support.
|
|
61
|
+
- **Babel:** preserve opted-in `babelUpwardRootMode` behavior and custom transforms.
|
|
62
|
+
Inline required webpack behavior if native configuration is insufficient.
|
|
63
|
+
- **Legacy lint behavior:** retain the effective build behavior where supported;
|
|
64
|
+
do not emit removed Next options on versions that reject them.
|
|
65
|
+
|
|
66
|
+
Avoid patches to Next internals when native configuration works. If behavior cannot
|
|
67
|
+
be preserved, describe the exact blocker and ask for a decision rather than silently
|
|
68
|
+
changing the application.
|
|
69
|
+
|
|
70
|
+
## Acceptance
|
|
71
|
+
|
|
72
|
+
Recreate the graph without its disk cache. Run affected builds without task-cache
|
|
73
|
+
reuse, relevant tests, production startup/static serving, and dev behavior. Check
|
|
74
|
+
shared-library rendering, CSS/SCSS, copied assets, aliases, output locations, and
|
|
75
|
+
configuration-specific behavior against the baseline. Use semantic comparisons
|
|
76
|
+
where generated hashes differ.
|
|
77
|
+
|
|
78
|
+
Search configs and imported helpers for remaining Nx wrappers. Already migrated
|
|
79
|
+
configs should be unchanged. Report evidence and unresolved differences; never
|
|
80
|
+
remove custom behavior or weaken tests to obtain a successful build.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = update;
|
|
4
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
5
|
+
function update(tree) {
|
|
6
|
+
return (0, internal_1.migrateRemovedExecutors)(tree, [
|
|
7
|
+
'@nx/next:build',
|
|
8
|
+
'@nx/next:server',
|
|
9
|
+
'@nrwl/next:build',
|
|
10
|
+
'@nrwl/next:server',
|
|
11
|
+
], async (tree, options) => {
|
|
12
|
+
const { convertToInferred } = require('../../generators/convert-to-inferred/convert-to-inferred');
|
|
13
|
+
// The callback only prints the options the converter could not carry
|
|
14
|
+
// over; migrateRemovedExecutors discards it.
|
|
15
|
+
const flushLogs = await convertToInferred(tree, options);
|
|
16
|
+
flushLogs();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#### Convert `@nx/next` build and server targets to inferred tasks
|
|
2
|
+
|
|
3
|
+
Nx 24 removes the `@nx/next:build` and `@nx/next:server` executors and their `@nrwl` aliases. The migration registers `@nx/next/plugin` in `nx.json` and converts the targets that use those executors to inferred tasks. It moves build options into `next.config.*`. A target with nothing left to override is removed from project configuration. When several projects share the same remaining options, those options move to a `targetDefaults` entry scoped to the plugin. `targetDefaults` entries keyed by a removed executor are removed once no target uses that executor.
|
|
4
|
+
|
|
5
|
+
The migration lists the targets the converter cannot convert safely. In agentic runs, an AI prompt finishes them and validates the project graph.
|
|
6
|
+
|
|
7
|
+
#### Sample code changes
|
|
8
|
+
|
|
9
|
+
##### Before
|
|
10
|
+
|
|
11
|
+
```json title="apps/my-app/project.json"
|
|
12
|
+
{
|
|
13
|
+
"name": "my-app",
|
|
14
|
+
"targets": {
|
|
15
|
+
"build": {
|
|
16
|
+
"executor": "@nx/next:build",
|
|
17
|
+
"defaultConfiguration": "production",
|
|
18
|
+
"options": {
|
|
19
|
+
"outputPath": "dist/apps/my-app"
|
|
20
|
+
},
|
|
21
|
+
"configurations": {
|
|
22
|
+
"development": {
|
|
23
|
+
"outputPath": "apps/my-app"
|
|
24
|
+
},
|
|
25
|
+
"production": {}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"serve": {
|
|
29
|
+
"executor": "@nx/next:server",
|
|
30
|
+
"defaultConfiguration": "development",
|
|
31
|
+
"options": {
|
|
32
|
+
"dev": true,
|
|
33
|
+
"port": 4200
|
|
34
|
+
},
|
|
35
|
+
"configurations": {
|
|
36
|
+
"development": {
|
|
37
|
+
"buildTarget": "my-app:build:development",
|
|
38
|
+
"dev": true
|
|
39
|
+
},
|
|
40
|
+
"production": {
|
|
41
|
+
"buildTarget": "my-app:build:production",
|
|
42
|
+
"dev": false
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
##### After
|
|
51
|
+
|
|
52
|
+
```json title="apps/my-app/project.json"
|
|
53
|
+
{
|
|
54
|
+
"name": "my-app",
|
|
55
|
+
"targets": {
|
|
56
|
+
"build": {
|
|
57
|
+
"configurations": {
|
|
58
|
+
"development": {}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"serve": {
|
|
62
|
+
"configurations": {
|
|
63
|
+
"development": {},
|
|
64
|
+
"production": {}
|
|
65
|
+
},
|
|
66
|
+
"defaultConfiguration": "development",
|
|
67
|
+
"options": {
|
|
68
|
+
"port": 4200
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```json title="nx.json"
|
|
76
|
+
{
|
|
77
|
+
"plugins": [
|
|
78
|
+
{
|
|
79
|
+
"plugin": "@nx/next/plugin",
|
|
80
|
+
"options": {
|
|
81
|
+
"buildTargetName": "build",
|
|
82
|
+
"devTargetName": "serve",
|
|
83
|
+
"serveStaticTargetName": "serve-static",
|
|
84
|
+
"startTargetName": "start"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
```
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { NextConfig } from 'next';
|
|
2
2
|
import type { NextConfigFn, NextPlugin, NextPluginThatReturnsConfigFn } from './config';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Export the Next.js config directly and compose
|
|
5
|
+
* any other wrappers yourself.
|
|
6
|
+
* This inert stub will be removed in Nx v25.
|
|
7
|
+
*/
|
|
8
|
+
export declare function composePlugins(..._plugins: (NextPlugin | NextPluginThatReturnsConfigFn)[]): (baseConfig: NextConfig) => NextConfigFn;
|
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.composePlugins = composePlugins;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (typeof configOrFn === 'function') {
|
|
25
|
-
config = await configOrFn(phase, context);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
config = configOrFn;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return config;
|
|
32
|
-
};
|
|
4
|
+
// TODO(v25): remove the inert config-helper stubs in this file.
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Export the Next.js config directly and compose
|
|
7
|
+
* any other wrappers yourself.
|
|
8
|
+
* This inert stub will be removed in Nx v25.
|
|
9
|
+
*/
|
|
10
|
+
function composePlugins(..._plugins) {
|
|
11
|
+
return (baseConfig) => async (phase) => {
|
|
12
|
+
const { PHASE_PRODUCTION_SERVER } = require('next/constants');
|
|
13
|
+
// Copied into production builds, so only resolve the warning on Nx task runs.
|
|
14
|
+
if (phase !== PHASE_PRODUCTION_SERVER &&
|
|
15
|
+
!global.NX_GRAPH_CREATION &&
|
|
16
|
+
process.env.NX_TASK_TARGET_TARGET) {
|
|
17
|
+
const { workspaceRoot } = require('@nx/devkit');
|
|
18
|
+
const { warnComposePluginsDeprecation } = require(require.resolve('@nx/next/src/utils/deprecation', {
|
|
19
|
+
paths: [workspaceRoot],
|
|
20
|
+
}));
|
|
21
|
+
warnComposePluginsDeprecation(phase);
|
|
22
|
+
}
|
|
23
|
+
return baseConfig;
|
|
33
24
|
};
|
|
34
25
|
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
declare global {
|
|
2
2
|
var NX_GRAPH_CREATION: boolean;
|
|
3
3
|
}
|
|
4
|
-
export declare const NEXT_BUILD_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/next:build` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/next:convert-to-inferred` to migrate to the `@nx/next/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
|
|
5
|
-
export declare const NEXT_SERVER_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/next:server` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/next:convert-to-inferred` to migrate to the `@nx/next/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
|
|
6
|
-
export declare function warnNextBuildExecutorDeprecation(): void;
|
|
7
|
-
export declare function warnNextServerExecutorDeprecation(): void;
|
|
8
|
-
export declare function warnNextExecutorGenerating(): void;
|
|
9
4
|
export declare const WITHNX_DEPRECATION_MESSAGE: string;
|
|
10
5
|
export declare const COMPOSE_PLUGINS_DEPRECATION_MESSAGE: string;
|
|
11
6
|
export declare function warnWithNxDeprecation(): void;
|
|
@@ -1,39 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.COMPOSE_PLUGINS_DEPRECATION_MESSAGE = exports.WITHNX_DEPRECATION_MESSAGE =
|
|
4
|
-
exports.warnNextBuildExecutorDeprecation = warnNextBuildExecutorDeprecation;
|
|
5
|
-
exports.warnNextServerExecutorDeprecation = warnNextServerExecutorDeprecation;
|
|
6
|
-
exports.warnNextExecutorGenerating = warnNextExecutorGenerating;
|
|
3
|
+
exports.COMPOSE_PLUGINS_DEPRECATION_MESSAGE = exports.WITHNX_DEPRECATION_MESSAGE = void 0;
|
|
7
4
|
exports.warnWithNxDeprecation = warnWithNxDeprecation;
|
|
8
5
|
exports.warnComposePluginsDeprecation = warnComposePluginsDeprecation;
|
|
9
6
|
const devkit_1 = require("@nx/devkit");
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function warnNextServerExecutorDeprecation() {
|
|
19
|
-
devkit_1.logger.warn(exports.NEXT_SERVER_EXECUTOR_DEPRECATION_MESSAGE);
|
|
20
|
-
}
|
|
21
|
-
// Fired when the @nx/next:application generator is about to generate targets
|
|
22
|
-
// that use the deprecated executors — i.e. when @nx/next/plugin isn't
|
|
23
|
-
// registered in nx.json. Surfaces the deprecation at generation time rather
|
|
24
|
-
// than only when the user later runs the generated targets.
|
|
25
|
-
function warnNextExecutorGenerating() {
|
|
26
|
-
devkit_1.logger.warn('Generating targets that use the deprecated `@nx/next:build` and `@nx/next:server` executors. These executors will be removed in Nx v24. Run `nx g @nx/next:convert-to-inferred` next to migrate these targets to the `@nx/next/plugin` inferred plugin and prevent future generators from emitting executor targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.');
|
|
27
|
-
}
|
|
28
|
-
// TODO(v24): Remove the `withNx`/`composePlugins` config wrappers. Modern
|
|
29
|
-
// workspaces resolve libraries via package manager workspaces and Next.js
|
|
30
|
-
// transpiles workspace source automatically, so a plain `next.config.js` works.
|
|
31
|
-
exports.WITHNX_DEPRECATION_MESSAGE = '[Nx] `withNx()` from `@nx/next` is deprecated and will be removed in Nx v24. ' +
|
|
32
|
-
'A plain `next.config.js` is now the recommended pattern; Next.js transpiles workspace libraries automatically. ' +
|
|
33
|
-
'See https://nx.dev/docs/technologies/react/next/Guides/next-config-setup for the migration recipe.';
|
|
34
|
-
exports.COMPOSE_PLUGINS_DEPRECATION_MESSAGE = '[Nx] `composePlugins()` from `@nx/next` is deprecated and will be removed in Nx v24. ' +
|
|
35
|
-
'Compose Next.js plugins directly in your `next.config.js` and remove the `@nx/next` import. ' +
|
|
36
|
-
'See https://nx.dev/docs/technologies/react/next/Guides/next-config-setup for the migration recipe.';
|
|
7
|
+
// Helper behavior was removed in v24; exports remain only as inert stubs.
|
|
8
|
+
// Keep old configs loadable; preserve required wrapper behavior in user config.
|
|
9
|
+
exports.WITHNX_DEPRECATION_MESSAGE = '[Nx] `withNx()` from `@nx/next` was removed in Nx v24. The remaining export is an inert compatibility stub and does not configure builds. ' +
|
|
10
|
+
'Migrate to native Next.js configuration and inline any remaining required behavior. ' +
|
|
11
|
+
'Follow the config-helper migration instructions generated by `nx migrate`.';
|
|
12
|
+
exports.COMPOSE_PLUGINS_DEPRECATION_MESSAGE = '[Nx] `composePlugins()` from `@nx/next` was removed in Nx v24. The remaining export is an inert compatibility stub and does not configure builds. ' +
|
|
13
|
+
'Compose Next.js plugins directly, preserving their order and config-function behavior. ' +
|
|
14
|
+
'Follow the config-helper migration instructions generated by `nx migrate`.';
|
|
37
15
|
let warnedWithNx = false;
|
|
38
16
|
function warnWithNxDeprecation() {
|
|
39
17
|
if (warnedWithNx)
|
package/executors.json
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
"executors": {
|
|
3
|
-
"build": {
|
|
4
|
-
"implementation": "./dist/src/executors/build/build.impl",
|
|
5
|
-
"schema": "./dist/src/executors/build/schema.json",
|
|
6
|
-
"description": "Build a Next.js application."
|
|
7
|
-
},
|
|
8
|
-
"server": {
|
|
9
|
-
"implementation": "./dist/src/executors/server/server.impl",
|
|
10
|
-
"schema": "./dist/src/executors/server/schema.json",
|
|
11
|
-
"description": "Serve a Next.js application."
|
|
12
|
-
}
|
|
13
|
-
}
|
|
2
|
+
"executors": {}
|
|
14
3
|
}
|