@nx/react 0.0.0-pr-30565-3c9418e → 0.0.0-pr-29464-73fdcbb
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/plugins/nx-react-webpack-plugin/lib/apply-react-config.js +3 -1
- package/src/generators/application/application.js +21 -20
- package/src/generators/application/files/react-router-ssr/common/app/app-nav.tsx__tmpl__ +0 -1
- package/src/generators/application/lib/add-e2e.js +4 -0
- package/src/generators/application/lib/add-jest.js +26 -2
- package/src/generators/application/lib/create-application-files.d.ts +61 -0
- package/src/generators/application/lib/create-application-files.js +49 -44
- package/src/generators/application/lib/normalize-options.js +4 -1
- package/src/generators/host/files/rspack-module-federation/rspack.config.js__tmpl__ +37 -13
- package/src/generators/host/files/rspack-module-federation/rspack.config.prod.js__tmpl__ +60 -32
- package/src/generators/host/files/rspack-module-federation-ssr/module-federation.server.config.js__tmpl__ +6 -0
- package/src/generators/host/files/rspack-module-federation-ssr/rspack.config.js__tmpl__ +66 -0
- package/src/generators/host/files/rspack-module-federation-ssr/server.ts__tmpl__ +1 -1
- package/src/generators/host/files/rspack-module-federation-ssr/src/main.server.tsx__tmpl__ +49 -0
- package/src/generators/host/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +6 -0
- package/src/generators/host/files/rspack-module-federation-ssr-ts/rspack.config.ts__tmpl__ +66 -0
- package/src/generators/host/files/rspack-module-federation-ssr-ts/server.ts__tmpl__ +1 -1
- package/src/generators/host/files/rspack-module-federation-ssr-ts/src/main.server.tsx__tmpl__ +49 -0
- package/src/generators/host/files/rspack-module-federation-ts/rspack.config.prod.ts__tmpl__ +37 -9
- package/src/generators/host/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +37 -14
- package/src/generators/host/host.js +15 -15
- package/src/generators/host/lib/add-module-federation-files.js +28 -12
- package/src/generators/host/lib/normalize-host-name.d.ts +2 -0
- package/src/generators/host/lib/normalize-host-name.js +12 -0
- package/src/generators/host/lib/setup-ssr-for-host.d.ts +3 -3
- package/src/generators/host/lib/setup-ssr-for-host.js +46 -22
- package/src/generators/library/library.js +1 -1
- package/src/generators/remote/files/rspack-module-federation/rspack.config.js__tmpl__ +40 -13
- package/src/generators/remote/files/rspack-module-federation-ssr/module-federation.server.config.js__tmpl__ +6 -0
- package/src/generators/remote/files/rspack-module-federation-ssr/rspack.config.js__tmpl__ +69 -0
- package/src/generators/remote/files/rspack-module-federation-ssr/server.ts__tmpl__ +2 -2
- package/src/generators/remote/files/rspack-module-federation-ssr/src/main.server.tsx__tmpl__ +45 -0
- package/src/generators/remote/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +6 -0
- package/src/generators/remote/files/rspack-module-federation-ssr-ts/rspack.config.ts__tmpl__ +69 -0
- package/src/generators/remote/files/rspack-module-federation-ssr-ts/server.ts__tmpl__ +2 -2
- package/src/generators/remote/files/rspack-module-federation-ssr-ts/src/main.server.tsx__tmpl__ +45 -0
- package/src/generators/remote/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +40 -13
- package/src/generators/remote/lib/setup-ssr-for-remote.d.ts +1 -1
- package/src/generators/remote/lib/setup-ssr-for-remote.js +37 -15
- package/src/generators/remote/remote.js +27 -21
- package/src/rules/update-module-federation-project.d.ts +2 -1
- package/src/rules/update-module-federation-project.js +28 -47
- package/src/utils/assertion.d.ts +2 -0
- package/src/utils/assertion.js +6 -0
- package/src/utils/ct-utils.d.ts +1 -1
- package/src/generators/host/files/rspack-module-federation-ssr/rspack.server.config.js__tmpl__ +0 -16
- package/src/generators/host/files/rspack-module-federation-ssr-ts/rspack.server.config.ts__tmpl__ +0 -16
- package/src/generators/remote/files/rspack-module-federation-ssr/rspack.server.config.js__tmpl__ +0 -16
- package/src/generators/remote/files/rspack-module-federation-ssr-ts/rspack.server.config.ts__tmpl__ +0 -16
- package/src/utils/format-file.d.ts +0 -1
- package/src/utils/format-file.js +0 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/react",
|
|
3
|
-
"version": "0.0.0-pr-
|
|
3
|
+
"version": "0.0.0-pr-29464-73fdcbb",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The React plugin for Nx contains executors and generators for managing React applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Vitest, Playwright, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
|
|
6
6
|
"repository": {
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"minimatch": "9.0.3",
|
|
39
39
|
"picocolors": "^1.1.0",
|
|
40
40
|
"tslib": "^2.3.0",
|
|
41
|
-
"@nx/devkit": "0.0.0-pr-
|
|
42
|
-
"@nx/js": "0.0.0-pr-
|
|
43
|
-
"@nx/eslint": "0.0.0-pr-
|
|
44
|
-
"@nx/web": "0.0.0-pr-
|
|
45
|
-
"@nx/module-federation": "0.0.0-pr-
|
|
41
|
+
"@nx/devkit": "0.0.0-pr-29464-73fdcbb",
|
|
42
|
+
"@nx/js": "0.0.0-pr-29464-73fdcbb",
|
|
43
|
+
"@nx/eslint": "0.0.0-pr-29464-73fdcbb",
|
|
44
|
+
"@nx/web": "0.0.0-pr-29464-73fdcbb",
|
|
45
|
+
"@nx/module-federation": "0.0.0-pr-29464-73fdcbb",
|
|
46
46
|
"express": "^4.21.2",
|
|
47
47
|
"http-proxy-middleware": "^3.0.3",
|
|
48
48
|
"semver": "^7.6.3"
|
|
@@ -57,7 +57,9 @@ function applyReactConfig(options, config = {}) {
|
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
function addHotReload(config) {
|
|
60
|
-
if (config.mode === 'development' &&
|
|
60
|
+
if (config.mode === 'development' &&
|
|
61
|
+
typeof config['devServer'] === 'object' &&
|
|
62
|
+
config['devServer']?.hot) {
|
|
61
63
|
// add `react-refresh/babel` to babel loader plugin
|
|
62
64
|
const babelLoader = config.module.rules.find((rule) => rule &&
|
|
63
65
|
typeof rule !== 'string' &&
|
|
@@ -46,25 +46,26 @@ async function applicationGeneratorInternal(tree, schema) {
|
|
|
46
46
|
});
|
|
47
47
|
tasks.push(jsInitTask);
|
|
48
48
|
const options = await (0, normalize_options_1.normalizeOptions)(tree, schema);
|
|
49
|
-
options.useReactRouter =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
49
|
+
options.useReactRouter =
|
|
50
|
+
options.routing && options.bundler === 'vite'
|
|
51
|
+
? options.useReactRouter ??
|
|
52
|
+
(await (0, prompt_1.promptWhenInteractive)({
|
|
53
|
+
name: 'response',
|
|
54
|
+
message: 'Would you like to use react-router for server-side rendering?',
|
|
55
|
+
type: 'autocomplete',
|
|
56
|
+
choices: [
|
|
57
|
+
{
|
|
58
|
+
name: 'Yes',
|
|
59
|
+
message: 'I want to use react-router [ https://reactrouter.com/start/framework/routing ]',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'No',
|
|
63
|
+
message: 'I do not want to use react-router for server-side rendering',
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
initial: 0,
|
|
67
|
+
}, { response: 'No' }).then((r) => r.response === 'Yes'))
|
|
68
|
+
: false;
|
|
68
69
|
(0, show_possible_warnings_1.showPossibleWarnings)(tree, options);
|
|
69
70
|
const initTask = await (0, init_1.default)(tree, {
|
|
70
71
|
...options,
|
|
@@ -167,7 +168,7 @@ async function applicationGeneratorInternal(tree, schema) {
|
|
|
167
168
|
moduleResolution: 'bundler',
|
|
168
169
|
}, options.linter === 'eslint'
|
|
169
170
|
? ['eslint.config.js', 'eslint.config.cjs', 'eslint.config.mjs']
|
|
170
|
-
: undefined);
|
|
171
|
+
: undefined, options.useReactRouter ? 'app' : 'src');
|
|
171
172
|
(0, sort_fields_1.sortPackageJsonFields)(tree, options.appProjectRoot);
|
|
172
173
|
if (!options.skipFormat) {
|
|
173
174
|
await (0, devkit_1.formatFiles)(tree);
|
|
@@ -27,6 +27,10 @@ async function addE2e(tree, options) {
|
|
|
27
27
|
const { getWebpackE2EWebServerInfo } = (0, devkit_1.ensurePackage)('@nx/webpack', versions_1.nxVersion);
|
|
28
28
|
e2eWebServerInfo = await getWebpackE2EWebServerInfo(tree, options.projectName, (0, devkit_1.joinPathFragments)(options.appProjectRoot, `webpack.config.${options.js ? 'js' : 'ts'}`), options.addPlugin, options.devServerPort ?? 4200);
|
|
29
29
|
}
|
|
30
|
+
else if (options.bundler === 'rspack') {
|
|
31
|
+
const { getRspackE2EWebServerInfo } = (0, devkit_1.ensurePackage)('@nx/rspack', versions_1.nxVersion);
|
|
32
|
+
e2eWebServerInfo = await getRspackE2EWebServerInfo(tree, options.projectName, (0, devkit_1.joinPathFragments)(options.appProjectRoot, `rspack.config.${options.js ? 'js' : 'ts'}`), options.addPlugin, options.devServerPort ?? 4200);
|
|
33
|
+
}
|
|
30
34
|
else if (options.bundler === 'vite') {
|
|
31
35
|
const { getViteE2EWebServerInfo, getReactRouterE2EWebServerInfo } = (0, devkit_1.ensurePackage)('@nx/vite', versions_1.nxVersion);
|
|
32
36
|
e2eWebServerInfo = options.useReactRouter
|
|
@@ -3,19 +3,43 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.addJest = addJest;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const versions_1 = require("../../../utils/versions");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
6
7
|
async function addJest(host, options) {
|
|
7
8
|
if (options.unitTestRunner === 'none') {
|
|
8
9
|
return () => { };
|
|
9
10
|
}
|
|
10
11
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/jest', versions_1.nxVersion);
|
|
11
|
-
|
|
12
|
+
await configurationGenerator(host, {
|
|
12
13
|
...options,
|
|
13
14
|
project: options.projectName,
|
|
14
15
|
supportTsx: true,
|
|
15
16
|
skipSerializers: true,
|
|
16
|
-
setupFile: 'none',
|
|
17
|
+
setupFile: options.useReactRouter ? 'react-router' : 'none',
|
|
17
18
|
compiler: options.compiler,
|
|
18
19
|
skipFormat: true,
|
|
19
20
|
runtimeTsconfigFileName: 'tsconfig.app.json',
|
|
20
21
|
});
|
|
22
|
+
if (options.useReactRouter) {
|
|
23
|
+
(0, devkit_1.updateJson)(host, (0, node_path_1.join)(options.appProjectRoot, 'tsconfig.spec.json'), (json) => {
|
|
24
|
+
json.include = json.include ?? [];
|
|
25
|
+
const reactRouterTestGlob = options.js
|
|
26
|
+
? [
|
|
27
|
+
'test/**/*.spec.jsx',
|
|
28
|
+
'test/**/*.spec.js',
|
|
29
|
+
'test/**/*.test.jsx',
|
|
30
|
+
'test/**/*.test.js',
|
|
31
|
+
]
|
|
32
|
+
: [
|
|
33
|
+
'test/**/*.spec.tsx',
|
|
34
|
+
'test/**/*.spec.ts',
|
|
35
|
+
'test/**/*.test.tsx',
|
|
36
|
+
'test/**/*.test.ts',
|
|
37
|
+
];
|
|
38
|
+
return {
|
|
39
|
+
...json,
|
|
40
|
+
include: Array.from(new Set([...json.include, ...reactRouterTestGlob])),
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return () => { };
|
|
21
45
|
}
|
|
@@ -1,3 +1,64 @@
|
|
|
1
1
|
import { Tree } from '@nx/devkit';
|
|
2
|
+
import { WithNxOptions } from '@nx/webpack';
|
|
3
|
+
import { WithReactOptions } from '../../../../plugins/with-react';
|
|
2
4
|
import { NormalizedSchema } from '../schema';
|
|
5
|
+
export declare function getDefaultTemplateVariables(host: Tree, options: NormalizedSchema): {
|
|
6
|
+
typesNodeVersion: string;
|
|
7
|
+
typesReactDomVersion: string;
|
|
8
|
+
reactRouterVersion: string;
|
|
9
|
+
typesReactVersion: string;
|
|
10
|
+
reactDomVersion: string;
|
|
11
|
+
reactVersion: string;
|
|
12
|
+
reactRouterIsBotVersion: string;
|
|
13
|
+
js: boolean;
|
|
14
|
+
tmpl: string;
|
|
15
|
+
offsetFromRoot: string;
|
|
16
|
+
appTests: string;
|
|
17
|
+
inSourceVitestTests: string;
|
|
18
|
+
style: "none" | "styled-components" | "@emotion/styled" | "styled-jsx" | "css" | "scss" | "less";
|
|
19
|
+
hasStyleFile: boolean;
|
|
20
|
+
isUsingTsSolutionSetup: boolean;
|
|
21
|
+
projectName: string;
|
|
22
|
+
appProjectRoot: string;
|
|
23
|
+
e2eProjectName: string;
|
|
24
|
+
e2eProjectRoot: string;
|
|
25
|
+
importPath: string;
|
|
26
|
+
parsedTags: string[];
|
|
27
|
+
fileName: string;
|
|
28
|
+
styledModule: null | import("../../../..").SupportedStyles;
|
|
29
|
+
hasStyles: boolean;
|
|
30
|
+
unitTestRunner: "jest" | "vitest" | "none";
|
|
31
|
+
addPlugin?: boolean;
|
|
32
|
+
names: ReturnType<typeof import("@nx/devkit").names>;
|
|
33
|
+
isUsingTsSolutionConfig?: boolean;
|
|
34
|
+
directory: string;
|
|
35
|
+
name: string;
|
|
36
|
+
skipFormat?: boolean;
|
|
37
|
+
tags?: string;
|
|
38
|
+
inSourceTests?: boolean;
|
|
39
|
+
e2eTestRunner: "cypress" | "playwright" | "none";
|
|
40
|
+
linter: import("@nx/eslint").Linter | import("@nx/eslint").LinterType;
|
|
41
|
+
classComponent?: boolean;
|
|
42
|
+
routing?: boolean;
|
|
43
|
+
useReactRouter?: boolean;
|
|
44
|
+
skipNxJson?: boolean;
|
|
45
|
+
globalCss?: boolean;
|
|
46
|
+
strict?: boolean;
|
|
47
|
+
setParserOptionsProject?: boolean;
|
|
48
|
+
compiler?: "babel" | "swc";
|
|
49
|
+
remotes?: string[];
|
|
50
|
+
devServerPort?: number;
|
|
51
|
+
skipPackageJson?: boolean;
|
|
52
|
+
rootProject?: boolean;
|
|
53
|
+
bundler?: "webpack" | "vite" | "rspack" | "rsbuild";
|
|
54
|
+
minimal?: boolean;
|
|
55
|
+
nxCloudToken?: string;
|
|
56
|
+
useTsSolution?: boolean;
|
|
57
|
+
formatter?: "prettier" | "none";
|
|
58
|
+
useProjectJson?: boolean;
|
|
59
|
+
className: string;
|
|
60
|
+
propertyName: string;
|
|
61
|
+
constantName: string;
|
|
62
|
+
};
|
|
63
|
+
export declare function createNxRspackPluginOptions(options: NormalizedSchema, rootOffset: string, tsx?: boolean): WithNxOptions & WithReactOptions;
|
|
3
64
|
export declare function createApplicationFiles(host: Tree, options: NormalizedSchema): Promise<void>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultTemplateVariables = getDefaultTemplateVariables;
|
|
4
|
+
exports.createNxRspackPluginOptions = createNxRspackPluginOptions;
|
|
3
5
|
exports.createApplicationFiles = createApplicationFiles;
|
|
4
6
|
const devkit_1 = require("@nx/devkit");
|
|
5
7
|
const js_1 = require("@nx/js");
|
|
@@ -13,6 +15,52 @@ const onboarding_1 = require("nx/src/nx-cloud/utilities/onboarding");
|
|
|
13
15
|
const has_rspack_plugin_1 = require("../../../utils/has-rspack-plugin");
|
|
14
16
|
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
|
|
15
17
|
const versions_1 = require("../../../utils/versions");
|
|
18
|
+
function getDefaultTemplateVariables(host, options) {
|
|
19
|
+
const hasStyleFile = ['scss', 'css', 'less'].includes(options.style);
|
|
20
|
+
const appTests = (0, get_app_tests_1.getAppTests)(options);
|
|
21
|
+
return {
|
|
22
|
+
...options.names,
|
|
23
|
+
...options,
|
|
24
|
+
typesNodeVersion: versions_1.typesNodeVersion,
|
|
25
|
+
typesReactDomVersion: versions_1.typesReactDomVersion,
|
|
26
|
+
reactRouterVersion: versions_1.reactRouterVersion,
|
|
27
|
+
typesReactVersion: versions_1.typesReactVersion,
|
|
28
|
+
reactDomVersion: versions_1.reactDomVersion,
|
|
29
|
+
reactVersion: versions_1.reactVersion,
|
|
30
|
+
reactRouterIsBotVersion: versions_1.reactRouterIsBotVersion,
|
|
31
|
+
js: !!options.js, // Ensure this is defined in template
|
|
32
|
+
tmpl: '',
|
|
33
|
+
offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.appProjectRoot),
|
|
34
|
+
appTests,
|
|
35
|
+
inSourceVitestTests: (0, get_in_source_vitest_tests_template_1.getInSourceVitestTestsTemplate)(appTests),
|
|
36
|
+
style: options.style === 'tailwind' ? 'css' : options.style,
|
|
37
|
+
hasStyleFile,
|
|
38
|
+
isUsingTsSolutionSetup: (0, ts_solution_setup_1.isUsingTsSolutionSetup)(host),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function createNxRspackPluginOptions(options, rootOffset, tsx = true) {
|
|
42
|
+
return {
|
|
43
|
+
target: 'web',
|
|
44
|
+
outputPath: options.isUsingTsSolutionConfig
|
|
45
|
+
? 'dist'
|
|
46
|
+
: (0, devkit_1.joinPathFragments)(rootOffset, 'dist', options.appProjectRoot != '.'
|
|
47
|
+
? options.appProjectRoot
|
|
48
|
+
: options.projectName),
|
|
49
|
+
index: './src/index.html',
|
|
50
|
+
baseHref: '/',
|
|
51
|
+
main: (0, maybe_js_1.maybeJs)({
|
|
52
|
+
js: options.js,
|
|
53
|
+
useJsx: true,
|
|
54
|
+
}, `./src/main.${tsx ? 'tsx' : 'ts'}`),
|
|
55
|
+
tsConfig: './tsconfig.app.json',
|
|
56
|
+
assets: ['./src/favicon.ico', './src/assets'],
|
|
57
|
+
styles: options.styledModule || !options.hasStyles
|
|
58
|
+
? []
|
|
59
|
+
: [
|
|
60
|
+
`./src/styles.${options.style !== 'tailwind' ? options.style : 'css'}`,
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
16
64
|
async function createApplicationFiles(host, options) {
|
|
17
65
|
let styleSolutionSpecificAppFiles;
|
|
18
66
|
if (options.styledModule && options.style !== 'styled-jsx') {
|
|
@@ -33,31 +81,11 @@ async function createApplicationFiles(host, options) {
|
|
|
33
81
|
else {
|
|
34
82
|
styleSolutionSpecificAppFiles = '../files/style-css-module';
|
|
35
83
|
}
|
|
36
|
-
const hasStyleFile = ['scss', 'css', 'less'].includes(options.style);
|
|
37
84
|
const onBoardingStatus = await (0, onboarding_1.createNxCloudOnboardingURLForWelcomeApp)(host, options.nxCloudToken);
|
|
38
85
|
const connectCloudUrl = onBoardingStatus === 'unclaimed' &&
|
|
39
86
|
(await (0, onboarding_1.getNxCloudAppOnBoardingUrl)(options.nxCloudToken));
|
|
40
87
|
const relativePathToRootTsConfig = (0, js_1.getRelativePathToRootTsConfig)(host, options.appProjectRoot);
|
|
41
|
-
const
|
|
42
|
-
const templateVariables = {
|
|
43
|
-
...options.names,
|
|
44
|
-
...options,
|
|
45
|
-
typesNodeVersion: versions_1.typesNodeVersion,
|
|
46
|
-
typesReactDomVersion: versions_1.typesReactDomVersion,
|
|
47
|
-
reactRouterVersion: versions_1.reactRouterVersion,
|
|
48
|
-
typesReactVersion: versions_1.typesReactVersion,
|
|
49
|
-
reactDomVersion: versions_1.reactDomVersion,
|
|
50
|
-
reactVersion: versions_1.reactVersion,
|
|
51
|
-
reactRouterIsBotVersion: versions_1.reactRouterIsBotVersion,
|
|
52
|
-
js: !!options.js, // Ensure this is defined in template
|
|
53
|
-
tmpl: '',
|
|
54
|
-
offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.appProjectRoot),
|
|
55
|
-
appTests,
|
|
56
|
-
inSourceVitestTests: (0, get_in_source_vitest_tests_template_1.getInSourceVitestTestsTemplate)(appTests),
|
|
57
|
-
style: options.style === 'tailwind' ? 'css' : options.style,
|
|
58
|
-
hasStyleFile,
|
|
59
|
-
isUsingTsSolutionSetup: (0, ts_solution_setup_1.isUsingTsSolutionSetup)(host),
|
|
60
|
-
};
|
|
88
|
+
const templateVariables = getDefaultTemplateVariables(host, options);
|
|
61
89
|
if (options.bundler === 'vite' && !options.useReactRouter) {
|
|
62
90
|
(0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, '../files/base-vite'), options.appProjectRoot, templateVariables);
|
|
63
91
|
}
|
|
@@ -185,29 +213,6 @@ function createNxWebpackPluginOptions(options, rootOffset) {
|
|
|
185
213
|
],
|
|
186
214
|
};
|
|
187
215
|
}
|
|
188
|
-
function createNxRspackPluginOptions(options, rootOffset) {
|
|
189
|
-
return {
|
|
190
|
-
target: 'web',
|
|
191
|
-
outputPath: options.isUsingTsSolutionConfig
|
|
192
|
-
? 'dist'
|
|
193
|
-
: (0, devkit_1.joinPathFragments)(rootOffset, 'dist', options.appProjectRoot != '.'
|
|
194
|
-
? options.appProjectRoot
|
|
195
|
-
: options.projectName),
|
|
196
|
-
index: './src/index.html',
|
|
197
|
-
baseHref: '/',
|
|
198
|
-
main: (0, maybe_js_1.maybeJs)({
|
|
199
|
-
js: options.js,
|
|
200
|
-
useJsx: true,
|
|
201
|
-
}, `./src/main.tsx`),
|
|
202
|
-
tsConfig: './tsconfig.app.json',
|
|
203
|
-
assets: ['./src/favicon.ico', './src/assets'],
|
|
204
|
-
styles: options.styledModule || !options.hasStyles
|
|
205
|
-
? []
|
|
206
|
-
: [
|
|
207
|
-
`./src/styles.${options.style !== 'tailwind' ? options.style : 'css'}`,
|
|
208
|
-
],
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
216
|
function generateReactRouterFiles(tree, options, templateVariables) {
|
|
212
217
|
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, '../files/react-router-ssr/common'), options.appProjectRoot, templateVariables);
|
|
213
218
|
if (options.rootProject) {
|
|
@@ -31,7 +31,10 @@ async function normalizeOptions(host, options) {
|
|
|
31
31
|
? null
|
|
32
32
|
: options.style;
|
|
33
33
|
(0, assertion_1.assertValidStyle)(options.style);
|
|
34
|
-
|
|
34
|
+
(0, assertion_1.assertValidReactRouter)(options.useReactRouter, options.bundler);
|
|
35
|
+
if (options.useReactRouter && !options.bundler) {
|
|
36
|
+
options.bundler = 'vite';
|
|
37
|
+
}
|
|
35
38
|
options.useReactRouter = options.routing ? options.useReactRouter : false;
|
|
36
39
|
const normalized = {
|
|
37
40
|
...options,
|
|
@@ -1,16 +1,40 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const {
|
|
1
|
+
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
|
2
|
+
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
|
3
|
+
const { NxModuleFederationPlugin, NxModuleFederationDevServerPlugin } = require('@nx/module-federation/rspack');
|
|
4
|
+
const { join } = require('path');
|
|
3
5
|
|
|
4
|
-
const
|
|
6
|
+
const config = require('./module-federation.config');
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
module.exports = {
|
|
9
|
+
output: {
|
|
10
|
+
path: join(__dirname, '<%= rspackPluginOptions.outputPath %>'),
|
|
11
|
+
publicPath: 'auto'
|
|
12
|
+
},
|
|
13
|
+
devServer: {
|
|
14
|
+
port: <%= devServerPort %>,
|
|
15
|
+
historyApiFallback: {
|
|
16
|
+
index: '/index.html',
|
|
17
|
+
disableDotRule: true,
|
|
18
|
+
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
plugins: [
|
|
22
|
+
new NxAppRspackPlugin({
|
|
23
|
+
tsConfig: '<%= rspackPluginOptions.tsConfig %>',
|
|
24
|
+
main: '<%= rspackPluginOptions.main %>',
|
|
25
|
+
index: '<%= rspackPluginOptions.index %>',
|
|
26
|
+
baseHref: '<%= rspackPluginOptions.baseHref %>',
|
|
27
|
+
assets: <%- JSON.stringify(rspackPluginOptions.assets) %>,
|
|
28
|
+
styles: <%- JSON.stringify(rspackPluginOptions.styles) %>,
|
|
29
|
+
outputHashing: process.env['NODE_ENV'] === 'production' ? 'all' : 'none',
|
|
30
|
+
optimization: process.env['NODE_ENV'] === 'production',
|
|
31
|
+
}),
|
|
32
|
+
new NxReactRspackPlugin({
|
|
33
|
+
// Uncomment this line if you don't want to use SVGR
|
|
34
|
+
// See: https://react-svgr.com/
|
|
35
|
+
// svgr: false
|
|
36
|
+
}),
|
|
37
|
+
new NxModuleFederationPlugin({ config }, { dts: false }),
|
|
38
|
+
new NxModuleFederationDevServerPlugin({ config }),
|
|
39
|
+
],
|
|
8
40
|
};
|
|
9
|
-
|
|
10
|
-
// Nx plugins for rspack to build config object from Nx options and context.
|
|
11
|
-
/**
|
|
12
|
-
* DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
|
|
13
|
-
* The DTS Plugin can be enabled by setting dts: true
|
|
14
|
-
* Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
|
|
15
|
-
*/
|
|
16
|
-
module.exports = composePlugins(withNx(), withReact(), withModuleFederation(config, { dts: false }));
|
|
@@ -1,38 +1,66 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const {
|
|
1
|
+
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
|
2
|
+
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
|
3
|
+
const { NxModuleFederationPlugin, NxModuleFederationDevServerPlugin } = require('@nx/module-federation/rspack');
|
|
4
|
+
const { join } = require('path');
|
|
3
5
|
|
|
4
6
|
const baseConfig = require('./module-federation.config');
|
|
5
7
|
|
|
6
8
|
const prodConfig = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
9
|
+
...baseConfig,
|
|
10
|
+
/*
|
|
11
|
+
* Remote overrides for production.
|
|
12
|
+
* Each entry is a pair of a unique name and the URL where it is deployed.
|
|
13
|
+
*
|
|
14
|
+
* e.g.
|
|
15
|
+
* remotes: [
|
|
16
|
+
* ['app1', 'http://app1.example.com'],
|
|
17
|
+
* ['app2', 'http://app2.example.com'],
|
|
18
|
+
* ]
|
|
19
|
+
*
|
|
20
|
+
* You can also use a full path to the remoteEntry.js file if desired.
|
|
21
|
+
*
|
|
22
|
+
* remotes: [
|
|
23
|
+
* ['app1', 'http://example.com/path/to/app1/remoteEntry.js'],
|
|
24
|
+
* ['app2', 'http://example.com/path/to/app2/remoteEntry.js'],
|
|
25
|
+
* ]
|
|
26
|
+
*/
|
|
27
|
+
remotes: [
|
|
28
|
+
<%_ remotes.forEach(function(r) { _%>
|
|
29
|
+
['<%= r.fileName %>', 'http://localhost:<%= r.port %>/'],
|
|
30
|
+
<%_ }); _%>
|
|
31
|
+
],
|
|
30
32
|
};
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
module.exports = {
|
|
35
|
+
output: {
|
|
36
|
+
path: join(__dirname, '<%= rspackPluginOptions.outputPath %>'),
|
|
37
|
+
publicPath: 'auto'
|
|
38
|
+
},
|
|
39
|
+
devServer: {
|
|
40
|
+
port: <%= devServerPort %>,
|
|
41
|
+
historyApiFallback: {
|
|
42
|
+
index: '/index.html',
|
|
43
|
+
disableDotRule: true,
|
|
44
|
+
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
plugins: [
|
|
48
|
+
new NxAppRspackPlugin({
|
|
49
|
+
tsConfig: '<%= rspackPluginOptions.tsConfig %>',
|
|
50
|
+
main: '<%= rspackPluginOptions.main %>',
|
|
51
|
+
index: '<%= rspackPluginOptions.index %>',
|
|
52
|
+
baseHref: '<%= rspackPluginOptions.baseHref %>',
|
|
53
|
+
assets: <%- JSON.stringify(rspackPluginOptions.assets) %>,
|
|
54
|
+
styles: <%- JSON.stringify(rspackPluginOptions.styles) %>,
|
|
55
|
+
outputHashing: process.env['NODE_ENV'] === 'production' ? 'all' : 'none',
|
|
56
|
+
optimization: process.env['NODE_ENV'] === 'production',
|
|
57
|
+
}),
|
|
58
|
+
new NxReactRspackPlugin({
|
|
59
|
+
// Uncomment this line if you don't want to use SVGR
|
|
60
|
+
// See: https://react-svgr.com/
|
|
61
|
+
// svgr: false
|
|
62
|
+
}),
|
|
63
|
+
new NxModuleFederationPlugin({ config: prodConfig }, { dts: false }),
|
|
64
|
+
new NxModuleFederationDevServerPlugin({ config: prodConfig }),
|
|
65
|
+
],
|
|
66
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
|
2
|
+
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
|
3
|
+
const { NxModuleFederationPlugin, NxModuleFederationSSRDevServerPlugin } = require('@nx/module-federation/rspack');
|
|
4
|
+
const { join } = require('path');
|
|
5
|
+
|
|
6
|
+
const browserMfConfig = require('./module-federation.config');
|
|
7
|
+
const serverMfConfig = require('./module-federation.server.config');
|
|
8
|
+
|
|
9
|
+
const browserRspackConfig = {
|
|
10
|
+
name: 'browser',
|
|
11
|
+
output: {
|
|
12
|
+
path: join(__dirname, '<%= rspackPluginOptions.outputPath %>', 'browser'),
|
|
13
|
+
publicPath: 'auto'
|
|
14
|
+
},
|
|
15
|
+
devServer: {
|
|
16
|
+
port: <%= devServerPort %>,
|
|
17
|
+
historyApiFallback: {
|
|
18
|
+
index: '/index.html',
|
|
19
|
+
disableDotRule: true,
|
|
20
|
+
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
|
|
21
|
+
},
|
|
22
|
+
devMiddleware: {
|
|
23
|
+
writeToDisk: (file: string) => !file.includes('.hot-update.'),
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
plugins: [
|
|
27
|
+
new NxAppRspackPlugin({
|
|
28
|
+
tsConfig: '<%= rspackPluginOptions.tsConfig %>',
|
|
29
|
+
main: '<%= rspackPluginOptions.main %>',
|
|
30
|
+
index: '<%= rspackPluginOptions.index %>',
|
|
31
|
+
baseHref: '<%= rspackPluginOptions.baseHref %>',
|
|
32
|
+
assets: <%- JSON.stringify(rspackPluginOptions.assets) %>,
|
|
33
|
+
styles: <%- JSON.stringify(rspackPluginOptions.styles) %>,
|
|
34
|
+
outputHashing: process.env['NODE_ENV'] === 'production' ? 'all' : 'none',
|
|
35
|
+
optimization: process.env['NODE_ENV'] === 'production',
|
|
36
|
+
}),
|
|
37
|
+
new NxReactRspackPlugin({
|
|
38
|
+
// Uncomment this line if you don't want to use SVGR
|
|
39
|
+
// See: https://react-svgr.com/
|
|
40
|
+
// svgr: false
|
|
41
|
+
}),
|
|
42
|
+
new NxModuleFederationPlugin({ config: browserMfConfig }, { dts: false }),
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const serverRspackConfig = {
|
|
47
|
+
name: 'server',
|
|
48
|
+
target: 'async-node',
|
|
49
|
+
output: {
|
|
50
|
+
path: join(__dirname, '<%= rspackPluginOptions.outputPath %>', 'server'),
|
|
51
|
+
filename: 'server.js'
|
|
52
|
+
},
|
|
53
|
+
plugins: [
|
|
54
|
+
new NxAppRspackPlugin({
|
|
55
|
+
outputPath: join(__dirname, '<%= rspackPluginOptions.outputPath %>', 'server'),
|
|
56
|
+
outputFileName: 'server.js',
|
|
57
|
+
tsConfig: '<%= rspackPluginOptions.tsConfig %>',
|
|
58
|
+
main: '<%= rspackPluginOptions.mainServer %>',
|
|
59
|
+
baseHref: '<%= rspackPluginOptions.baseHref %>',
|
|
60
|
+
}),
|
|
61
|
+
new NxModuleFederationPlugin({ config: serverMfConfig, isServer: true }, { dts: false }),
|
|
62
|
+
new NxModuleFederationSSRDevServerPlugin({ config: serverMfConfig }),
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
module.exports = [browserRspackConfig, serverRspackConfig];
|
|
@@ -7,7 +7,7 @@ import { handleRequest } from './src/main.server';
|
|
|
7
7
|
const port = process.env['PORT'] || <%= port %>;
|
|
8
8
|
const app = express();
|
|
9
9
|
|
|
10
|
-
const browserDist = path.join(process.cwd(), '<%=
|
|
10
|
+
const browserDist = path.join(process.cwd(), '<%= rspackPluginOptions.outputPath %>', 'browser');
|
|
11
11
|
const indexPath = path.join(browserDist, 'index.html');
|
|
12
12
|
|
|
13
13
|
app.use(cors());
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as ReactDOMServer from 'react-dom/server';
|
|
4
|
+
import isbot from 'isbot'
|
|
5
|
+
|
|
6
|
+
import App from './app/app';
|
|
7
|
+
|
|
8
|
+
import { StaticRouter } from 'react-router-dom/server';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
let indexHtml: null | string = null;
|
|
12
|
+
|
|
13
|
+
export function handleRequest(indexPath: string) {
|
|
14
|
+
return function render(req: Request, res: Response) {
|
|
15
|
+
let didError = false;
|
|
16
|
+
|
|
17
|
+
if (!indexHtml) {
|
|
18
|
+
indexHtml = fs.readFileSync(indexPath).toString();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const [htmlStart, htmlEnd] = indexHtml.split(`<div id="root"></div>`);
|
|
22
|
+
|
|
23
|
+
// For bots (e.g. search engines), the content will not be streamed but render all at once.
|
|
24
|
+
// For users, content should be streamed to the user as they are ready.
|
|
25
|
+
const callbackName = isbot(req.headers['user-agent']) ? 'onAllReady' : 'onShellReady';
|
|
26
|
+
|
|
27
|
+
const stream = ReactDOMServer.renderToPipeableStream(
|
|
28
|
+
<StaticRouter location={req.originalUrl}><App /></StaticRouter>,
|
|
29
|
+
{
|
|
30
|
+
[callbackName]() {
|
|
31
|
+
res.statusCode = didError ? 500 : 200;
|
|
32
|
+
res.setHeader('Content-type', 'text/html; charset=utf-8');
|
|
33
|
+
res.write(`${htmlStart}<div id="root">`);
|
|
34
|
+
stream.pipe(res);
|
|
35
|
+
res.write(`</div>${htmlEnd}`);
|
|
36
|
+
},
|
|
37
|
+
onShellError(error) {
|
|
38
|
+
console.error(error);
|
|
39
|
+
res.statusCode = 500;
|
|
40
|
+
res.send('<!doctype html><h1>Server Error</h1>');
|
|
41
|
+
},
|
|
42
|
+
onError(error) {
|
|
43
|
+
didError = true;
|
|
44
|
+
console.error(error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|