@nx/next 23.2.0-beta.1 → 23.2.0-beta.11
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/README.md +2 -2
- package/dist/plugins/component-testing.js +7 -6
- package/dist/plugins/with-nx.js +1 -1
- package/dist/src/executors/build/build.impl.js +7 -11
- package/dist/src/executors/build/lib/update-package-json.d.ts +1 -1
- package/dist/src/generators/application/application.js +9 -7
- package/dist/src/generators/application/files/app/api/hello/route.ts__tmpl__ +1 -1
- package/dist/src/generators/application/files/app/page.tsx__tmpl__ +2 -0
- package/dist/src/generators/application/files/pages/__fileName__.tsx__tmpl__ +2 -0
- package/dist/src/generators/application/lib/add-e2e.js +3 -2
- package/dist/src/generators/application/lib/add-jest.js +6 -3
- package/dist/src/generators/application/lib/add-linting.js +8 -7
- package/dist/src/generators/application/lib/add-vitest.d.ts +3 -0
- package/dist/src/generators/application/lib/add-vitest.js +116 -0
- package/dist/src/generators/application/lib/normalize-options.js +1 -1
- package/dist/src/generators/application/schema.d.ts +8 -4
- package/dist/src/generators/application/schema.json +16 -7
- package/dist/src/generators/custom-server/custom-server.js +14 -15
- package/dist/src/generators/library/lib/normalize-options.d.ts +2 -0
- package/dist/src/generators/library/lib/normalize-options.js +3 -0
- package/dist/src/generators/library/library.js +21 -4
- package/dist/src/generators/library/schema.d.ts +6 -2
- package/dist/src/generators/library/schema.json +13 -9
- package/dist/src/migrations/update-22-2-0/ai-instructions-for-next-16.md +2 -6
- package/dist/src/migrations/update-23-2-0/add-svgr-webpack-if-used.d.ts +2 -0
- package/dist/src/migrations/update-23-2-0/add-svgr-webpack-if-used.js +33 -0
- package/dist/src/migrations/update-23-2-0/add-svgr-webpack-if-used.md +28 -0
- package/dist/src/plugins/plugin.js +2 -4
- package/dist/src/utils/add-gitignore-entry.d.ts +1 -1
- package/dist/src/utils/create-copy-plugin.js +11 -11
- package/dist/src/utils/versions.d.ts +1 -0
- package/dist/src/utils/versions.js +2 -1
- package/generators.json +1 -1
- package/migrations.json +6 -0
- package/package.json +18 -12
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
<div style="text-align: center;">
|
|
9
9
|
|
|
10
|
-
[]()
|
|
10
|
+
[](<>)
|
|
11
11
|
[](https://www.npmjs.com/package/nx)
|
|
12
|
-
[]()
|
|
12
|
+
[](<>)
|
|
13
13
|
[](http://commitizen.github.io/cz-cli/)
|
|
14
14
|
[](https://go.nx.dev/community)
|
|
15
15
|
[](https://nx.dev/docs/features/ci-features/sandboxing)
|
|
@@ -7,16 +7,17 @@ const devkit_1 = require("@nx/devkit");
|
|
|
7
7
|
const internal_2 = require("@nx/js/internal");
|
|
8
8
|
const react_1 = require("@nx/react");
|
|
9
9
|
const internal_3 = require("@nx/react/internal");
|
|
10
|
-
const webpack_1 = require("@nx/webpack");
|
|
11
|
-
const internal_4 = require("@nx/webpack/internal");
|
|
12
|
-
const configuration_1 = require("nx/src/config/configuration");
|
|
13
10
|
const path_1 = require("path");
|
|
11
|
+
const internal_4 = require("@nx/devkit/internal");
|
|
14
12
|
function nxComponentTestingPreset(pathToConfig, options) {
|
|
15
13
|
if (global.NX_GRAPH_CREATION) {
|
|
16
14
|
// this is only used by plugins, so we don't need the component testing
|
|
17
15
|
// options, cast to any to avoid type errors
|
|
18
16
|
return (0, cypress_preset_1.nxBaseCypressPreset)(pathToConfig);
|
|
19
17
|
}
|
|
18
|
+
(0, internal_3.assertPackageIsInstalled)('@nx/webpack', '@nx/next/plugins/component-testing');
|
|
19
|
+
const { composePluginsSync, withNx, } = require('@nx/webpack');
|
|
20
|
+
const { suppressWebpackComposeHelperWarnings, } = require('@nx/webpack/internal');
|
|
20
21
|
const graph = (0, devkit_1.readCachedProjectGraph)();
|
|
21
22
|
const { targets: ctTargets, name: ctProjectName } = (0, internal_1.getProjectConfigByPath)(graph, pathToConfig);
|
|
22
23
|
const ctTargetName = options?.ctTargetName || 'component-test';
|
|
@@ -39,7 +40,7 @@ function nxComponentTestingPreset(pathToConfig, options) {
|
|
|
39
40
|
cwd: process.cwd(),
|
|
40
41
|
root: devkit_1.workspaceRoot,
|
|
41
42
|
projectsConfigurations: (0, devkit_1.readProjectsConfigurationFromProjectGraph)(graph),
|
|
42
|
-
nxJsonConfiguration: (0,
|
|
43
|
+
nxJsonConfiguration: (0, internal_4.readNxJsonFromDisk)(devkit_1.workspaceRoot),
|
|
43
44
|
isVerbose: false,
|
|
44
45
|
projectName: ctProjectName,
|
|
45
46
|
projectGraph: graph,
|
|
@@ -83,8 +84,8 @@ Able to find CT project, ${!!ctProjectConfig}.`);
|
|
|
83
84
|
};
|
|
84
85
|
// Nx composes these helpers internally for the Cypress CT preset; suppress
|
|
85
86
|
// their deprecation warning so it fires only for user-authored configs.
|
|
86
|
-
const webpackConfig =
|
|
87
|
-
const configure =
|
|
87
|
+
const webpackConfig = suppressWebpackComposeHelperWarnings(() => (0, internal_3.suppressReactComposeHelperWarnings)(() => {
|
|
88
|
+
const configure = composePluginsSync(withNx({
|
|
88
89
|
target: 'web',
|
|
89
90
|
styles: [],
|
|
90
91
|
scripts: [],
|
package/dist/plugins/with-nx.js
CHANGED
|
@@ -103,7 +103,7 @@ function withNx(_nextConfig = {}, context = getWithNxContext()) {
|
|
|
103
103
|
if (!graph.dependencies[project])
|
|
104
104
|
return;
|
|
105
105
|
const { readTsConfigPaths } = require('@nx/js');
|
|
106
|
-
const { findAllProjectNodeDependencies, } = require('nx/
|
|
106
|
+
const { findAllProjectNodeDependencies, } = require('@nx/devkit/internal');
|
|
107
107
|
const paths = readTsConfigPaths();
|
|
108
108
|
const deps = findAllProjectNodeDependencies(project);
|
|
109
109
|
nextConfig.transpilePackages ??= [];
|
|
@@ -66,19 +66,15 @@ async function buildExecutor(options, context) {
|
|
|
66
66
|
start: 'next start',
|
|
67
67
|
};
|
|
68
68
|
(0, update_package_json_1.updatePackageJson)(builtPackageJson, context);
|
|
69
|
-
(0, devkit_1.
|
|
69
|
+
const packageManager = (0, devkit_1.detectPackageManager)(context.root);
|
|
70
70
|
if (options.generateLockfile) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const lockFile = (0, js_1.createLockFile)(builtPackageJson, context.projectGraph, packageManager);
|
|
77
|
-
(0, node_fs_1.writeFileSync)(`${options.outputPath}/${(0, js_1.getLockFileName)(packageManager)}`, lockFile, {
|
|
78
|
-
encoding: 'utf-8',
|
|
79
|
-
});
|
|
80
|
-
}
|
|
71
|
+
(0, js_1.generatePrunedDeployOutput)(builtPackageJson, context.projectGraph, projectRoot, {
|
|
72
|
+
outputDirectory: options.outputPath,
|
|
73
|
+
packageManager,
|
|
74
|
+
workspaceRoot: context.root,
|
|
75
|
+
});
|
|
81
76
|
}
|
|
77
|
+
(0, devkit_1.writeJsonFile)(`${options.outputPath}/package.json`, builtPackageJson);
|
|
82
78
|
// If output path is different from source path, then copy over the config and public files.
|
|
83
79
|
// This is the default behavior when running `nx build <app>`.
|
|
84
80
|
if (options.outputPath.replace(/\/$/, '') !== projectRoot) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ExecutorContext } from '@nx/devkit';
|
|
2
|
-
import type
|
|
2
|
+
import { type PackageJson } from '@nx/devkit/internal';
|
|
3
3
|
export declare function updatePackageJson(packageJson: PackageJson, context: ExecutorContext): void;
|
|
@@ -7,10 +7,10 @@ const devkit_1 = require("@nx/devkit");
|
|
|
7
7
|
const assert_supported_next_version_1 = require("../../utils/assert-supported-next-version");
|
|
8
8
|
const js_1 = require("@nx/js");
|
|
9
9
|
const internal_2 = require("@nx/react/internal");
|
|
10
|
-
const internal_3 = require("@nx/react/internal");
|
|
11
10
|
const normalize_options_1 = require("./lib/normalize-options");
|
|
12
11
|
const add_e2e_1 = require("./lib/add-e2e");
|
|
13
12
|
const add_jest_1 = require("./lib/add-jest");
|
|
13
|
+
const add_vitest_1 = require("./lib/add-vitest");
|
|
14
14
|
const add_project_1 = require("./lib/add-project");
|
|
15
15
|
const create_application_files_1 = require("./lib/create-application-files");
|
|
16
16
|
const set_defaults_1 = require("./lib/set-defaults");
|
|
@@ -20,7 +20,7 @@ const add_linting_1 = require("./lib/add-linting");
|
|
|
20
20
|
const custom_server_1 = require("../custom-server/custom-server");
|
|
21
21
|
const update_cypress_tsconfig_1 = require("./lib/update-cypress-tsconfig");
|
|
22
22
|
const versions_1 = require("../../utils/versions");
|
|
23
|
-
const
|
|
23
|
+
const internal_3 = require("@nx/js/internal");
|
|
24
24
|
const add_swc_to_custom_server_1 = require("../../utils/add-swc-to-custom-server");
|
|
25
25
|
const jest_config_util_1 = require("../../utils/jest-config-util");
|
|
26
26
|
async function applicationGenerator(host, schema) {
|
|
@@ -33,7 +33,7 @@ async function applicationGenerator(host, schema) {
|
|
|
33
33
|
async function applicationGeneratorInternal(host, schema) {
|
|
34
34
|
(0, assert_supported_next_version_1.assertSupportedNextVersion)(host);
|
|
35
35
|
const tasks = [];
|
|
36
|
-
const addTsPlugin = (0,
|
|
36
|
+
const addTsPlugin = (0, internal_3.shouldConfigureTsSolutionSetup)(host, schema.addPlugin, schema.useTsSolution);
|
|
37
37
|
const jsInitTask = await (0, js_1.initGenerator)(host, {
|
|
38
38
|
js: schema.js,
|
|
39
39
|
skipPackageJson: schema.skipPackageJson,
|
|
@@ -54,7 +54,7 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
54
54
|
// If we are using the new TS solution
|
|
55
55
|
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
|
56
56
|
if (options.isTsSolutionSetup) {
|
|
57
|
-
await (0,
|
|
57
|
+
await (0, internal_3.addProjectToTsSolutionWorkspace)(host, options.appProjectRoot);
|
|
58
58
|
}
|
|
59
59
|
const lintTask = await (0, add_linting_1.addLinting)(host, options);
|
|
60
60
|
tasks.push(lintTask);
|
|
@@ -62,6 +62,8 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
62
62
|
tasks.push(e2eTask);
|
|
63
63
|
const jestTask = await (0, add_jest_1.addJest)(host, options);
|
|
64
64
|
tasks.push(jestTask);
|
|
65
|
+
const vitestTask = await (0, add_vitest_1.addVitest)(host, options);
|
|
66
|
+
tasks.push(vitestTask);
|
|
65
67
|
const styledTask = (0, styles_1.addStyleDependencies)(host, {
|
|
66
68
|
style: options.style,
|
|
67
69
|
swc: !host.exists((0, devkit_1.joinPathFragments)(options.appProjectRoot, '.babelrc')),
|
|
@@ -81,7 +83,7 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
81
83
|
});
|
|
82
84
|
}
|
|
83
85
|
if (!options.skipPackageJson) {
|
|
84
|
-
const reactVersions = await (0,
|
|
86
|
+
const reactVersions = await (0, internal_2.getReactDependenciesVersionsToInstall)(host);
|
|
85
87
|
const devDependencies = {
|
|
86
88
|
'@types/react': reactVersions['@types/react'],
|
|
87
89
|
'@types/react-dom': reactVersions['@types/react-dom'],
|
|
@@ -92,14 +94,14 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
92
94
|
}
|
|
93
95
|
tasks.push((0, devkit_1.addDependenciesToPackageJson)(host, { tslib: versions_1.tsLibVersion }, devDependencies, undefined, true));
|
|
94
96
|
}
|
|
95
|
-
(0,
|
|
97
|
+
(0, internal_3.updateTsconfigFiles)(host, options.appProjectRoot, 'tsconfig.json', {
|
|
96
98
|
jsx: 'preserve',
|
|
97
99
|
module: 'esnext',
|
|
98
100
|
moduleResolution: 'bundler',
|
|
99
101
|
}, options.linter === 'eslint'
|
|
100
102
|
? ['.next', 'eslint.config.js', 'eslint.config.cjs', 'eslint.config.mjs']
|
|
101
103
|
: ['.next'], options.src ? 'src' : '.');
|
|
102
|
-
(0,
|
|
104
|
+
(0, internal_3.sortPackageJsonFields)(host, options.appProjectRoot);
|
|
103
105
|
if (!options.skipFormat) {
|
|
104
106
|
await (0, devkit_1.formatFiles)(host);
|
|
105
107
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* oxlint-disable jsx-a11y/prefer-tag-over-role -- the icons below
|
|
2
|
+
are inline SVGs, which have no tag to swap the role for. */
|
|
1
3
|
<%_ if (style !== 'none') { var wrapper = 'div'; _%>
|
|
2
4
|
import styles from './page.module.<%= style %>';
|
|
3
5
|
<% } else { var wrapper = 'div'; } %>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* oxlint-disable jsx-a11y/prefer-tag-over-role -- the icons below
|
|
2
|
+
are inline SVGs, which have no tag to swap the role for. */
|
|
1
3
|
<%_ if (style !== 'none') { var wrapper = 'div'; _%>
|
|
2
4
|
import styles from './<%= fileName %>.module.<%= style %>';
|
|
3
5
|
<% } else { var wrapper = 'div'; } %>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.addE2e = addE2e;
|
|
4
4
|
const internal_1 = require("@nx/devkit/internal");
|
|
5
|
+
const internal_2 = require("@nx/eslint/internal");
|
|
5
6
|
const devkit_1 = require("@nx/devkit");
|
|
6
7
|
const web_1 = require("@nx/web");
|
|
7
8
|
const versions_1 = require("../../../utils/versions");
|
|
@@ -46,13 +47,13 @@ async function addE2e(host, options) {
|
|
|
46
47
|
}
|
|
47
48
|
const e2eTask = await configurationGenerator(host, {
|
|
48
49
|
...options,
|
|
49
|
-
linter: 'eslint',
|
|
50
50
|
project: options.e2eProjectName,
|
|
51
51
|
directory: 'src',
|
|
52
52
|
skipFormat: true,
|
|
53
53
|
devServerTarget: e2eWebServerInfo.e2eDevServerTarget,
|
|
54
54
|
baseUrl: e2eWebServerInfo.e2eWebServerAddress,
|
|
55
55
|
jsx: true,
|
|
56
|
+
enableTypedLinting: (0, internal_2.isTypedLintingEnabled)(options),
|
|
56
57
|
webServerCommands: {
|
|
57
58
|
default: e2eWebServerInfo.e2eWebServerCommand,
|
|
58
59
|
},
|
|
@@ -94,7 +95,7 @@ async function addE2e(host, options) {
|
|
|
94
95
|
directory: 'src',
|
|
95
96
|
js: false,
|
|
96
97
|
linter: options.linter,
|
|
97
|
-
|
|
98
|
+
enableTypedLinting: (0, internal_2.isTypedLintingEnabled)(options),
|
|
98
99
|
webServerAddress: e2eWebServerInfo.e2eCiBaseUrl,
|
|
99
100
|
webServerCommand: e2eWebServerInfo.e2eWebServerCommand,
|
|
100
101
|
addPlugin: options.addPlugin,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.addJest = addJest;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const internal_1 = require("@nx/eslint/internal");
|
|
5
6
|
const versions_1 = require("../../../utils/versions");
|
|
6
7
|
async function addJest(host, options) {
|
|
7
8
|
if (options.unitTestRunner !== 'jest') {
|
|
@@ -14,7 +15,9 @@ async function addJest(host, options) {
|
|
|
14
15
|
supportTsx: true,
|
|
15
16
|
skipSerializers: true,
|
|
16
17
|
setupFile: 'none',
|
|
17
|
-
|
|
18
|
+
// The generated config is replaced by updateJestConfig, so this only decides
|
|
19
|
+
// which transformer package gets installed; 'tsc' installs none.
|
|
20
|
+
compiler: 'tsc',
|
|
18
21
|
skipFormat: true,
|
|
19
22
|
runtimeTsconfigFileName: 'tsconfig.json',
|
|
20
23
|
});
|
|
@@ -27,8 +30,8 @@ async function addJest(host, options) {
|
|
|
27
30
|
});
|
|
28
31
|
(0, devkit_1.updateJson)(host, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.spec.json'), (json) => {
|
|
29
32
|
json.compilerOptions.jsx = 'react';
|
|
30
|
-
//
|
|
31
|
-
if (
|
|
33
|
+
// Override exclude so typed linting doesn't fail on jest.config.ts and jest.config.cts.
|
|
34
|
+
if ((0, internal_1.isTypedLintingEnabled)(options)) {
|
|
32
35
|
const tsConfig = (0, devkit_1.readJson)(host, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.json'));
|
|
33
36
|
json.exclude = tsConfig.exclude.filter((e) => e !== 'jest.config.ts' && e !== 'jest.config.cts');
|
|
34
37
|
}
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.addLinting = addLinting;
|
|
4
|
-
const eslint_1 = require("@nx/eslint");
|
|
5
4
|
const devkit_1 = require("@nx/devkit");
|
|
6
5
|
const react_1 = require("@nx/react");
|
|
7
6
|
const internal_1 = require("@nx/eslint/internal");
|
|
8
7
|
const version_utils_1 = require("../../../utils/version-utils");
|
|
8
|
+
const internal_2 = require("@nx/js/internal");
|
|
9
9
|
async function addLinting(host, options) {
|
|
10
|
-
if (options.linter !== 'eslint')
|
|
11
|
-
return () => { };
|
|
12
10
|
const tasks = [];
|
|
13
|
-
tasks.push(await (0,
|
|
11
|
+
tasks.push(await (0, internal_2.addLintingToProject)(host, {
|
|
12
|
+
oxlintPlugins: ['nextjs', 'react', 'react-perf', 'jsx-a11y'],
|
|
14
13
|
linter: options.linter,
|
|
15
14
|
project: options.projectName,
|
|
16
15
|
tsConfigPaths: [
|
|
17
16
|
(0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.app.json'),
|
|
18
17
|
],
|
|
19
18
|
unitTestRunner: options.unitTestRunner,
|
|
20
|
-
skipFormat: true,
|
|
21
19
|
rootProject: options.rootProject,
|
|
22
|
-
|
|
20
|
+
enableTypedLinting: (0, internal_1.isTypedLintingEnabled)(options),
|
|
23
21
|
addPlugin: options.addPlugin,
|
|
22
|
+
skipPackageJson: options.skipPackageJson,
|
|
24
23
|
}));
|
|
24
|
+
// Everything below configures ESLint — predefined configs, `extends`, ignore
|
|
25
|
+
// entries — which have no equivalent in other linters.
|
|
25
26
|
if (options.linter === 'eslint' && (0, internal_1.isEslintConfigSupported)(host)) {
|
|
26
27
|
if ((0, internal_1.useFlatConfig)(host)) {
|
|
27
28
|
(0, internal_1.addPredefinedConfigToFlatLintConfig)(host, options.appProjectRoot, 'flat/react-typescript', { checkBaseConfig: true });
|
|
@@ -67,7 +68,7 @@ async function addLinting(host, options) {
|
|
|
67
68
|
...(options.isTsSolutionSetup ? ['**/out-tsc'] : []),
|
|
68
69
|
]);
|
|
69
70
|
}
|
|
70
|
-
if (!options.skipPackageJson) {
|
|
71
|
+
if (options.linter === 'eslint' && !options.skipPackageJson) {
|
|
71
72
|
const eslintConfigNextVersion = await (0, version_utils_1.getEslintConfigNextDependenciesVersionsToInstall)(host);
|
|
72
73
|
tasks.push((0, devkit_1.addDependenciesToPackageJson)(host, react_1.extraEslintDependencies.dependencies, {
|
|
73
74
|
...react_1.extraEslintDependencies.devDependencies,
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addVitest = addVitest;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const js_1 = require("@nx/js");
|
|
6
|
+
const internal_1 = require("@nx/js/internal");
|
|
7
|
+
const versions_1 = require("../../../utils/versions");
|
|
8
|
+
async function addVitest(host, options) {
|
|
9
|
+
if (options.unitTestRunner !== 'vitest') {
|
|
10
|
+
return () => { };
|
|
11
|
+
}
|
|
12
|
+
(0, devkit_1.ensurePackage)('@nx/vitest', versions_1.nxVersion);
|
|
13
|
+
// CommonJS `require` instead of dynamic ESM `import`: `ensurePackage` exposes
|
|
14
|
+
// the temp install via `Module._initPaths`, which ESM ignores.
|
|
15
|
+
const { configurationGenerator, } = require('@nx/vitest/generators');
|
|
16
|
+
const { createOrEditViteConfig, } = require('@nx/vitest/internal');
|
|
17
|
+
const vitestTask = await configurationGenerator(host, {
|
|
18
|
+
project: options.projectName,
|
|
19
|
+
uiFramework: 'react',
|
|
20
|
+
coverageProvider: 'v8',
|
|
21
|
+
testEnvironment: 'jsdom',
|
|
22
|
+
runtimeTsconfigFileName: 'tsconfig.json',
|
|
23
|
+
// Next.js builds with its own toolchain, so the project has no vite config
|
|
24
|
+
// to extend. Write a standalone vitest config below instead.
|
|
25
|
+
skipViteConfig: true,
|
|
26
|
+
addPlugin: options.addPlugin,
|
|
27
|
+
skipPackageJson: options.skipPackageJson,
|
|
28
|
+
skipFormat: true,
|
|
29
|
+
});
|
|
30
|
+
// Vitest cannot resolve the `@/*` alias (or workspace-root aliases in
|
|
31
|
+
// non-TS-solution setups) that Next resolves itself at build time, so mirror
|
|
32
|
+
// the tsconfig `paths` as explicit aliases.
|
|
33
|
+
const tsConfigJson = (0, devkit_1.readJson)(host, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.json'));
|
|
34
|
+
const resolveAlias = {};
|
|
35
|
+
const collectAliases = (paths, prefix) => {
|
|
36
|
+
for (const [key, targets] of Object.entries(paths ?? {})) {
|
|
37
|
+
if (!targets?.[0]) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (key.endsWith('/*') && targets[0].endsWith('/*')) {
|
|
41
|
+
resolveAlias[key.slice(0, -2)] = prefix + targets[0].slice(0, -2);
|
|
42
|
+
}
|
|
43
|
+
else if (!key.includes('*')) {
|
|
44
|
+
resolveAlias[key] = prefix + targets[0];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
collectAliases(tsConfigJson?.compilerOptions?.paths, '');
|
|
49
|
+
if (!(0, internal_1.isUsingTsSolutionSetup)(host)) {
|
|
50
|
+
const rootTsConfigPath = (0, js_1.getRootTsConfigPathInTree)(host);
|
|
51
|
+
if (rootTsConfigPath && host.exists(rootTsConfigPath)) {
|
|
52
|
+
const rootTsConfig = (0, devkit_1.readJson)(host, rootTsConfigPath);
|
|
53
|
+
// Path mappings resolve relative to `baseUrl` when the root tsconfig
|
|
54
|
+
// sets one.
|
|
55
|
+
const baseUrl = rootTsConfig?.compilerOptions?.baseUrl ?? '.';
|
|
56
|
+
collectAliases(rootTsConfig?.compilerOptions?.paths, (0, devkit_1.joinPathFragments)((0, devkit_1.offsetFromRoot)(options.appProjectRoot), baseUrl) + '/');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
createOrEditViteConfig(host, {
|
|
60
|
+
project: options.projectName,
|
|
61
|
+
includeLib: false,
|
|
62
|
+
includeVitest: true,
|
|
63
|
+
testEnvironment: 'jsdom',
|
|
64
|
+
// The generated spec lives in `specs/`; colocated specs may sit under
|
|
65
|
+
// `src/`, or under root `app/`/`pages/` when `--no-src` is used.
|
|
66
|
+
testInclude: [
|
|
67
|
+
'{src,app,pages,specs}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
|
|
68
|
+
],
|
|
69
|
+
imports: [`import react from '@vitejs/plugin-react'`],
|
|
70
|
+
plugins: ['react()'],
|
|
71
|
+
resolveAlias,
|
|
72
|
+
useEsmExtension: true,
|
|
73
|
+
}, true, {
|
|
74
|
+
vitestFileName: true,
|
|
75
|
+
skipPackageJson: options.skipPackageJson,
|
|
76
|
+
skipNxPlugins: true,
|
|
77
|
+
});
|
|
78
|
+
// The generated specs live in `specs/`, which only tsconfig.json covers, so
|
|
79
|
+
// it needs the test types (vitest globals, node) from tsconfig.spec.json.
|
|
80
|
+
const tsConfigSpecJson = (0, devkit_1.readJson)(host, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.spec.json'));
|
|
81
|
+
(0, devkit_1.updateJson)(host, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.json'), (json) => {
|
|
82
|
+
json.compilerOptions ??= {};
|
|
83
|
+
json.compilerOptions.types ??= [];
|
|
84
|
+
json.compilerOptions.types.push(...(tsConfigSpecJson?.compilerOptions?.types ?? []));
|
|
85
|
+
return json;
|
|
86
|
+
});
|
|
87
|
+
// tsconfig.spec.json extends tsconfig.base.json in TS solution setups, so
|
|
88
|
+
// specs would not see the app's `@/*` alias without copying it over. Its
|
|
89
|
+
// include also only covers `src/`, so add the `specs/` layout.
|
|
90
|
+
(0, devkit_1.updateJson)(host, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.spec.json'), (json) => {
|
|
91
|
+
if (tsConfigJson?.compilerOptions?.paths) {
|
|
92
|
+
json.compilerOptions ??= {};
|
|
93
|
+
json.compilerOptions.paths = {
|
|
94
|
+
...tsConfigJson.compilerOptions.paths,
|
|
95
|
+
...json.compilerOptions.paths,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (options.js) {
|
|
99
|
+
json.compilerOptions ??= {};
|
|
100
|
+
json.compilerOptions.allowJs = true;
|
|
101
|
+
}
|
|
102
|
+
json.include = [
|
|
103
|
+
...(json.include ?? []),
|
|
104
|
+
'specs/**/*.test.ts',
|
|
105
|
+
'specs/**/*.spec.ts',
|
|
106
|
+
'specs/**/*.test.tsx',
|
|
107
|
+
'specs/**/*.spec.tsx',
|
|
108
|
+
'specs/**/*.test.js',
|
|
109
|
+
'specs/**/*.spec.js',
|
|
110
|
+
'specs/**/*.test.jsx',
|
|
111
|
+
'specs/**/*.spec.jsx',
|
|
112
|
+
];
|
|
113
|
+
return json;
|
|
114
|
+
});
|
|
115
|
+
return vitestTask;
|
|
116
|
+
}
|
|
@@ -39,7 +39,7 @@ async function normalizeOptions(host, options) {
|
|
|
39
39
|
e2eProjectRoot,
|
|
40
40
|
e2eTestRunner: options.e2eTestRunner || 'playwright',
|
|
41
41
|
fileName,
|
|
42
|
-
linter: options.linter
|
|
42
|
+
linter: await (0, internal_2.normalizeLinterOption)(host, options.linter),
|
|
43
43
|
outputPath,
|
|
44
44
|
parsedTags,
|
|
45
45
|
projectName: appProjectName,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LinterType } from '@nx/js';
|
|
2
2
|
import type { SupportedStyles } from '@nx/react';
|
|
3
3
|
|
|
4
4
|
export interface Schema {
|
|
@@ -7,10 +7,14 @@ export interface Schema {
|
|
|
7
7
|
style?: SupportedStyles;
|
|
8
8
|
skipFormat?: boolean;
|
|
9
9
|
tags?: string;
|
|
10
|
-
unitTestRunner?: 'jest' | 'none';
|
|
10
|
+
unitTestRunner?: 'jest' | 'vitest' | 'none';
|
|
11
11
|
e2eTestRunner?: 'cypress' | 'playwright' | 'none';
|
|
12
|
-
linter?:
|
|
12
|
+
linter?: LinterType;
|
|
13
13
|
js?: boolean;
|
|
14
|
+
enableTypedLinting?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use `enableTypedLinting` instead. This option will be removed in Nx v24.
|
|
17
|
+
*/
|
|
14
18
|
setParserOptionsProject?: boolean;
|
|
15
19
|
swc?: boolean;
|
|
16
20
|
customServer?: boolean;
|
|
@@ -21,6 +25,6 @@ export interface Schema {
|
|
|
21
25
|
rootProject?: boolean;
|
|
22
26
|
addPlugin?: boolean;
|
|
23
27
|
useTsSolution?: boolean;
|
|
24
|
-
formatter?: 'prettier' | 'none';
|
|
28
|
+
formatter?: 'prettier' | 'oxfmt' | 'none';
|
|
25
29
|
useProjectJson?: boolean;
|
|
26
30
|
}
|
|
@@ -48,13 +48,16 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"linter": {
|
|
51
|
-
"description": "The tool to use for running lint checks.",
|
|
51
|
+
"description": "The tool to use for running lint checks. Defaults to the linter the workspace already uses.",
|
|
52
52
|
"type": "string",
|
|
53
|
-
"enum": ["eslint", "none"],
|
|
54
|
-
"default": "none",
|
|
55
|
-
"x-prompt": "Which linter would you like to use?",
|
|
53
|
+
"enum": ["eslint", "oxlint", "none"],
|
|
56
54
|
"x-priority": "important"
|
|
57
55
|
},
|
|
56
|
+
"formatter": {
|
|
57
|
+
"description": "The tool to use for code formatting.",
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": ["none", "prettier", "oxfmt"]
|
|
60
|
+
},
|
|
58
61
|
"skipFormat": {
|
|
59
62
|
"description": "Skip formatting files.",
|
|
60
63
|
"type": "boolean",
|
|
@@ -63,7 +66,7 @@
|
|
|
63
66
|
},
|
|
64
67
|
"unitTestRunner": {
|
|
65
68
|
"type": "string",
|
|
66
|
-
"enum": ["jest", "none"],
|
|
69
|
+
"enum": ["vitest", "jest", "none"],
|
|
67
70
|
"description": "Test runner to use for unit tests.",
|
|
68
71
|
"default": "none",
|
|
69
72
|
"x-prompt": "What unit test runner should be used?",
|
|
@@ -86,11 +89,17 @@
|
|
|
86
89
|
"description": "Generate JavaScript files rather than TypeScript files.",
|
|
87
90
|
"default": false
|
|
88
91
|
},
|
|
89
|
-
"
|
|
92
|
+
"enableTypedLinting": {
|
|
90
93
|
"type": "boolean",
|
|
91
|
-
"description": "Whether
|
|
94
|
+
"description": "Whether to enable typed linting. For flat configs, this configures the recommended `parserOptions.projectService` and `tsconfigRootDir`. For legacy `.eslintrc` configs, this configures `parserOptions.project`. We do not enable this by default for lint performance reasons.",
|
|
92
95
|
"default": false
|
|
93
96
|
},
|
|
97
|
+
"setParserOptionsProject": {
|
|
98
|
+
"type": "boolean",
|
|
99
|
+
"description": "Deprecated alias for `enableTypedLinting`.",
|
|
100
|
+
"default": false,
|
|
101
|
+
"x-deprecated": "Use `enableTypedLinting` instead. This option will be removed in Nx v24."
|
|
102
|
+
},
|
|
94
103
|
"swc": {
|
|
95
104
|
"description": "Enable the Rust-based compiler SWC to compile JS/TS files.",
|
|
96
105
|
"type": "boolean",
|
|
@@ -3,21 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.customServerGenerator = customServerGenerator;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const internal_1 = require("@nx/devkit/internal");
|
|
6
|
-
const devkit_2 = require("@nx/devkit");
|
|
7
6
|
const path_1 = require("path");
|
|
8
7
|
const add_swc_to_custom_server_1 = require("../../utils/add-swc-to-custom-server");
|
|
9
8
|
const internal_2 = require("@nx/js/internal");
|
|
10
9
|
const assert_supported_next_version_1 = require("../../utils/assert-supported-next-version");
|
|
11
10
|
async function customServerGenerator(host, options) {
|
|
12
11
|
(0, assert_supported_next_version_1.assertSupportedNextVersion)(host);
|
|
13
|
-
const project = (0,
|
|
12
|
+
const project = (0, devkit_1.readProjectConfiguration)(host, options.project);
|
|
14
13
|
const swcServerName = '.server.swcrc';
|
|
15
|
-
const nxJson = (0,
|
|
14
|
+
const nxJson = (0, devkit_1.readNxJson)(host);
|
|
16
15
|
const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
|
|
17
16
|
? p === '@nx/next/plugin'
|
|
18
17
|
: p.plugin === '@nx/next/plugin');
|
|
19
18
|
if (project.targets?.build?.executor !== '@nx/next:build' && !hasPlugin) {
|
|
20
|
-
|
|
19
|
+
devkit_1.logger.error(`Project ${options.project} is not a Next.js project. Did you generate it with "nx g @nx/next:app"?`);
|
|
21
20
|
return;
|
|
22
21
|
}
|
|
23
22
|
// In Nx 18 next artifacts are inside the project root .next/ & dist/ (for custom server)
|
|
@@ -28,22 +27,22 @@ async function customServerGenerator(host, options) {
|
|
|
28
27
|
!project.targets?.build?.configurations?.development ||
|
|
29
28
|
!project.targets?.build?.configurations?.production) &&
|
|
30
29
|
!hasPlugin) {
|
|
31
|
-
|
|
30
|
+
devkit_1.logger.error(`Project ${options.project} has invalid config. Did you generate it with "nx g @nx/next:app"?`);
|
|
32
31
|
return;
|
|
33
32
|
}
|
|
34
33
|
if (project.targets?.['build-custom-server'] ||
|
|
35
34
|
project.targets?.['serve-custom-server']) {
|
|
36
|
-
|
|
35
|
+
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
36
|
return;
|
|
38
37
|
}
|
|
39
38
|
// In Nx 18 next artifacts are inside the project root .next/ & dist/ (for custom server)
|
|
40
39
|
// So we need ensure the mapping is correct from dist to the project root
|
|
41
40
|
const projectPathFromDist = hasPlugin
|
|
42
|
-
? `../../${(0,
|
|
43
|
-
: `${(0,
|
|
44
|
-
const offset = (0,
|
|
41
|
+
? `../../${(0, devkit_1.offsetFromRoot)(project.root)}${project.root}`
|
|
42
|
+
: `${(0, devkit_1.offsetFromRoot)(`dist/${project.root}`)}${project.root}`;
|
|
43
|
+
const offset = (0, devkit_1.offsetFromRoot)(project.root);
|
|
45
44
|
const isTsSolution = (0, internal_2.isUsingTsSolutionSetup)(host);
|
|
46
|
-
(0,
|
|
45
|
+
(0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, 'files'), project.root, {
|
|
47
46
|
...options,
|
|
48
47
|
hasPlugin,
|
|
49
48
|
projectPathFromDist,
|
|
@@ -98,23 +97,23 @@ async function customServerGenerator(host, options) {
|
|
|
98
97
|
},
|
|
99
98
|
},
|
|
100
99
|
};
|
|
101
|
-
(0,
|
|
102
|
-
(0,
|
|
100
|
+
(0, devkit_1.updateProjectConfiguration)(host, options.project, project);
|
|
101
|
+
(0, devkit_1.updateJson)(host, 'nx.json', (json) => {
|
|
103
102
|
if (!json.tasksRunnerOptions?.default?.options?.cacheableOperations?.includes('build-custom-server') &&
|
|
104
103
|
json.tasksRunnerOptions?.default?.options?.cacheableOperations) {
|
|
105
104
|
json.tasksRunnerOptions.default.options.cacheableOperations.push('build-custom-server');
|
|
106
105
|
}
|
|
107
106
|
return json;
|
|
108
107
|
});
|
|
109
|
-
const updatedNxJson = (0,
|
|
108
|
+
const updatedNxJson = (0, devkit_1.readNxJson)(host) ?? {};
|
|
110
109
|
(0, internal_1.upsertTargetDefault)(host, updatedNxJson, {
|
|
111
110
|
target: 'build-custom-server',
|
|
112
111
|
cache: true,
|
|
113
112
|
});
|
|
114
|
-
(0,
|
|
113
|
+
(0, devkit_1.updateNxJson)(host, updatedNxJson);
|
|
115
114
|
if (options.compiler === 'swc') {
|
|
116
115
|
// Update app swc to exlude server files
|
|
117
|
-
(0,
|
|
116
|
+
(0, devkit_1.updateJson)(host, (0, path_1.join)(project.root, '.swcrc'), (json) => {
|
|
118
117
|
json.exclude = [...(json.exclude ?? []), 'server/**'];
|
|
119
118
|
return json;
|
|
120
119
|
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Tree } from '@nx/devkit';
|
|
2
2
|
import { Schema } from '../schema';
|
|
3
|
+
import type { LinterType } from '@nx/js';
|
|
3
4
|
export interface NormalizedSchema extends Schema {
|
|
5
|
+
linter: LinterType;
|
|
4
6
|
importPath: string;
|
|
5
7
|
projectRoot: string;
|
|
6
8
|
isUsingTsSolutionConfig: boolean;
|
|
@@ -19,6 +19,9 @@ async function normalizeOptions(host, options) {
|
|
|
19
19
|
const isUsingTsSolutionConfig = (0, internal_2.isUsingTsSolutionSetup)(host);
|
|
20
20
|
return {
|
|
21
21
|
...options,
|
|
22
|
+
// Resolved after the spread: the framework's ESLint shaping is guarded on
|
|
23
|
+
// `=== 'eslint'`, and an unresolved `undefined` would skip all of it.
|
|
24
|
+
linter: await (0, internal_2.normalizeLinterOption)(host, options.linter),
|
|
22
25
|
importPath,
|
|
23
26
|
projectRoot,
|
|
24
27
|
isUsingTsSolutionConfig,
|
|
@@ -43,10 +43,6 @@ async function libraryGeneratorInternal(host, rawOptions) {
|
|
|
43
43
|
tasks.push(libTask);
|
|
44
44
|
if (!options.skipPackageJson) {
|
|
45
45
|
const devDependencies = {};
|
|
46
|
-
if (options.linter === 'eslint') {
|
|
47
|
-
devDependencies['eslint-config-next'] = versions_1.eslintConfigNextVersion;
|
|
48
|
-
devDependencies['@next/eslint-plugin-next'] = versions_1.eslintConfigNextVersion;
|
|
49
|
-
}
|
|
50
46
|
if (options.unitTestRunner && options.unitTestRunner !== 'none') {
|
|
51
47
|
devDependencies['@testing-library/react'] = internal_1.testingLibraryReactVersion;
|
|
52
48
|
devDependencies['@testing-library/dom'] = internal_1.testingLibraryDomVersion;
|
|
@@ -71,6 +67,27 @@ export async function HelloServer() {
|
|
|
71
67
|
if (!options.skipTsConfig && !isTsSolutionSetup) {
|
|
72
68
|
(0, js_1.addTsConfigPath)(host, `${options.importPath}/server`, [serverEntryPath]);
|
|
73
69
|
}
|
|
70
|
+
const isBuildable = (options.bundler && options.bundler !== 'none') ||
|
|
71
|
+
options.buildable ||
|
|
72
|
+
options.publishable;
|
|
73
|
+
if (isTsSolutionSetup && !isBuildable) {
|
|
74
|
+
// Non-buildable libs resolve `.` straight to source, so `./server` does the same.
|
|
75
|
+
const packageJsonPath = (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json');
|
|
76
|
+
if (host.exists(packageJsonPath)) {
|
|
77
|
+
(0, devkit_1.updateJson)(host, packageJsonPath, (json) => {
|
|
78
|
+
json.exports ??= {};
|
|
79
|
+
const serverSource = `./src/server.${options.js ? 'js' : 'ts'}`;
|
|
80
|
+
json.exports['./server'] = options.js
|
|
81
|
+
? serverSource
|
|
82
|
+
: {
|
|
83
|
+
types: serverSource,
|
|
84
|
+
import: serverSource,
|
|
85
|
+
default: serverSource,
|
|
86
|
+
};
|
|
87
|
+
return json;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
74
91
|
// Configure Vite and package.json for server entry point when using Vite bundler
|
|
75
92
|
if (options.bundler === 'vite') {
|
|
76
93
|
// Update vite.config.mts to support multiple entry points
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LinterType } from '@nx/js';
|
|
2
2
|
import type { SupportedStyles } from '@nx/react';
|
|
3
3
|
|
|
4
4
|
export interface Schema {
|
|
@@ -11,7 +11,7 @@ export interface Schema {
|
|
|
11
11
|
routing?: boolean;
|
|
12
12
|
appProject?: string;
|
|
13
13
|
unitTestRunner: 'jest' | 'vitest' | 'none';
|
|
14
|
-
linter
|
|
14
|
+
linter?: LinterType;
|
|
15
15
|
component?: boolean;
|
|
16
16
|
publishable?: boolean;
|
|
17
17
|
/** @deprecated Use bundler instead. */
|
|
@@ -21,6 +21,10 @@ export interface Schema {
|
|
|
21
21
|
js?: boolean;
|
|
22
22
|
globalCss?: boolean;
|
|
23
23
|
strict?: boolean;
|
|
24
|
+
enableTypedLinting?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* @deprecated Use `enableTypedLinting` instead. This option will be removed in Nx v24.
|
|
27
|
+
*/
|
|
24
28
|
setParserOptionsProject?: boolean;
|
|
25
29
|
skipPackageJson?: boolean;
|
|
26
30
|
addPlugin?: boolean;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/schema",
|
|
3
3
|
"cli": "nx",
|
|
4
|
-
"$id": "
|
|
5
|
-
"title": "Create a
|
|
6
|
-
"description": "Create a
|
|
4
|
+
"$id": "NxNextLibrary",
|
|
5
|
+
"title": "Create a Next.js Library for Nx",
|
|
6
|
+
"description": "Create a Next.js library for an Nx workspace. Same output as `@nx/react:library`, plus a `server` entry point for React Server Components and the Next.js type declarations.",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
9
|
"directory": {
|
|
@@ -56,11 +56,9 @@
|
|
|
56
56
|
"x-priority": "important"
|
|
57
57
|
},
|
|
58
58
|
"linter": {
|
|
59
|
-
"description": "The tool to use for running lint checks.",
|
|
59
|
+
"description": "The tool to use for running lint checks. Defaults to the linter the workspace already uses.",
|
|
60
60
|
"type": "string",
|
|
61
|
-
"enum": ["eslint", "none"],
|
|
62
|
-
"default": "none",
|
|
63
|
-
"x-prompt": "Which linter would you like to use?",
|
|
61
|
+
"enum": ["eslint", "oxlint", "none"],
|
|
64
62
|
"x-priority": "important"
|
|
65
63
|
},
|
|
66
64
|
"unitTestRunner": {
|
|
@@ -129,11 +127,17 @@
|
|
|
129
127
|
"description": "Whether to enable tsconfig strict mode or not.",
|
|
130
128
|
"default": true
|
|
131
129
|
},
|
|
132
|
-
"
|
|
130
|
+
"enableTypedLinting": {
|
|
133
131
|
"type": "boolean",
|
|
134
|
-
"description": "Whether
|
|
132
|
+
"description": "Whether to enable typed linting. For flat configs, this configures the recommended `parserOptions.projectService` and `tsconfigRootDir`. For legacy `.eslintrc` configs, this configures `parserOptions.project`. We do not enable this by default for lint performance reasons.",
|
|
135
133
|
"default": false
|
|
136
134
|
},
|
|
135
|
+
"setParserOptionsProject": {
|
|
136
|
+
"type": "boolean",
|
|
137
|
+
"description": "Deprecated alias for `enableTypedLinting`.",
|
|
138
|
+
"default": false,
|
|
139
|
+
"x-deprecated": "Use `enableTypedLinting` instead. This option will be removed in Nx v24."
|
|
140
|
+
},
|
|
137
141
|
"skipPackageJson": {
|
|
138
142
|
"type": "boolean",
|
|
139
143
|
"default": false,
|
|
@@ -310,17 +310,13 @@ Turbopack is now the default bundler for development.
|
|
|
310
310
|
// BEFORE (Next.js 15)
|
|
311
311
|
const nextConfig = {
|
|
312
312
|
experimental: {
|
|
313
|
-
turbopack: {
|
|
314
|
-
/* options */
|
|
315
|
-
},
|
|
313
|
+
turbopack: {/* options */},
|
|
316
314
|
},
|
|
317
315
|
};
|
|
318
316
|
|
|
319
317
|
// AFTER (Next.js 16)
|
|
320
318
|
const nextConfig = {
|
|
321
|
-
turbopack: {
|
|
322
|
-
/* options */
|
|
323
|
-
},
|
|
319
|
+
turbopack: {/* options */},
|
|
324
320
|
};
|
|
325
321
|
```
|
|
326
322
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = addSvgrWebpackIfUsed;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const versions_1 = require("../../utils/versions");
|
|
6
|
+
// The Nx 22 `add-svgr-to-next-config` migration inlined a `withSvgr` helper
|
|
7
|
+
// that resolves `@svgr/webpack` into user next configs, but never added the
|
|
8
|
+
// package to the workspace - it only resolved transitively through `@nx/next`.
|
|
9
|
+
// Now that `@nx/next` no longer depends on it, backfill it where a next config
|
|
10
|
+
// actually references it.
|
|
11
|
+
const nextConfigFileNames = [
|
|
12
|
+
'next.config.js',
|
|
13
|
+
'next.config.cjs',
|
|
14
|
+
'next.config.mjs',
|
|
15
|
+
'next.config.ts',
|
|
16
|
+
];
|
|
17
|
+
async function addSvgrWebpackIfUsed(tree) {
|
|
18
|
+
let needsSvgr = false;
|
|
19
|
+
for (const [, project] of (0, devkit_1.getProjects)(tree)) {
|
|
20
|
+
for (const fileName of nextConfigFileNames) {
|
|
21
|
+
const path = (0, devkit_1.joinPathFragments)(project.root, fileName);
|
|
22
|
+
needsSvgr ||=
|
|
23
|
+
tree.exists(path) && tree.read(path, 'utf-8').includes('@svgr/webpack');
|
|
24
|
+
}
|
|
25
|
+
if (needsSvgr) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (!needsSvgr) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@svgr/webpack': versions_1.svgrWebpackVersion }, undefined, true);
|
|
33
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#### Add `@svgr/webpack` If Used
|
|
2
|
+
|
|
3
|
+
Adds `@svgr/webpack` to the workspace when a next config references it.
|
|
4
|
+
|
|
5
|
+
`@svgr/webpack` is no longer a dependency of `@nx/next`, so workspaces whose next configs resolve it - which is what the Nx 22 `add-svgr-to-next-config` migration inlined - must declare it themselves. This migration backfills it for those workspaces. Workspaces that already have `@svgr/webpack` are left untouched.
|
|
6
|
+
|
|
7
|
+
#### Examples
|
|
8
|
+
|
|
9
|
+
##### Before
|
|
10
|
+
|
|
11
|
+
```jsonc title="package.json"
|
|
12
|
+
{
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@nx/next": "23.1.0",
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
##### After
|
|
20
|
+
|
|
21
|
+
```jsonc title="package.json"
|
|
22
|
+
{
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@nx/next": "23.1.0",
|
|
25
|
+
"@svgr/webpack": "^8.0.1",
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
```
|
|
@@ -6,8 +6,6 @@ const devkit_1 = require("@nx/devkit");
|
|
|
6
6
|
const js_1 = require("@nx/js");
|
|
7
7
|
const internal_2 = require("@nx/js/internal");
|
|
8
8
|
const fs_1 = require("fs");
|
|
9
|
-
const devkit_internals_1 = require("nx/src/devkit-internals");
|
|
10
|
-
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
11
9
|
const path_1 = require("path");
|
|
12
10
|
const nextConfigBlob = '**/next.config.{ts,js,cjs,mjs}';
|
|
13
11
|
/**
|
|
@@ -20,8 +18,8 @@ exports.createDependencies = createDependencies;
|
|
|
20
18
|
exports.createNodes = [
|
|
21
19
|
nextConfigBlob,
|
|
22
20
|
async (configFiles, options, context) => {
|
|
23
|
-
const optionsHash = (0,
|
|
24
|
-
const cachePath = (0, path_1.join)(
|
|
21
|
+
const optionsHash = (0, internal_1.hashObject)(options);
|
|
22
|
+
const cachePath = (0, path_1.join)(internal_1.workspaceDataDirectory, `next-${optionsHash}.json`);
|
|
25
23
|
const targetsCache = new internal_1.PluginCache(cachePath);
|
|
26
24
|
const isTsSolutionSetup = (0, internal_2.isUsingTsSolutionSetup)();
|
|
27
25
|
const packageManager = (0, devkit_1.detectPackageManager)(context.workspaceRoot);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Tree } from 'nx/
|
|
1
|
+
import { Tree } from '@nx/devkit';
|
|
2
2
|
export declare function addGitIgnoreEntry(host: Tree): void;
|
|
@@ -2,24 +2,24 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createCopyPlugin = createCopyPlugin;
|
|
4
4
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
5
|
-
const path_1 = require("
|
|
6
|
-
const path_2 = require("path");
|
|
5
|
+
const path_1 = require("path");
|
|
7
6
|
const fs_1 = require("fs");
|
|
7
|
+
const devkit_1 = require("@nx/devkit");
|
|
8
8
|
function normalizeAssets(assets, root, sourceRoot) {
|
|
9
9
|
return assets.map((asset) => {
|
|
10
10
|
if (typeof asset === 'string') {
|
|
11
|
-
const assetPath = (0,
|
|
12
|
-
const resolvedAssetPath = (0,
|
|
13
|
-
const resolvedSourceRoot = (0,
|
|
11
|
+
const assetPath = (0, devkit_1.normalizePath)(asset);
|
|
12
|
+
const resolvedAssetPath = (0, path_1.resolve)(root, assetPath);
|
|
13
|
+
const resolvedSourceRoot = (0, path_1.resolve)(root, sourceRoot);
|
|
14
14
|
if (!resolvedAssetPath.startsWith(resolvedSourceRoot)) {
|
|
15
15
|
throw new Error(`The ${resolvedAssetPath} asset path must start with the project source root: ${sourceRoot}`);
|
|
16
16
|
}
|
|
17
17
|
const isDirectory = (0, fs_1.statSync)(resolvedAssetPath).isDirectory();
|
|
18
18
|
const input = isDirectory
|
|
19
19
|
? resolvedAssetPath
|
|
20
|
-
: (0,
|
|
21
|
-
const output = (0,
|
|
22
|
-
const glob = isDirectory ? '**/*' : (0,
|
|
20
|
+
: (0, path_1.dirname)(resolvedAssetPath);
|
|
21
|
+
const output = (0, path_1.relative)(resolvedSourceRoot, (0, path_1.resolve)(root, input));
|
|
22
|
+
const glob = isDirectory ? '**/*' : (0, path_1.basename)(resolvedAssetPath);
|
|
23
23
|
return {
|
|
24
24
|
input,
|
|
25
25
|
output,
|
|
@@ -30,8 +30,8 @@ function normalizeAssets(assets, root, sourceRoot) {
|
|
|
30
30
|
if (asset.output.startsWith('..')) {
|
|
31
31
|
throw new Error('An asset cannot be written to a location outside of the output path.');
|
|
32
32
|
}
|
|
33
|
-
const assetPath = (0,
|
|
34
|
-
const resolvedAssetPath = (0,
|
|
33
|
+
const assetPath = (0, devkit_1.normalizePath)(asset.input);
|
|
34
|
+
const resolvedAssetPath = (0, path_1.resolve)(root, assetPath);
|
|
35
35
|
return {
|
|
36
36
|
...asset,
|
|
37
37
|
input: resolvedAssetPath,
|
|
@@ -46,7 +46,7 @@ function createCopyPlugin(assets, root, sourceRoot) {
|
|
|
46
46
|
patterns: normalizeAssets(assets, root, sourceRoot).map((asset) => {
|
|
47
47
|
return {
|
|
48
48
|
context: asset.input,
|
|
49
|
-
to: (0,
|
|
49
|
+
to: (0, path_1.join)('../public', asset.output),
|
|
50
50
|
from: asset.glob,
|
|
51
51
|
globOptions: {
|
|
52
52
|
ignore: [
|
|
@@ -10,3 +10,4 @@ export declare const eslintConfigNext14Version = "^15.5.18";
|
|
|
10
10
|
export declare const eslintConfigNextVersion = "^16.1.6";
|
|
11
11
|
export declare const sassVersion = "1.97.2";
|
|
12
12
|
export declare const tsLibVersion = "^2.3.0";
|
|
13
|
+
export declare const svgrWebpackVersion = "^8.0.1";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.tsLibVersion = exports.sassVersion = exports.eslintConfigNextVersion = exports.eslintConfigNext14Version = exports.eslintConfigNext15Version = exports.eslintConfigNext16Version = exports.nextVersion = exports.next14Version = exports.next15Version = exports.next16Version = exports.minSupportedNextVersion = exports.nxVersion = void 0;
|
|
3
|
+
exports.svgrWebpackVersion = exports.tsLibVersion = exports.sassVersion = exports.eslintConfigNextVersion = exports.eslintConfigNext14Version = exports.eslintConfigNext15Version = exports.eslintConfigNext16Version = exports.nextVersion = exports.next14Version = exports.next15Version = exports.next16Version = exports.minSupportedNextVersion = exports.nxVersion = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
exports.nxVersion = require((0, path_1.join)('@nx/next', 'package.json')).version;
|
|
6
6
|
exports.minSupportedNextVersion = '14.0.0';
|
|
@@ -15,3 +15,4 @@ exports.eslintConfigNext14Version = '^15.5.18';
|
|
|
15
15
|
exports.eslintConfigNextVersion = exports.eslintConfigNext16Version;
|
|
16
16
|
exports.sassVersion = '1.97.2';
|
|
17
17
|
exports.tsLibVersion = '^2.3.0';
|
|
18
|
+
exports.svgrWebpackVersion = '^8.0.1';
|
package/generators.json
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"schema": "./dist/src/generators/library/schema.json",
|
|
32
32
|
"aliases": ["lib"],
|
|
33
33
|
"x-type": "library",
|
|
34
|
-
"description": "Create a library."
|
|
34
|
+
"description": "Create a Next.js library."
|
|
35
35
|
},
|
|
36
36
|
"custom-server": {
|
|
37
37
|
"factory": "./dist/src/generators/custom-server/custom-server#customServerGenerator",
|
package/migrations.json
CHANGED
|
@@ -29,6 +29,12 @@
|
|
|
29
29
|
"description": "Create AI instructions to help migrate workspaces from Next.js 14 to 15.",
|
|
30
30
|
"prompt": "./dist/src/migrations/update-23-1-0/ai-instructions-for-next-15.md",
|
|
31
31
|
"documentation": "./dist/src/migrations/update-23-1-0/upgrade-to-next-15.md"
|
|
32
|
+
},
|
|
33
|
+
"update-23-2-0-add-svgr-webpack-if-used": {
|
|
34
|
+
"version": "23.2.0-beta.4",
|
|
35
|
+
"description": "Add `@svgr/webpack` when a next config references it.",
|
|
36
|
+
"implementation": "./dist/src/migrations/update-23-2-0/add-svgr-webpack-if-used",
|
|
37
|
+
"documentation": "./dist/src/migrations/update-23-2-0/add-svgr-webpack-if-used.md"
|
|
32
38
|
}
|
|
33
39
|
},
|
|
34
40
|
"packageJsonUpdates": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/next",
|
|
3
|
-
"version": "23.2.0-beta.
|
|
3
|
+
"version": "23.2.0-beta.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Next.js plugin for Nx contains executors and generators for managing Next.js applications and libraries within an Nx workspace. It provides:\n\n\n- Scaffolding for creating, building, serving, linting, and testing Next.js applications.\n\n- Integration with building, serving, and exporting a Next.js application.\n\n- Integration with React libraries within the workspace. \n\nWhen using Next.js in Nx, you get the out-of-the-box support for TypeScript, Playwright, Cypress, and Jest. No need to configure anything: watch mode, source maps, and typings just work.",
|
|
6
6
|
"repository": {
|
|
@@ -67,28 +67,34 @@
|
|
|
67
67
|
"supportsOptionalMigrations": true
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"next": ">=14.0.0 <17.0.0"
|
|
70
|
+
"next": ">=14.0.0 <17.0.0",
|
|
71
|
+
"@nx/webpack": "23.2.0-beta.11"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"@nx/webpack": {
|
|
75
|
+
"optional": true
|
|
76
|
+
}
|
|
71
77
|
},
|
|
72
78
|
"dependencies": {
|
|
73
79
|
"@babel/plugin-proposal-decorators": "^7.22.7",
|
|
74
|
-
"@svgr/webpack": "^8.0.1",
|
|
75
80
|
"copy-webpack-plugin": "^14.0.0",
|
|
76
81
|
"ignore": "^7.0.5",
|
|
77
82
|
"semver": "^7.6.3",
|
|
78
83
|
"tslib": "^2.3.0",
|
|
79
84
|
"webpack-merge": "^5.8.0",
|
|
80
85
|
"@phenomnomnominal/tsquery": "~6.2.0",
|
|
81
|
-
"@nx/devkit": "23.2.0-beta.
|
|
82
|
-
"@nx/js": "23.2.0-beta.
|
|
83
|
-
"@nx/eslint": "23.2.0-beta.
|
|
84
|
-
"@nx/react": "23.2.0-beta.
|
|
85
|
-
"@nx/web": "23.2.0-beta.
|
|
86
|
-
"@nx/webpack": "23.2.0-beta.1"
|
|
86
|
+
"@nx/devkit": "23.2.0-beta.11",
|
|
87
|
+
"@nx/js": "23.2.0-beta.11",
|
|
88
|
+
"@nx/eslint": "23.2.0-beta.11",
|
|
89
|
+
"@nx/react": "23.2.0-beta.11",
|
|
90
|
+
"@nx/web": "23.2.0-beta.11"
|
|
87
91
|
},
|
|
88
92
|
"devDependencies": {
|
|
89
|
-
"@nx/cypress": "23.2.0-beta.
|
|
90
|
-
"@nx/playwright": "23.2.0-beta.
|
|
91
|
-
"nx": "23.2.0-beta.
|
|
93
|
+
"@nx/cypress": "23.2.0-beta.11",
|
|
94
|
+
"@nx/playwright": "23.2.0-beta.11",
|
|
95
|
+
"@nx/vitest": "23.2.0-beta.11",
|
|
96
|
+
"@nx/webpack": "23.2.0-beta.11",
|
|
97
|
+
"nx": "23.2.0-beta.11"
|
|
92
98
|
},
|
|
93
99
|
"publishConfig": {
|
|
94
100
|
"access": "public"
|