@nx/react 0.0.0-pr-29720-06f67e5 → 0.0.0-pr-3-4fa8cf8
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/package.json +6 -6
- package/router-plugin.d.ts +1 -0
- package/router-plugin.js +5 -0
- package/src/generators/application/application.js +48 -9
- package/src/generators/application/files/react-router-ssr/common/app/app-nav.tsx__tmpl__ +15 -0
- package/src/generators/application/files/react-router-ssr/common/app/entry.client.tsx__tmpl__ +18 -0
- package/src/generators/application/files/react-router-ssr/common/app/entry.server.tsx__tmpl__ +74 -0
- package/src/generators/application/files/react-router-ssr/common/app/root.tsx__tmpl__ +51 -0
- package/src/generators/application/files/react-router-ssr/common/app/routes/about.tsx__tmpl__ +7 -0
- package/src/generators/application/files/react-router-ssr/common/app/routes.tsx__tmpl__ +6 -0
- package/src/generators/application/files/react-router-ssr/common/public/favicon.ico +0 -0
- package/src/generators/application/files/react-router-ssr/common/react-router.config.ts__tmpl__ +5 -0
- package/src/generators/application/files/react-router-ssr/common/tests/routes/_index.spec.tsx__tmpl__ +16 -0
- package/src/generators/application/files/react-router-ssr/common/tsconfig.app.json__tmpl__ +23 -0
- package/src/generators/application/files/react-router-ssr/common/tsconfig.json__tmpl__ +27 -0
- package/src/generators/application/files/react-router-ssr/non-root/.gitignore__tmpl__ +5 -0
- package/src/generators/application/files/react-router-ssr/non-root/package.json__tmpl__ +24 -0
- package/src/generators/application/files/react-router-ssr/nx-welcome/claimed/app/nx-welcome.tsx__tmpl__ +866 -0
- package/src/generators/application/files/react-router-ssr/nx-welcome/not-configured/app/nx-welcome.tsx__tmpl__ +866 -0
- package/src/generators/application/files/react-router-ssr/nx-welcome/unclaimed/app/nx-welcome.tsx__tmpl__ +864 -0
- package/src/generators/application/files/react-router-ssr/ts-solution/package.json__tmpl__ +24 -0
- package/src/generators/application/files/react-router-ssr/ts-solution/tsconfig.app.json__tmpl__ +39 -0
- package/src/generators/application/lib/add-e2e.js +29 -24
- package/src/generators/application/lib/add-linting.d.ts +1 -0
- package/src/generators/application/lib/add-linting.js +38 -0
- package/src/generators/application/lib/add-project.js +31 -15
- package/src/generators/application/lib/add-routing.js +1 -1
- package/src/generators/application/lib/bundlers/add-vite.js +15 -6
- package/src/generators/application/lib/create-application-files.js +41 -4
- package/src/generators/application/lib/install-common-dependencies.js +13 -2
- package/src/generators/application/lib/normalize-options.d.ts +0 -2
- package/src/generators/application/lib/normalize-options.js +11 -20
- package/src/generators/application/schema.d.ts +5 -1
- package/src/generators/application/schema.json +10 -1
- package/src/generators/host/host.js +6 -3
- package/src/generators/init/init.js +23 -0
- package/src/generators/init/schema.d.ts +2 -0
- package/src/generators/library/lib/add-rollup-build-target.d.ts +3 -1
- package/src/generators/library/lib/add-rollup-build-target.js +6 -7
- package/src/generators/library/lib/create-files.js +2 -1
- package/src/generators/library/lib/normalize-options.js +8 -5
- package/src/generators/library/library.js +21 -15
- package/src/generators/library/schema.d.ts +2 -0
- package/src/generators/library/schema.json +4 -0
- package/src/generators/remote/remote.js +12 -9
- package/src/plugins/router-plugin.d.ts +10 -0
- package/src/plugins/router-plugin.js +219 -0
- package/src/utils/ast-utils.d.ts +1 -1
- package/src/utils/ast-utils.js +2 -2
- package/src/utils/versions.d.ts +3 -1
- package/src/utils/versions.js +6 -3
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Tree } from 'nx/src/generators/tree';
|
|
2
2
|
import { GeneratorCallback } from '@nx/devkit';
|
|
3
3
|
import { NormalizedSchema } from '../schema';
|
|
4
|
-
export declare function addRollupBuildTarget(host: Tree, options: NormalizedSchema
|
|
4
|
+
export declare function addRollupBuildTarget(host: Tree, options: NormalizedSchema & {
|
|
5
|
+
format?: Array<'esm' | 'cjs'>;
|
|
6
|
+
}, external?: Set<String>): Promise<GeneratorCallback>;
|
|
@@ -4,7 +4,7 @@ exports.addRollupBuildTarget = addRollupBuildTarget;
|
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const maybe_js_1 = require("../../../utils/maybe-js");
|
|
6
6
|
const versions_1 = require("../../../utils/versions");
|
|
7
|
-
async function addRollupBuildTarget(host, options) {
|
|
7
|
+
async function addRollupBuildTarget(host, options, external = new Set(['react', 'react-dom'])) {
|
|
8
8
|
const tasks = [];
|
|
9
9
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/rollup', versions_1.nxVersion);
|
|
10
10
|
tasks.push(await configurationGenerator(host, {
|
|
@@ -19,12 +19,11 @@ async function addRollupBuildTarget(host, options) {
|
|
|
19
19
|
'@svgr/rollup': versions_1.svgrRollupVersion,
|
|
20
20
|
}));
|
|
21
21
|
}
|
|
22
|
-
const external = ['react', 'react-dom'];
|
|
23
22
|
if (options.style === '@emotion/styled') {
|
|
24
|
-
external.
|
|
23
|
+
external.add('@emotion/react/jsx-runtime');
|
|
25
24
|
}
|
|
26
25
|
else {
|
|
27
|
-
external.
|
|
26
|
+
external.add('react/jsx-runtime');
|
|
28
27
|
}
|
|
29
28
|
const nxJson = (0, devkit_1.readNxJson)(host);
|
|
30
29
|
const hasRollupPlugin = !!nxJson.plugins?.some((p) => typeof p === 'string'
|
|
@@ -44,8 +43,8 @@ module.exports = withNx(
|
|
|
44
43
|
: (0, devkit_1.joinPathFragments)((0, devkit_1.offsetFromRoot)(options.projectRoot), 'dist', options.projectRoot)}',
|
|
45
44
|
tsConfig: './tsconfig.lib.json',
|
|
46
45
|
compiler: '${options.compiler ?? 'babel'}',
|
|
47
|
-
external: ${JSON.stringify(external)},
|
|
48
|
-
format: ['esm'],
|
|
46
|
+
external: ${JSON.stringify(Array.from(external))},
|
|
47
|
+
format: ${JSON.stringify(options.format ?? ['esm'])},
|
|
49
48
|
assets:[{ input: '.', output: '.', glob: 'README.md'}],
|
|
50
49
|
}, {
|
|
51
50
|
// Provide additional rollup configuration here. See: https://rollupjs.org/configuration-options
|
|
@@ -74,7 +73,7 @@ module.exports = withNx(
|
|
|
74
73
|
tsConfig: `${options.projectRoot}/tsconfig.lib.json`,
|
|
75
74
|
project: `${options.projectRoot}/package.json`,
|
|
76
75
|
entryFile: (0, maybe_js_1.maybeJs)(options, `${options.projectRoot}/src/index.ts`),
|
|
77
|
-
external,
|
|
76
|
+
external: Array.from(external),
|
|
78
77
|
rollupConfig: `@nx/react/plugins/bundle-rollup`,
|
|
79
78
|
compiler: options.compiler ?? 'babel',
|
|
80
79
|
assets: [
|
|
@@ -43,7 +43,8 @@ function createFiles(host, options) {
|
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
if ((options.publishable || options.buildable) &&
|
|
46
|
-
!options.isUsingTsSolutionConfig
|
|
46
|
+
!options.isUsingTsSolutionConfig &&
|
|
47
|
+
options.useProjectJson) {
|
|
47
48
|
if (options.bundler === 'vite') {
|
|
48
49
|
(0, devkit_1.writeJson)(host, `${options.projectRoot}/package.json`, {
|
|
49
50
|
name: options.importPath,
|
|
@@ -7,7 +7,7 @@ const assertion_1 = require("../../../utils/assertion");
|
|
|
7
7
|
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
|
|
8
8
|
async function normalizeOptions(host, options) {
|
|
9
9
|
const isUsingTsSolutionConfig = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(host);
|
|
10
|
-
await (0, project_name_and_root_utils_1.
|
|
10
|
+
await (0, project_name_and_root_utils_1.ensureRootProjectName)(options, 'library');
|
|
11
11
|
const { projectName, names: projectNames, projectRoot, importPath, } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(host, {
|
|
12
12
|
name: options.name,
|
|
13
13
|
projectType: 'library',
|
|
@@ -41,23 +41,26 @@ async function normalizeOptions(host, options) {
|
|
|
41
41
|
bundler,
|
|
42
42
|
fileName,
|
|
43
43
|
routePath: `/${projectNames.projectSimpleName}`,
|
|
44
|
-
name: isUsingTsSolutionConfig ? importPath : projectName,
|
|
44
|
+
name: isUsingTsSolutionConfig && !options.name ? importPath : projectName,
|
|
45
45
|
projectRoot,
|
|
46
46
|
parsedTags,
|
|
47
47
|
importPath,
|
|
48
|
+
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
|
48
49
|
};
|
|
49
50
|
// Libraries with a bundler or is publishable must also be buildable.
|
|
50
51
|
normalized.buildable = Boolean(normalized.bundler !== 'none' || options.buildable || options.publishable);
|
|
51
52
|
normalized.inSourceTests === normalized.minimal || normalized.inSourceTests;
|
|
52
53
|
if (options.appProject) {
|
|
53
54
|
const appProjectConfig = (0, devkit_1.getProjects)(host).get(options.appProject);
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
const appProjectType = (0, ts_solution_setup_1.getProjectType)(host, appProjectConfig.root, appProjectConfig.projectType);
|
|
56
|
+
if (appProjectType !== 'application') {
|
|
57
|
+
throw new Error(`appProject expected type of "application" but got "${appProjectType}"`);
|
|
56
58
|
}
|
|
59
|
+
const appSourceRoot = (0, ts_solution_setup_1.getProjectSourceRoot)(host, appProjectConfig.sourceRoot, appProjectConfig.root);
|
|
57
60
|
normalized.appMain =
|
|
58
61
|
appProjectConfig.targets.build?.options?.main ??
|
|
59
62
|
findMainEntry(host, appProjectConfig.root);
|
|
60
|
-
normalized.appSourceRoot = (0, devkit_1.normalizePath)(
|
|
63
|
+
normalized.appSourceRoot = (0, devkit_1.normalizePath)(appSourceRoot);
|
|
61
64
|
// TODO(jack): We should use appEntryFile instead of appProject so users can directly set it rather than us inferring it.
|
|
62
65
|
if (!normalized.appMain) {
|
|
63
66
|
throw new Error(`Could not locate project main for ${options.appProject}`);
|
|
@@ -27,6 +27,7 @@ const add_release_config_1 = require("@nx/js/src/generators/library/utils/add-re
|
|
|
27
27
|
async function libraryGenerator(host, schema) {
|
|
28
28
|
return await libraryGeneratorInternal(host, {
|
|
29
29
|
addPlugin: false,
|
|
30
|
+
useProjectJson: true,
|
|
30
31
|
...schema,
|
|
31
32
|
});
|
|
32
33
|
}
|
|
@@ -38,9 +39,6 @@ async function libraryGeneratorInternal(host, schema) {
|
|
|
38
39
|
});
|
|
39
40
|
tasks.push(jsInitTask);
|
|
40
41
|
const options = await (0, normalize_options_1.normalizeOptions)(host, schema);
|
|
41
|
-
if (options.isUsingTsSolutionConfig) {
|
|
42
|
-
(0, ts_solution_setup_1.addProjectToTsSolutionWorkspace)(host, options.projectRoot);
|
|
43
|
-
}
|
|
44
42
|
if (options.publishable === true && !schema.importPath) {
|
|
45
43
|
throw new Error(`For publishable libs you have to provide a proper "--importPath" which needs to be a valid npm package name (e.g. my-awesome-lib or @myorg/my-lib)`);
|
|
46
44
|
}
|
|
@@ -52,18 +50,20 @@ async function libraryGeneratorInternal(host, schema) {
|
|
|
52
50
|
skipFormat: true,
|
|
53
51
|
});
|
|
54
52
|
tasks.push(initTask);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
53
|
+
const packageJson = {
|
|
54
|
+
name: options.importPath,
|
|
55
|
+
version: '0.0.1',
|
|
56
|
+
...(0, determine_entry_fields_1.determineEntryFields)(options),
|
|
57
|
+
files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined,
|
|
58
|
+
};
|
|
59
|
+
if (!options.useProjectJson) {
|
|
60
|
+
if (options.name !== options.importPath) {
|
|
61
|
+
packageJson.nx = { name: options.name };
|
|
62
|
+
}
|
|
63
|
+
if (options.parsedTags?.length) {
|
|
64
|
+
packageJson.nx ??= {};
|
|
65
|
+
packageJson.nx.tags = options.parsedTags;
|
|
66
|
+
}
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
69
|
(0, devkit_1.addProjectConfiguration)(host, options.name, {
|
|
@@ -74,7 +74,13 @@ async function libraryGeneratorInternal(host, schema) {
|
|
|
74
74
|
targets: {},
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
|
+
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
|
78
|
+
(0, devkit_1.writeJson)(host, `${options.projectRoot}/package.json`, packageJson);
|
|
79
|
+
}
|
|
77
80
|
(0, create_files_1.createFiles)(host, options);
|
|
81
|
+
if (options.isUsingTsSolutionConfig) {
|
|
82
|
+
await (0, ts_solution_setup_1.addProjectToTsSolutionWorkspace)(host, options.projectRoot);
|
|
83
|
+
}
|
|
78
84
|
const lintTask = await (0, add_linting_1.addLinting)(host, options);
|
|
79
85
|
tasks.push(lintTask);
|
|
80
86
|
// Set up build target
|
|
@@ -27,6 +27,7 @@ export interface Schema {
|
|
|
27
27
|
minimal?: boolean;
|
|
28
28
|
simpleName?: boolean;
|
|
29
29
|
addPlugin?: boolean;
|
|
30
|
+
useProjectJson?: boolean;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export interface NormalizedSchema extends Schema {
|
|
@@ -36,6 +37,7 @@ export interface NormalizedSchema extends Schema {
|
|
|
36
37
|
projectRoot: string;
|
|
37
38
|
routePath: string;
|
|
38
39
|
parsedTags: string[];
|
|
40
|
+
importPath: string;
|
|
39
41
|
appMain?: string;
|
|
40
42
|
appSourceRoot?: string;
|
|
41
43
|
unitTestRunner: 'jest' | 'vitest' | 'none';
|
|
@@ -190,6 +190,10 @@
|
|
|
190
190
|
"description": "Don't include the directory in the name of the module of the library.",
|
|
191
191
|
"type": "boolean",
|
|
192
192
|
"default": false
|
|
193
|
+
},
|
|
194
|
+
"useProjectJson": {
|
|
195
|
+
"type": "boolean",
|
|
196
|
+
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
|
193
197
|
}
|
|
194
198
|
},
|
|
195
199
|
"required": ["directory"]
|
|
@@ -48,7 +48,10 @@ function addModuleFederationFiles(host, options) {
|
|
|
48
48
|
async function remoteGenerator(host, schema) {
|
|
49
49
|
const tasks = [];
|
|
50
50
|
const options = {
|
|
51
|
-
...(await (0, normalize_options_1.normalizeOptions)(host,
|
|
51
|
+
...(await (0, normalize_options_1.normalizeOptions)(host, {
|
|
52
|
+
...schema,
|
|
53
|
+
useProjectJson: true,
|
|
54
|
+
})),
|
|
52
55
|
// when js is set to true, we want to use the js configuration
|
|
53
56
|
js: schema.js ?? false,
|
|
54
57
|
typescriptConfiguration: schema.js
|
|
@@ -62,29 +65,29 @@ async function remoteGenerator(host, schema) {
|
|
|
62
65
|
if (options.dynamic) {
|
|
63
66
|
// Dynamic remotes generate with library { type: 'var' } by default.
|
|
64
67
|
// We need to ensure that the remote name is a valid variable name.
|
|
65
|
-
const isValidRemote = (0, js_1.isValidVariable)(options.
|
|
68
|
+
const isValidRemote = (0, js_1.isValidVariable)(options.projectName);
|
|
66
69
|
if (!isValidRemote.isValid) {
|
|
67
|
-
throw new Error(`Invalid remote name provided: ${options.
|
|
70
|
+
throw new Error(`Invalid remote name provided: ${options.projectName}. ${isValidRemote.message}`);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
|
-
await (0, project_name_and_root_utils_1.
|
|
73
|
+
await (0, project_name_and_root_utils_1.ensureRootProjectName)(options, 'application');
|
|
71
74
|
const REMOTE_NAME_REGEX = '^[a-zA-Z_$][a-zA-Z_$0-9]*$';
|
|
72
75
|
const remoteNameRegex = new RegExp(REMOTE_NAME_REGEX);
|
|
73
|
-
if (!remoteNameRegex.test(options.
|
|
74
|
-
throw new Error((0, devkit_1.stripIndents) `Invalid remote name: ${options.
|
|
76
|
+
if (!remoteNameRegex.test(options.projectName)) {
|
|
77
|
+
throw new Error((0, devkit_1.stripIndents) `Invalid remote name: ${options.projectName}. Remote project names must:
|
|
75
78
|
- Start with a letter, dollar sign ($) or underscore (_)
|
|
76
79
|
- Followed by any valid character (letters, digits, underscores, or dollar signs)
|
|
77
80
|
The regular expression used is ${REMOTE_NAME_REGEX}.`);
|
|
78
81
|
}
|
|
79
82
|
const initAppTask = await (0, application_1.default)(host, {
|
|
80
83
|
...options,
|
|
81
|
-
name: options.
|
|
84
|
+
name: options.projectName,
|
|
82
85
|
skipFormat: true,
|
|
83
|
-
|
|
86
|
+
useProjectJson: true,
|
|
84
87
|
});
|
|
85
88
|
tasks.push(initAppTask);
|
|
86
89
|
if (options.host) {
|
|
87
|
-
(0, update_host_with_remote_1.updateHostWithRemote)(host, options.host, options.
|
|
90
|
+
(0, update_host_with_remote_1.updateHostWithRemote)(host, options.host, options.projectName);
|
|
88
91
|
}
|
|
89
92
|
// Module federation requires bootstrap code to be dynamically imported.
|
|
90
93
|
// Renaming original entry file so we can use `import(./bootstrap)` in
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type CreateNodesV2 } from '@nx/devkit';
|
|
2
|
+
export interface ReactRouterPluginOptions {
|
|
3
|
+
buildTargetName?: string;
|
|
4
|
+
devTargetName?: string;
|
|
5
|
+
startTargetName?: string;
|
|
6
|
+
typecheckTargetName?: string;
|
|
7
|
+
buildDepsTargetName?: string;
|
|
8
|
+
watchDepsTargetName?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const createNodesV2: CreateNodesV2<ReactRouterPluginOptions>;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodesV2 = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
|
|
8
|
+
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
9
|
+
const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
|
|
10
|
+
const js_1 = require("@nx/js");
|
|
11
|
+
const devkit_internals_1 = require("nx/src/devkit-internals");
|
|
12
|
+
const util_1 = require("@nx/js/src/plugins/typescript/util");
|
|
13
|
+
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
|
|
14
|
+
const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
|
|
15
|
+
const pmCommand = (0, devkit_1.getPackageManagerCommand)();
|
|
16
|
+
const reactRouterConfigBlob = '**/react-router.config.{ts,js,cjs,cts,mjs,mts}';
|
|
17
|
+
function readTargetsCache(cachePath) {
|
|
18
|
+
return process.env.NX_CACHE_PROJECT_GRAPH !== 'false' && (0, fs_1.existsSync)(cachePath)
|
|
19
|
+
? (0, devkit_1.readJsonFile)(cachePath)
|
|
20
|
+
: {};
|
|
21
|
+
}
|
|
22
|
+
function writeTargetsToCache(cachePath, results) {
|
|
23
|
+
(0, devkit_1.writeJsonFile)(cachePath, results);
|
|
24
|
+
}
|
|
25
|
+
exports.createNodesV2 = [
|
|
26
|
+
reactRouterConfigBlob,
|
|
27
|
+
async (configFiles, options, context) => {
|
|
28
|
+
const optionsHash = (0, devkit_internals_1.hashObject)(options);
|
|
29
|
+
const normalizedOptions = normalizeOptions(options);
|
|
30
|
+
const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `react-router-${optionsHash}.hash`);
|
|
31
|
+
const targetsCache = readTargetsCache(cachePath);
|
|
32
|
+
const isUsingTsSolutionSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)();
|
|
33
|
+
const { roots: projectRoots, configFiles: validConfigFiles } = configFiles.reduce((acc, configFile) => {
|
|
34
|
+
const potentialRoot = (0, path_1.dirname)(configFile);
|
|
35
|
+
if (checkIfConfigFileShouldBeProject(potentialRoot, context)) {
|
|
36
|
+
acc.roots.push(potentialRoot);
|
|
37
|
+
acc.configFiles.push(configFile);
|
|
38
|
+
}
|
|
39
|
+
return acc;
|
|
40
|
+
}, {
|
|
41
|
+
roots: [],
|
|
42
|
+
configFiles: [],
|
|
43
|
+
});
|
|
44
|
+
const lockfile = (0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot));
|
|
45
|
+
const hashes = await (0, calculate_hash_for_create_nodes_1.calculateHashesForCreateNodes)(projectRoots, { ...normalizedOptions, isUsingTsSolutionSetup }, context, projectRoots.map((_) => [lockfile]));
|
|
46
|
+
try {
|
|
47
|
+
return await (0, devkit_1.createNodesFromFiles)(async (configFile, _, context, idx) => {
|
|
48
|
+
const projectRoot = (0, path_1.dirname)(configFile);
|
|
49
|
+
const siblingFiles = (0, fs_1.readdirSync)((0, devkit_1.joinPathFragments)(context.workspaceRoot, projectRoot));
|
|
50
|
+
const hash = hashes[idx] + configFile;
|
|
51
|
+
const { projectType, metadata, targets } = (targetsCache[hash] ??=
|
|
52
|
+
await buildReactRouterTargets(configFile, projectRoot, normalizedOptions, context, siblingFiles, isUsingTsSolutionSetup));
|
|
53
|
+
const project = {
|
|
54
|
+
root: projectRoot,
|
|
55
|
+
targets,
|
|
56
|
+
metadata,
|
|
57
|
+
};
|
|
58
|
+
if (project.targets[normalizedOptions.buildTargetName]) {
|
|
59
|
+
project.projectType = projectType;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
projects: {
|
|
63
|
+
[projectRoot]: project,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}, validConfigFiles, options, context);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
writeTargetsToCache(cachePath, targetsCache);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
async function buildReactRouterTargets(configFilePath, projectRoot, options, context, siblingFiles, isUsingTsSolutionSetup) {
|
|
74
|
+
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
75
|
+
const configPath = (0, path_1.join)(context.workspaceRoot, configFilePath);
|
|
76
|
+
if (require.cache[configPath])
|
|
77
|
+
(0, config_utils_1.clearRequireCache)();
|
|
78
|
+
const reactRouterConfig = await (0, config_utils_1.loadConfigFile)(configPath);
|
|
79
|
+
const isLibMode = reactRouterConfig?.ssr !== undefined && reactRouterConfig.ssr === false;
|
|
80
|
+
const { buildDirectory, serverBuildPath } = await getBuildPaths(reactRouterConfig, isLibMode);
|
|
81
|
+
const targets = {};
|
|
82
|
+
targets[options.buildTargetName] = await getBuildTargetConfig(options.buildTargetName, projectRoot, buildDirectory, serverBuildPath, namedInputs, isUsingTsSolutionSetup);
|
|
83
|
+
targets[options.devTargetName] = await devTarget(projectRoot, isUsingTsSolutionSetup);
|
|
84
|
+
if (serverBuildPath) {
|
|
85
|
+
targets[options.startTargetName] = await startTarget(projectRoot, serverBuildPath, options.buildTargetName, isUsingTsSolutionSetup);
|
|
86
|
+
}
|
|
87
|
+
targets[options.typecheckTargetName] = await typecheckTarget(projectRoot, options.typecheckTargetName, namedInputs, siblingFiles, isUsingTsSolutionSetup);
|
|
88
|
+
(0, util_1.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmCommand);
|
|
89
|
+
const metadata = {};
|
|
90
|
+
return {
|
|
91
|
+
targets,
|
|
92
|
+
metadata,
|
|
93
|
+
projectType: isLibMode ? 'library' : 'application',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async function getBuildTargetConfig(buildTargetName, projectRoot, buildDirectory, serverBuildDirectory, namedInputs, isUsingTsSolutionSetup) {
|
|
97
|
+
const basePath = projectRoot === '.'
|
|
98
|
+
? `{workspaceRoot}`
|
|
99
|
+
: (0, devkit_1.joinPathFragments)(`{workspaceRoot}`, projectRoot);
|
|
100
|
+
const outputs = [
|
|
101
|
+
(0, devkit_1.joinPathFragments)(basePath, buildDirectory),
|
|
102
|
+
...(serverBuildDirectory
|
|
103
|
+
? [(0, devkit_1.joinPathFragments)(basePath, serverBuildDirectory)]
|
|
104
|
+
: []),
|
|
105
|
+
];
|
|
106
|
+
const buildTarget = {
|
|
107
|
+
cache: true,
|
|
108
|
+
dependsOn: [`^${buildTargetName}`],
|
|
109
|
+
inputs: [
|
|
110
|
+
...('production' in namedInputs
|
|
111
|
+
? ['production', '^production']
|
|
112
|
+
: ['default', '^default']),
|
|
113
|
+
{ externalDependencies: ['@react-router/dev'] },
|
|
114
|
+
],
|
|
115
|
+
outputs,
|
|
116
|
+
command: 'react-router build',
|
|
117
|
+
options: { cwd: projectRoot },
|
|
118
|
+
};
|
|
119
|
+
if (isUsingTsSolutionSetup) {
|
|
120
|
+
buildTarget.syncGenerators = ['@nx/js:typescript-sync'];
|
|
121
|
+
}
|
|
122
|
+
return buildTarget;
|
|
123
|
+
}
|
|
124
|
+
async function getBuildPaths(reactRouterConfig, isLibMode) {
|
|
125
|
+
return {
|
|
126
|
+
buildDirectory: reactRouterConfig?.buildDirectory ?? 'build/client',
|
|
127
|
+
...(isLibMode
|
|
128
|
+
? undefined
|
|
129
|
+
: {
|
|
130
|
+
serverBuildPath: reactRouterConfig?.buildDirectory
|
|
131
|
+
? (0, path_1.join)((0, path_1.dirname)(reactRouterConfig.buildDirectory), `server`)
|
|
132
|
+
: 'build/server',
|
|
133
|
+
}),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
async function devTarget(projectRoot, isUsingTsSolutionSetup) {
|
|
137
|
+
const devTarget = {
|
|
138
|
+
command: 'react-router dev',
|
|
139
|
+
options: { cwd: projectRoot },
|
|
140
|
+
};
|
|
141
|
+
if (isUsingTsSolutionSetup) {
|
|
142
|
+
devTarget.syncGenerators = ['@nx/js:typescript-sync'];
|
|
143
|
+
}
|
|
144
|
+
return devTarget;
|
|
145
|
+
}
|
|
146
|
+
async function startTarget(projectRoot, serverBuildPath, buildTargetName, isUsingTsSolutionSetup) {
|
|
147
|
+
const serverPath = serverBuildPath === 'build/server'
|
|
148
|
+
? `${serverBuildPath}/index.js`
|
|
149
|
+
: serverBuildPath;
|
|
150
|
+
const startTarget = {
|
|
151
|
+
dependsOn: [buildTargetName],
|
|
152
|
+
command: `react-router-serve ${serverPath}`,
|
|
153
|
+
options: { cwd: projectRoot },
|
|
154
|
+
};
|
|
155
|
+
if (isUsingTsSolutionSetup) {
|
|
156
|
+
startTarget.syncGenerators = ['@nx/js:typescript-sync'];
|
|
157
|
+
}
|
|
158
|
+
return startTarget;
|
|
159
|
+
}
|
|
160
|
+
async function typecheckTarget(projectRoot, typecheckTargetName, namedInputs, siblingFiles, isUsingTsSolutionSetup) {
|
|
161
|
+
const hasTsConfigAppJson = siblingFiles.includes('tsconfig.app.json');
|
|
162
|
+
const typecheckTarget = {
|
|
163
|
+
cache: true,
|
|
164
|
+
inputs: [
|
|
165
|
+
...('production' in namedInputs
|
|
166
|
+
? ['production', '^production']
|
|
167
|
+
: ['default', '^default']),
|
|
168
|
+
{ externalDependencies: ['typescript'] },
|
|
169
|
+
],
|
|
170
|
+
command: isUsingTsSolutionSetup
|
|
171
|
+
? `tsc --build --emitDeclarationOnly`
|
|
172
|
+
: `tsc${hasTsConfigAppJson ? ` -p tsconfig.app.json` : ``} --noEmit`,
|
|
173
|
+
options: {
|
|
174
|
+
cwd: projectRoot,
|
|
175
|
+
},
|
|
176
|
+
metadata: {
|
|
177
|
+
description: `Runs type-checking for the project.`,
|
|
178
|
+
technologies: ['typescript'],
|
|
179
|
+
help: {
|
|
180
|
+
command: isUsingTsSolutionSetup
|
|
181
|
+
? `${pmCommand.exec} tsc --build --help`
|
|
182
|
+
: `${pmCommand.exec} tsc${hasTsConfigAppJson ? ` -p tsconfig.app.json` : ``} --help`,
|
|
183
|
+
example: isUsingTsSolutionSetup
|
|
184
|
+
? { args: ['--force'] }
|
|
185
|
+
: { options: { noEmit: true } },
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
if (isUsingTsSolutionSetup) {
|
|
190
|
+
typecheckTarget.dependsOn = [`^${typecheckTargetName}`];
|
|
191
|
+
typecheckTarget.syncGenerators = ['@nx/js:typescript-sync'];
|
|
192
|
+
}
|
|
193
|
+
return typecheckTarget;
|
|
194
|
+
}
|
|
195
|
+
function normalizeOptions(options) {
|
|
196
|
+
options ??= {};
|
|
197
|
+
options.buildTargetName ??= 'build';
|
|
198
|
+
options.devTargetName ??= 'dev';
|
|
199
|
+
options.startTargetName ??= 'start';
|
|
200
|
+
options.typecheckTargetName ??= 'typecheck';
|
|
201
|
+
return options;
|
|
202
|
+
}
|
|
203
|
+
function checkIfConfigFileShouldBeProject(projectRoot, context) {
|
|
204
|
+
// Do not create a project if package.json and project.json isn't there.
|
|
205
|
+
const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
|
|
206
|
+
return hasRequiredConfigs(siblingFiles);
|
|
207
|
+
}
|
|
208
|
+
function hasRequiredConfigs(files) {
|
|
209
|
+
const lowerFiles = files.map((file) => file.toLowerCase());
|
|
210
|
+
// Check if vite.config.{ext} is present
|
|
211
|
+
const hasViteConfig = lowerFiles.some((file) => {
|
|
212
|
+
const parts = file.split('.');
|
|
213
|
+
return parts[0] === 'vite' && parts[1] === 'config' && parts.length > 2;
|
|
214
|
+
});
|
|
215
|
+
if (!hasViteConfig)
|
|
216
|
+
return false;
|
|
217
|
+
const hasProjectOrPackageJson = lowerFiles.includes('project.json') || lowerFiles.includes('package.json');
|
|
218
|
+
return hasProjectOrPackageJson;
|
|
219
|
+
}
|
package/src/utils/ast-utils.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare function findComponentImportPath(componentName: string, source: t
|
|
|
11
11
|
export declare function findElements(source: ts.SourceFile, tagName: string): ts.Node[];
|
|
12
12
|
export declare function findClosestOpening(tagName: string, node: ts.Node): ts.Node;
|
|
13
13
|
export declare function isTag(tagName: string, node: ts.Node): boolean;
|
|
14
|
-
export declare function addInitialRoutes(sourcePath: string, source: ts.SourceFile): StringChange[];
|
|
14
|
+
export declare function addInitialRoutes(sourcePath: string, source: ts.SourceFile, addBrowserRouter?: boolean): StringChange[];
|
|
15
15
|
export declare function addRoute(sourcePath: string, source: ts.SourceFile, options: {
|
|
16
16
|
routePath: string;
|
|
17
17
|
componentName: string;
|
package/src/utils/ast-utils.js
CHANGED
|
@@ -234,7 +234,7 @@ function isTag(tagName, node) {
|
|
|
234
234
|
}
|
|
235
235
|
return false;
|
|
236
236
|
}
|
|
237
|
-
function addInitialRoutes(sourcePath, source) {
|
|
237
|
+
function addInitialRoutes(sourcePath, source, addBrowserRouter) {
|
|
238
238
|
if (!tsModule) {
|
|
239
239
|
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
|
240
240
|
}
|
|
@@ -281,7 +281,7 @@ function addInitialRoutes(sourcePath, source) {
|
|
|
281
281
|
`,
|
|
282
282
|
};
|
|
283
283
|
return [
|
|
284
|
-
...addImport(source, `import { Route, Routes, Link } from 'react-router-dom';`),
|
|
284
|
+
...addImport(source, `import { Route, Routes, Link ${addBrowserRouter ? ', BrowserRouter ' : ''}} from 'react-router-dom';`),
|
|
285
285
|
insertRoutes,
|
|
286
286
|
];
|
|
287
287
|
}
|
package/src/utils/versions.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare const typesReactDomVersion = "19.0.0";
|
|
|
14
14
|
export declare const typesReactIsV18Version = "18.3.0";
|
|
15
15
|
export declare const typesReactIsVersion = "19.0.0";
|
|
16
16
|
export declare const reactViteVersion = "^4.2.0";
|
|
17
|
-
export declare const typesNodeVersion = "
|
|
17
|
+
export declare const typesNodeVersion = "^20.0.0";
|
|
18
18
|
export declare const babelPresetReactVersion = "^7.14.5";
|
|
19
19
|
export declare const babelCoreVersion = "^7.14.5";
|
|
20
20
|
export declare const styledComponentsVersion = "5.3.6";
|
|
@@ -24,6 +24,8 @@ export declare const emotionReactVersion = "11.11.1";
|
|
|
24
24
|
export declare const emotionBabelPlugin = "11.11.0";
|
|
25
25
|
export declare const styledJsxVersion = "5.1.2";
|
|
26
26
|
export declare const reactRouterDomVersion = "6.29.0";
|
|
27
|
+
export declare const reactRouterVersion = "^7.2.0";
|
|
28
|
+
export declare const reactRouterIsBotVersion = "^4.4.0";
|
|
27
29
|
export declare const testingLibraryReactVersion = "16.1.0";
|
|
28
30
|
export declare const testingLibraryDomVersion = "10.4.0";
|
|
29
31
|
export declare const reduxjsToolkitVersion = "1.9.3";
|
package/src/utils/versions.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.swcPluginStyledComponentsVersion = exports.swcPluginEmotionVersion = exports.swcPluginStyledJsxVersion = void 0;
|
|
3
|
+
exports.sassVersion = exports.lessVersion = exports.moduleFederationEnhancedVersion = exports.moduleFederationNodeVersion = exports.typesCorsVersion = exports.corsVersion = exports.isbotVersion = exports.typesExpressVersion = exports.expressVersion = exports.autoprefixerVersion = exports.tailwindcssVersion = exports.postcssVersion = exports.tsLibVersion = exports.babelPluginStyledComponentsVersion = exports.eslintPluginReactHooksVersion = exports.eslintPluginReactVersion = exports.eslintPluginJsxA11yVersion = exports.eslintPluginImportVersion = exports.reactReduxVersion = exports.reduxjsToolkitVersion = exports.testingLibraryDomVersion = exports.testingLibraryReactVersion = exports.reactRouterIsBotVersion = exports.reactRouterVersion = exports.reactRouterDomVersion = exports.styledJsxVersion = exports.emotionBabelPlugin = exports.emotionReactVersion = exports.emotionStyledVersion = exports.typesStyledComponentsVersion = exports.styledComponentsVersion = exports.babelCoreVersion = exports.babelPresetReactVersion = exports.typesNodeVersion = exports.reactViteVersion = exports.typesReactIsVersion = exports.typesReactIsV18Version = exports.typesReactDomVersion = exports.typesReactDomV18Version = exports.typesReactVersion = exports.typesReactV18Version = exports.babelLoaderVersion = exports.swcLoaderVersion = exports.reactIsV18Version = exports.reactIsVersion = exports.reactDomV18Version = exports.reactDomVersion = exports.reactV18Version = exports.reactVersion = exports.nxVersion = void 0;
|
|
4
|
+
exports.swcPluginStyledComponentsVersion = exports.swcPluginEmotionVersion = exports.swcPluginStyledJsxVersion = exports.svgrRollupVersion = exports.rollupPluginUrlVersion = void 0;
|
|
5
5
|
exports.nxVersion = require('../../package.json').version;
|
|
6
6
|
exports.reactVersion = '19.0.0';
|
|
7
7
|
exports.reactV18Version = '18.3.1';
|
|
@@ -18,7 +18,8 @@ exports.typesReactDomVersion = '19.0.0';
|
|
|
18
18
|
exports.typesReactIsV18Version = '18.3.0';
|
|
19
19
|
exports.typesReactIsVersion = '19.0.0';
|
|
20
20
|
exports.reactViteVersion = '^4.2.0';
|
|
21
|
-
|
|
21
|
+
// Needed for React-Router
|
|
22
|
+
exports.typesNodeVersion = '^20.0.0';
|
|
22
23
|
exports.babelPresetReactVersion = '^7.14.5';
|
|
23
24
|
exports.babelCoreVersion = '^7.14.5';
|
|
24
25
|
exports.styledComponentsVersion = '5.3.6';
|
|
@@ -29,6 +30,8 @@ exports.emotionBabelPlugin = '11.11.0';
|
|
|
29
30
|
// WARNING: This needs to be in sync with Next.js' dependency or else there might be issues.
|
|
30
31
|
exports.styledJsxVersion = '5.1.2';
|
|
31
32
|
exports.reactRouterDomVersion = '6.29.0';
|
|
33
|
+
exports.reactRouterVersion = '^7.2.0';
|
|
34
|
+
exports.reactRouterIsBotVersion = '^4.4.0';
|
|
32
35
|
exports.testingLibraryReactVersion = '16.1.0';
|
|
33
36
|
exports.testingLibraryDomVersion = '10.4.0';
|
|
34
37
|
exports.reduxjsToolkitVersion = '1.9.3';
|