@nx/react 17.0.3 → 17.0.5
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/LICENSE +1 -1
- package/README.md +9 -4
- package/generators.json +1 -1
- package/index.d.ts +1 -0
- package/index.js +3 -1
- package/mf/dynamic-federation.d.ts +4 -0
- package/mf/dynamic-federation.js +75 -0
- package/mf/index.d.ts +1 -0
- package/mf/index.js +7 -0
- package/migrations.json +21 -0
- package/package.json +7 -7
- package/plugins/component-testing/index.js +52 -24
- package/plugins/component-testing/webpack-fallback.js +1 -1
- package/plugins/nx-react-webpack-plugin/lib/apply-react-config.d.ts +4 -0
- package/plugins/nx-react-webpack-plugin/lib/apply-react-config.js +86 -0
- package/plugins/nx-react-webpack-plugin/nx-react-webpack-plugin.d.ts +8 -0
- package/plugins/nx-react-webpack-plugin/nx-react-webpack-plugin.js +13 -0
- package/plugins/storybook/index.js +6 -2
- package/plugins/storybook/merge-plugins.d.ts +1 -1
- package/plugins/webpack.d.ts +1 -3
- package/plugins/webpack.js +3 -11
- package/plugins/with-react.d.ts +2 -4
- package/plugins/with-react.js +2 -58
- package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.d.ts +13 -0
- package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.js +173 -58
- package/src/executors/module-federation-dev-server/schema.json +13 -1
- package/src/generators/application/application.js +41 -18
- package/src/generators/application/files/base-vite/index.html__tmpl__ +1 -1
- package/src/generators/application/files/base-webpack/src/index.html +0 -2
- package/src/generators/application/files/base-webpack/webpack.config.js__tmpl__ +46 -5
- package/src/generators/application/files/nx-welcome/src/app/nx-welcome.tsx +54 -13
- package/src/generators/application/files/style-tailwind/src/app/__fileName__.tsx__tmpl__ +33 -0
- package/src/generators/application/files/style-tailwind/src/styles.css +1 -0
- package/src/generators/application/lib/add-e2e.js +25 -7
- package/src/generators/application/lib/add-jest.js +2 -2
- package/src/generators/application/lib/add-project.d.ts +2 -2
- package/src/generators/application/lib/add-project.js +12 -15
- package/src/generators/application/lib/add-routing.d.ts +1 -1
- package/src/generators/application/lib/add-routing.js +4 -8
- package/src/generators/application/lib/create-application-files.js +30 -1
- package/src/generators/application/lib/install-common-dependencies.js +15 -1
- package/src/generators/application/lib/normalize-options.js +35 -1
- package/src/generators/application/lib/set-defaults.js +1 -0
- package/src/generators/application/lib/update-jest-config.js +8 -8
- package/src/generators/application/schema.d.ts +5 -0
- package/src/generators/application/schema.json +7 -3
- package/src/generators/component/files/__fileName__.tsx__tmpl__ +39 -22
- package/src/generators/component/lib/normalize-options.js +4 -2
- package/src/generators/component/schema.d.ts +6 -4
- package/src/generators/component/schema.json +7 -7
- package/src/generators/component-cypress-spec/schema.json +1 -1
- package/src/generators/component-story/schema.json +1 -1
- package/src/generators/component-test/schema.json +1 -1
- package/src/generators/cypress-component-configuration/cypress-component-configuration.d.ts +2 -1
- package/src/generators/cypress-component-configuration/cypress-component-configuration.js +18 -7
- package/src/generators/cypress-component-configuration/lib/add-files.js +1 -6
- package/src/generators/cypress-component-configuration/schema.d.ts +1 -0
- package/src/generators/federate-module/federate-module.js +2 -2
- package/src/generators/federate-module/schema.d.ts +1 -1
- package/src/generators/federate-module/schema.json +4 -3
- package/src/generators/hook/files/__fileName__.ts__tmpl__ +15 -15
- package/src/generators/hook/schema.d.ts +4 -4
- package/src/generators/hook/schema.json +5 -5
- package/src/generators/host/files/common/src/main.js__tmpl__ +10 -0
- package/src/generators/host/files/common/tsconfig.lint.json__tmpl__ +19 -0
- package/src/generators/host/files/common-ts/src/app/__fileName__.tsx__tmpl__ +41 -0
- package/src/generators/host/files/common-ts/src/main.ts__tmpl__ +10 -0
- package/src/generators/host/files/module-federation/module-federation.config.js__tmpl__ +17 -2
- package/src/generators/host/files/module-federation-ssr/module-federation.server.config.js__tmpl__ +5 -2
- package/src/generators/host/files/module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +5 -2
- package/src/generators/host/files/module-federation-ts/module-federation.config.ts__tmpl__ +17 -2
- package/src/generators/host/files/module-federation-ts/webpack.config.prod.ts__tmpl__ +2 -1
- package/src/generators/host/files/module-federation-ts/webpack.config.ts__tmpl__ +2 -2
- package/src/generators/host/host.js +15 -1
- package/src/generators/host/lib/add-module-federation-files.d.ts +2 -1
- package/src/generators/host/lib/add-module-federation-files.js +24 -11
- package/src/generators/host/lib/setup-ssr-for-host.js +1 -0
- package/src/generators/host/lib/update-module-federation-e2e-project.js +7 -5
- package/src/generators/host/schema.d.ts +5 -2
- package/src/generators/host/schema.json +16 -6
- package/src/generators/init/init.d.ts +1 -1
- package/src/generators/init/init.js +10 -49
- package/src/generators/init/schema.d.ts +1 -6
- package/src/generators/init/schema.json +5 -22
- package/src/generators/library/lib/add-linting.js +2 -2
- package/src/generators/library/lib/add-rollup-build-target.d.ts +2 -1
- package/src/generators/library/lib/add-rollup-build-target.js +16 -8
- package/src/generators/library/lib/install-common-dependencies.js +13 -5
- package/src/generators/library/lib/normalize-options.js +34 -5
- package/src/generators/library/lib/update-app-routes.js +1 -1
- package/src/generators/library/library.js +17 -6
- package/src/generators/library/schema.d.ts +1 -0
- package/src/generators/library/schema.json +3 -3
- package/src/generators/redux/schema.d.ts +1 -1
- package/src/generators/redux/schema.json +2 -2
- package/src/generators/remote/files/module-federation/module-federation.config.js__tmpl__ +4 -1
- package/src/generators/remote/files/module-federation-ssr/module-federation.server.config.js__tmpl__ +1 -1
- package/src/generators/remote/files/module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +1 -1
- package/src/generators/remote/files/module-federation-ssr-ts/tsconfig.lint.json__tmpl__ +19 -0
- package/src/generators/remote/files/module-federation-ts/module-federation.config.ts__tmpl__ +4 -1
- package/src/generators/remote/files/module-federation-ts/tsconfig.lint.json__tmpl__ +19 -0
- package/src/generators/remote/lib/add-remote-to-dynamic-host.d.ts +2 -0
- package/src/generators/remote/lib/add-remote-to-dynamic-host.js +11 -0
- package/src/generators/remote/lib/setup-ssr-for-remote.js +5 -1
- package/src/generators/remote/lib/setup-tspath-for-remote.js +2 -1
- package/src/generators/remote/lib/update-host-with-remote.js +10 -1
- package/src/generators/remote/remote.js +22 -2
- package/src/generators/remote/schema.d.ts +3 -2
- package/src/generators/remote/schema.json +17 -6
- package/src/generators/setup-ssr/schema.json +1 -1
- package/src/generators/setup-ssr/setup-ssr.js +23 -7
- package/src/generators/setup-tailwind/schema.json +1 -1
- package/src/generators/stories/schema.json +1 -1
- package/src/generators/stories/stories.js +17 -5
- package/src/generators/storybook-configuration/configuration.d.ts +2 -0
- package/src/generators/storybook-configuration/configuration.js +37 -15
- package/src/generators/storybook-configuration/schema.d.ts +2 -1
- package/src/generators/storybook-configuration/schema.json +7 -7
- package/src/migrations/update-18-0-0/add-mf-env-var-to-target-defaults.d.ts +2 -0
- package/src/migrations/update-18-0-0/add-mf-env-var-to-target-defaults.js +26 -0
- package/src/migrations/update-18-1-1/fix-target-defaults-inputs.d.ts +2 -0
- package/src/migrations/update-18-1-1/fix-target-defaults-inputs.js +53 -0
- package/src/module-federation/ast-utils.js +1 -1
- package/src/module-federation/utils.js +8 -1
- package/src/module-federation/with-module-federation-ssr.js +3 -0
- package/src/module-federation/with-module-federation.d.ts +3 -3
- package/src/module-federation/with-module-federation.js +14 -4
- package/src/rules/update-module-federation-project.d.ts +2 -0
- package/src/rules/update-module-federation-project.js +12 -3
- package/src/utils/add-mf-env-to-inputs.d.ts +2 -0
- package/src/utils/add-mf-env-to-inputs.js +27 -0
- package/src/utils/assertion.js +1 -0
- package/src/utils/ct-utils.d.ts +6 -1
- package/src/utils/ct-utils.js +39 -9
- package/src/utils/get-in-source-vitest-tests-template.js +1 -1
- package/src/utils/has-vite-plugin.d.ts +2 -0
- package/src/utils/has-vite-plugin.js +11 -0
- package/src/utils/has-webpack-plugin.d.ts +2 -0
- package/src/utils/has-webpack-plugin.js +11 -0
- package/src/utils/maybe-js.d.ts +3 -0
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js +1 -1
- package/typings/style.d.ts +1 -0
- package/src/generators/application/files/base-webpack/src/environments/environment.prod.ts__tmpl__ +0 -3
- package/src/generators/application/files/base-webpack/src/environments/environment.ts__tmpl__ +0 -6
- package/src/generators/host/files/module-federation/src/main.ts__tmpl__ +0 -1
- package/src/generators/host/files/module-federation-ts/src/main.ts__tmpl__ +0 -1
- package/src/generators/library/lib/maybe-js.d.ts +0 -2
- /package/src/generators/host/files/common/src/app/{__fileName__.tsx__tmpl__ → __fileName__.js__tmpl__} +0 -0
- /package/src/generators/remote/files/{module-federation/src/main.ts__tmpl__ → common/src/main.js__tmpl__} +0 -0
- /package/src/generators/remote/files/{module-federation/src/remote-entry.ts__tmpl__ → common/src/remote-entry.js__tmpl__} +0 -0
- /package/src/generators/remote/files/{module-federation-ts → common-ts}/src/main.ts__tmpl__ +0 -0
- /package/src/generators/remote/files/{module-federation-ts → common-ts}/src/remote-entry.ts__tmpl__ +0 -0
- /package/src/{generators/library/lib → utils}/maybe-js.js +0 -0
|
@@ -5,7 +5,20 @@ type ModuleFederationDevServerOptions = WebDevServerOptions & {
|
|
|
5
5
|
skipRemotes?: string[];
|
|
6
6
|
static?: boolean;
|
|
7
7
|
isInitialHost?: boolean;
|
|
8
|
+
parallel?: number;
|
|
9
|
+
staticRemotesPort?: number;
|
|
10
|
+
pathToManifestFile?: string;
|
|
8
11
|
};
|
|
12
|
+
type StaticRemoteConfig = {
|
|
13
|
+
basePath: string;
|
|
14
|
+
outputPath: string;
|
|
15
|
+
urlSegment: string;
|
|
16
|
+
};
|
|
17
|
+
type StaticRemotesConfig = {
|
|
18
|
+
remotes: string[];
|
|
19
|
+
config: Record<string, StaticRemoteConfig> | undefined;
|
|
20
|
+
};
|
|
21
|
+
export declare function parseStaticRemotesConfig(staticRemotes: string[] | undefined, context: ExecutorContext): StaticRemotesConfig;
|
|
9
22
|
export default function moduleFederationDevServer(options: ModuleFederationDevServerOptions, context: ExecutorContext): AsyncIterableIterator<{
|
|
10
23
|
success: boolean;
|
|
11
24
|
baseUrl?: string;
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStaticRemotesConfig = void 0;
|
|
3
4
|
const devkit_1 = require("@nx/devkit");
|
|
4
5
|
const dev_server_impl_1 = require("@nx/webpack/src/executors/dev-server/dev-server.impl");
|
|
5
6
|
const file_server_impl_1 = require("@nx/web/src/executors/file-server/file-server.impl");
|
|
6
7
|
const module_federation_1 = require("@nx/webpack/src/utils/module-federation");
|
|
7
8
|
const async_iterable_1 = require("@nx/devkit/src/utils/async-iterable");
|
|
8
9
|
const wait_for_port_open_1 = require("@nx/web/src/utils/wait-for-port-open");
|
|
9
|
-
const
|
|
10
|
+
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
11
|
+
const node_child_process_1 = require("node:child_process");
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
const node_fs_1 = require("node:fs");
|
|
14
|
+
const fs_1 = require("fs");
|
|
15
|
+
const path_1 = require("path");
|
|
10
16
|
function getBuildOptions(buildTarget, context) {
|
|
11
17
|
const target = (0, devkit_1.parseTargetString)(buildTarget, context);
|
|
12
18
|
const buildOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
@@ -14,7 +20,133 @@ function getBuildOptions(buildTarget, context) {
|
|
|
14
20
|
...buildOptions,
|
|
15
21
|
};
|
|
16
22
|
}
|
|
23
|
+
function startStaticRemotesFileServer(staticRemotesConfig, context, options) {
|
|
24
|
+
let shouldMoveToCommonLocation = false;
|
|
25
|
+
let commonOutputDirectory;
|
|
26
|
+
for (const app of staticRemotesConfig.remotes) {
|
|
27
|
+
const remoteBasePath = staticRemotesConfig.config[app].basePath;
|
|
28
|
+
if (!commonOutputDirectory) {
|
|
29
|
+
commonOutputDirectory = remoteBasePath;
|
|
30
|
+
}
|
|
31
|
+
else if (commonOutputDirectory !== remoteBasePath) {
|
|
32
|
+
shouldMoveToCommonLocation = true;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (shouldMoveToCommonLocation) {
|
|
37
|
+
commonOutputDirectory = (0, node_path_1.join)(devkit_1.workspaceRoot, 'tmp/static-remotes');
|
|
38
|
+
for (const app of staticRemotesConfig.remotes) {
|
|
39
|
+
const remoteConfig = staticRemotesConfig.config[app];
|
|
40
|
+
(0, node_fs_1.cpSync)(remoteConfig.outputPath, (0, node_path_1.join)(commonOutputDirectory, remoteConfig.urlSegment), {
|
|
41
|
+
force: true,
|
|
42
|
+
recursive: true,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const staticRemotesIter = (0, file_server_impl_1.default)({
|
|
47
|
+
cors: true,
|
|
48
|
+
watch: false,
|
|
49
|
+
staticFilePath: commonOutputDirectory,
|
|
50
|
+
parallel: false,
|
|
51
|
+
spa: false,
|
|
52
|
+
withDeps: false,
|
|
53
|
+
host: options.host,
|
|
54
|
+
port: options.staticRemotesPort,
|
|
55
|
+
ssl: options.ssl,
|
|
56
|
+
sslCert: options.sslCert,
|
|
57
|
+
sslKey: options.sslKey,
|
|
58
|
+
}, context);
|
|
59
|
+
return staticRemotesIter;
|
|
60
|
+
}
|
|
61
|
+
async function startRemotes(remotes, context, options, target = 'serve') {
|
|
62
|
+
const remoteIters = [];
|
|
63
|
+
for (const app of remotes) {
|
|
64
|
+
const remoteProjectServeTarget = context.projectGraph.nodes[app].data.targets[target];
|
|
65
|
+
const isUsingModuleFederationDevServerExecutor = remoteProjectServeTarget.executor.includes('module-federation-dev-server');
|
|
66
|
+
const overrides = target === 'serve'
|
|
67
|
+
? {
|
|
68
|
+
watch: true,
|
|
69
|
+
...(options.host ? { host: options.host } : {}),
|
|
70
|
+
...(options.ssl ? { ssl: options.ssl } : {}),
|
|
71
|
+
...(options.sslCert ? { sslCert: options.sslCert } : {}),
|
|
72
|
+
...(options.sslKey ? { sslKey: options.sslKey } : {}),
|
|
73
|
+
...(isUsingModuleFederationDevServerExecutor
|
|
74
|
+
? { isInitialHost: false }
|
|
75
|
+
: {}),
|
|
76
|
+
}
|
|
77
|
+
: {};
|
|
78
|
+
remoteIters.push(await (0, devkit_1.runExecutor)({
|
|
79
|
+
project: app,
|
|
80
|
+
target,
|
|
81
|
+
configuration: context.configurationName,
|
|
82
|
+
}, overrides, context));
|
|
83
|
+
}
|
|
84
|
+
return remoteIters;
|
|
85
|
+
}
|
|
86
|
+
async function buildStaticRemotes(staticRemotesConfig, nxBin, context, options) {
|
|
87
|
+
if (!staticRemotesConfig.remotes.length) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
devkit_1.logger.info(`NX Building ${staticRemotesConfig.remotes.length} static remotes...`);
|
|
91
|
+
const mappedLocationOfRemotes = {};
|
|
92
|
+
for (const app of staticRemotesConfig.remotes) {
|
|
93
|
+
mappedLocationOfRemotes[app] = `http${options.ssl ? 's' : ''}://${options.host}:${options.staticRemotesPort}/${staticRemotesConfig.config[app].urlSegment}`;
|
|
94
|
+
}
|
|
95
|
+
process.env.NX_MF_DEV_SERVER_STATIC_REMOTES = JSON.stringify(mappedLocationOfRemotes);
|
|
96
|
+
await new Promise((res) => {
|
|
97
|
+
const staticProcess = (0, node_child_process_1.fork)(nxBin, [
|
|
98
|
+
'run-many',
|
|
99
|
+
`--target=build`,
|
|
100
|
+
`--projects=${staticRemotesConfig.remotes.join(',')}`,
|
|
101
|
+
...(context.configurationName
|
|
102
|
+
? [`--configuration=${context.configurationName}`]
|
|
103
|
+
: []),
|
|
104
|
+
...(options.parallel ? [`--parallel=${options.parallel}`] : []),
|
|
105
|
+
], {
|
|
106
|
+
cwd: context.root,
|
|
107
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
108
|
+
});
|
|
109
|
+
// File to debug build failures e.g. 2024-01-01T00_00_0_0Z-build.log'
|
|
110
|
+
const remoteBuildLogFile = (0, node_path_1.join)(cache_directory_1.projectGraphCacheDirectory, `${new Date().toISOString().replace(/[:\.]/g, '_')}-build.log`);
|
|
111
|
+
const stdoutStream = (0, node_fs_1.createWriteStream)(remoteBuildLogFile);
|
|
112
|
+
staticProcess.stdout.on('data', (data) => {
|
|
113
|
+
const ANSII_CODE_REGEX = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
|
114
|
+
const stdoutString = data.toString().replace(ANSII_CODE_REGEX, '');
|
|
115
|
+
stdoutStream.write(stdoutString);
|
|
116
|
+
if (stdoutString.includes('Successfully ran target build')) {
|
|
117
|
+
staticProcess.stdout.removeAllListeners('data');
|
|
118
|
+
devkit_1.logger.info(`NX Built ${staticRemotesConfig.remotes.length} static remotes`);
|
|
119
|
+
res();
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
staticProcess.stderr.on('data', (data) => devkit_1.logger.info(data.toString()));
|
|
123
|
+
staticProcess.on('exit', (code) => {
|
|
124
|
+
stdoutStream.end();
|
|
125
|
+
if (code !== 0) {
|
|
126
|
+
throw new Error(`Remote failed to start. A complete log can be found in: ${remoteBuildLogFile}`);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
process.on('SIGTERM', () => staticProcess.kill('SIGTERM'));
|
|
130
|
+
process.on('exit', () => staticProcess.kill('SIGTERM'));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function parseStaticRemotesConfig(staticRemotes, context) {
|
|
134
|
+
if (!staticRemotes?.length) {
|
|
135
|
+
return { remotes: [], config: undefined };
|
|
136
|
+
}
|
|
137
|
+
const config = {};
|
|
138
|
+
for (const app of staticRemotes) {
|
|
139
|
+
const outputPath = context.projectGraph.nodes[app].data.targets['build'].options.outputPath;
|
|
140
|
+
const basePath = (0, node_path_1.dirname)(outputPath);
|
|
141
|
+
const urlSegment = (0, node_path_1.basename)(outputPath);
|
|
142
|
+
config[app] = { basePath, outputPath, urlSegment };
|
|
143
|
+
}
|
|
144
|
+
return { remotes: staticRemotes, config };
|
|
145
|
+
}
|
|
146
|
+
exports.parseStaticRemotesConfig = parseStaticRemotesConfig;
|
|
17
147
|
async function* moduleFederationDevServer(options, context) {
|
|
148
|
+
const initialStaticRemotesPorts = options.staticRemotesPort;
|
|
149
|
+
options.staticRemotesPort ??= options.port + 1;
|
|
18
150
|
// Force Node to resolve to look for the nx binary that is inside node_modules
|
|
19
151
|
const nxBin = require.resolve('nx/bin/nx');
|
|
20
152
|
const currIter = options.static
|
|
@@ -28,6 +160,17 @@ async function* moduleFederationDevServer(options, context) {
|
|
|
28
160
|
: (0, dev_server_impl_1.default)(options, context);
|
|
29
161
|
const p = context.projectsConfigurations.projects[context.projectName];
|
|
30
162
|
const buildOptions = getBuildOptions(options.buildTarget, context);
|
|
163
|
+
let pathToManifestFile = (0, node_path_1.join)(context.root, p.sourceRoot, 'assets/module-federation.manifest.json');
|
|
164
|
+
if (options.pathToManifestFile) {
|
|
165
|
+
const userPathToManifestFile = (0, node_path_1.join)(context.root, options.pathToManifestFile);
|
|
166
|
+
if (!(0, fs_1.existsSync)(userPathToManifestFile)) {
|
|
167
|
+
throw new Error(`The provided Module Federation manifest file path does not exist. Please check the file exists at "${userPathToManifestFile}".`);
|
|
168
|
+
}
|
|
169
|
+
else if ((0, path_1.extname)(options.pathToManifestFile) !== '.json') {
|
|
170
|
+
throw new Error(`The Module Federation manifest file must be a JSON. Please ensure the file at ${userPathToManifestFile} is a JSON.`);
|
|
171
|
+
}
|
|
172
|
+
pathToManifestFile = userPathToManifestFile;
|
|
173
|
+
}
|
|
31
174
|
if (!options.isInitialHost) {
|
|
32
175
|
return yield* currIter;
|
|
33
176
|
}
|
|
@@ -36,57 +179,26 @@ async function* moduleFederationDevServer(options, context) {
|
|
|
36
179
|
projectName: context.projectName,
|
|
37
180
|
projectGraph: context.projectGraph,
|
|
38
181
|
root: context.root,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
devRemoteIters.push(await (0, devkit_1.runExecutor)({
|
|
46
|
-
project: app,
|
|
47
|
-
target: 'serve',
|
|
48
|
-
configuration: context.configurationName,
|
|
49
|
-
}, {
|
|
50
|
-
watch: true,
|
|
51
|
-
...(isUsingModuleFederationDevServerExecutor
|
|
52
|
-
? { isInitialHost: false }
|
|
53
|
-
: {}),
|
|
54
|
-
}, context));
|
|
55
|
-
}
|
|
56
|
-
for (const app of remotes.staticRemotes) {
|
|
57
|
-
const remoteProjectServeTarget = context.projectGraph.nodes[app].data.targets['serve-static'];
|
|
58
|
-
const isUsingModuleFederationDevServerExecutor = remoteProjectServeTarget.executor.includes('module-federation-dev-server');
|
|
59
|
-
let outWithErr = [];
|
|
60
|
-
const staticProcess = (0, child_process_1.fork)(nxBin, [
|
|
61
|
-
'run',
|
|
62
|
-
`${app}:serve-static${context.configurationName ? `:${context.configurationName}` : ''}`,
|
|
63
|
-
...(isUsingModuleFederationDevServerExecutor
|
|
64
|
-
? [`--isInitialHost=false`]
|
|
65
|
-
: []),
|
|
66
|
-
], {
|
|
67
|
-
cwd: context.root,
|
|
68
|
-
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
69
|
-
});
|
|
70
|
-
staticProcess.stdout.on('data', (data) => {
|
|
71
|
-
if (isCollectingStaticRemoteOutput) {
|
|
72
|
-
outWithErr.push(data.toString());
|
|
182
|
+
}, pathToManifestFile);
|
|
183
|
+
if (remotes.devRemotes.length > 0 && !initialStaticRemotesPorts) {
|
|
184
|
+
options.staticRemotesPort = options.devRemotes.reduce((portToUse, r) => {
|
|
185
|
+
const remotePort = context.projectGraph.nodes[r].data.targets['serve'].options.port;
|
|
186
|
+
if (remotePort >= portToUse) {
|
|
187
|
+
return remotePort + 1;
|
|
73
188
|
}
|
|
74
189
|
else {
|
|
75
|
-
|
|
76
|
-
staticProcess.stdout.removeAllListeners('data');
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
staticProcess.stderr.on('data', (data) => devkit_1.logger.info(data.toString()));
|
|
80
|
-
staticProcess.on('exit', (code) => {
|
|
81
|
-
if (code !== 0) {
|
|
82
|
-
devkit_1.logger.info(outWithErr.join(''));
|
|
83
|
-
throw new Error(`Remote failed to start. See above for errors.`);
|
|
190
|
+
return portToUse;
|
|
84
191
|
}
|
|
85
|
-
});
|
|
86
|
-
process.on('SIGTERM', () => staticProcess.kill('SIGTERM'));
|
|
87
|
-
process.on('exit', () => staticProcess.kill('SIGTERM'));
|
|
192
|
+
}, options.staticRemotesPort);
|
|
88
193
|
}
|
|
89
|
-
|
|
194
|
+
const staticRemotesConfig = parseStaticRemotesConfig(remotes.staticRemotes, context);
|
|
195
|
+
await buildStaticRemotes(staticRemotesConfig, nxBin, context, options);
|
|
196
|
+
const devRemoteIters = await startRemotes(remotes.devRemotes, context, options, 'serve');
|
|
197
|
+
const dynamicRemotesIters = await startRemotes(remotes.dynamicRemotes, context, options, 'serve-static');
|
|
198
|
+
const staticRemotesIter = remotes.staticRemotes.length > 0
|
|
199
|
+
? startStaticRemotesFileServer(staticRemotesConfig, context, options)
|
|
200
|
+
: undefined;
|
|
201
|
+
return yield* (0, async_iterable_1.combineAsyncIterables)(currIter, ...devRemoteIters, ...dynamicRemotesIters, ...(staticRemotesIter ? [staticRemotesIter] : []), (0, async_iterable_1.createAsyncIterable)(async ({ next, done }) => {
|
|
90
202
|
if (!options.isInitialHost) {
|
|
91
203
|
done();
|
|
92
204
|
return;
|
|
@@ -96,20 +208,23 @@ async function* moduleFederationDevServer(options, context) {
|
|
|
96
208
|
return;
|
|
97
209
|
}
|
|
98
210
|
try {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
211
|
+
const host = options.host ?? 'localhost';
|
|
212
|
+
const baseUrl = `http${options.ssl ? 's' : ''}://${host}:${options.port}`;
|
|
213
|
+
const portsToWaitFor = staticRemotesIter
|
|
214
|
+
? [options.staticRemotesPort, ...remotes.remotePorts]
|
|
215
|
+
: [...remotes.remotePorts];
|
|
216
|
+
await Promise.all(portsToWaitFor.map((port) => (0, wait_for_port_open_1.waitForPortOpen)(port, {
|
|
103
217
|
retries: 480,
|
|
104
218
|
retryDelay: 2500,
|
|
105
|
-
host:
|
|
219
|
+
host: host,
|
|
106
220
|
})));
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
next({ success: true, baseUrl: `http://localhost:${options.port}` });
|
|
221
|
+
devkit_1.logger.info(`NX All remotes started, server ready at ${baseUrl}`);
|
|
222
|
+
next({ success: true, baseUrl: baseUrl });
|
|
110
223
|
}
|
|
111
|
-
catch {
|
|
112
|
-
throw new Error(`
|
|
224
|
+
catch (err) {
|
|
225
|
+
throw new Error(`Failed to start remotes. Check above for any errors.`, {
|
|
226
|
+
cause: err,
|
|
227
|
+
});
|
|
113
228
|
}
|
|
114
229
|
finally {
|
|
115
230
|
done();
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"items": {
|
|
20
20
|
"type": "string"
|
|
21
21
|
},
|
|
22
|
-
"description": "List of remote applications to not automatically serve, either statically or in development mode.",
|
|
22
|
+
"description": "List of remote applications to not automatically serve, either statically or in development mode. This will not remove the remotes from the `module-federation.config` file, and therefore the application may still try to fetch these remotes.\nThis option is useful for when the `host` application is using a `remote` that does not live in the same workspace as the `host`.",
|
|
23
23
|
"x-priority": "important"
|
|
24
24
|
},
|
|
25
25
|
"buildTarget": {
|
|
@@ -101,6 +101,18 @@
|
|
|
101
101
|
"description": "Whether the host that is running this executor is the first in the project tree to do so.",
|
|
102
102
|
"default": true,
|
|
103
103
|
"x-priority": "internal"
|
|
104
|
+
},
|
|
105
|
+
"parallel": {
|
|
106
|
+
"type": "number",
|
|
107
|
+
"description": "Max number of parallel processes for building static remotes"
|
|
108
|
+
},
|
|
109
|
+
"staticRemotesPort": {
|
|
110
|
+
"type": "number",
|
|
111
|
+
"description": "The port at which to serve the file-server for the static remotes."
|
|
112
|
+
},
|
|
113
|
+
"pathToManifestFile": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"description": "Path to a Module Federation manifest file (e.g. `my/path/to/module-federation.manifest.json`) containing the dynamic remote applications relative to the workspace root."
|
|
104
116
|
}
|
|
105
117
|
}
|
|
106
118
|
}
|
|
@@ -13,8 +13,8 @@ const add_styled_dependencies_1 = require("../../rules/add-styled-dependencies")
|
|
|
13
13
|
const devkit_1 = require("@nx/devkit");
|
|
14
14
|
const init_1 = require("../init/init");
|
|
15
15
|
const eslint_1 = require("@nx/eslint");
|
|
16
|
-
const lint_project_1 = require("@nx/eslint/src/generators/lint-project/lint-project");
|
|
17
16
|
const versions_1 = require("../../utils/versions");
|
|
17
|
+
const maybe_js_1 = require("../../utils/maybe-js");
|
|
18
18
|
const install_common_dependencies_1 = require("./lib/install-common-dependencies");
|
|
19
19
|
const create_ts_config_1 = require("../../utils/create-ts-config");
|
|
20
20
|
const add_swc_dependencies_1 = require("@nx/js/src/utils/swc/add-swc-dependencies");
|
|
@@ -22,6 +22,9 @@ const chalk = require("chalk");
|
|
|
22
22
|
const show_possible_warnings_1 = require("./lib/show-possible-warnings");
|
|
23
23
|
const add_e2e_1 = require("./lib/add-e2e");
|
|
24
24
|
const eslint_file_1 = require("@nx/eslint/src/generators/utils/eslint-file");
|
|
25
|
+
const js_1 = require("@nx/js");
|
|
26
|
+
const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command");
|
|
27
|
+
const setup_tailwind_1 = require("../setup-tailwind/setup-tailwind");
|
|
25
28
|
async function addLinting(host, options) {
|
|
26
29
|
const tasks = [];
|
|
27
30
|
if (options.linter === eslint_1.Linter.EsLint) {
|
|
@@ -32,12 +35,10 @@ async function addLinting(host, options) {
|
|
|
32
35
|
(0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.app.json'),
|
|
33
36
|
],
|
|
34
37
|
unitTestRunner: options.unitTestRunner,
|
|
35
|
-
eslintFilePatterns: [
|
|
36
|
-
(0, lint_project_1.mapLintPattern)(options.appProjectRoot, '{ts,tsx,js,jsx}', options.rootProject),
|
|
37
|
-
],
|
|
38
38
|
skipFormat: true,
|
|
39
39
|
rootProject: options.rootProject,
|
|
40
40
|
skipPackageJson: options.skipPackageJson,
|
|
41
|
+
addPlugin: options.addPlugin,
|
|
41
42
|
});
|
|
42
43
|
tasks.push(lintTask);
|
|
43
44
|
if ((0, eslint_file_1.isEslintConfigSupported)(host)) {
|
|
@@ -53,6 +54,7 @@ async function addLinting(host, options) {
|
|
|
53
54
|
}
|
|
54
55
|
async function applicationGenerator(host, schema) {
|
|
55
56
|
return await applicationGeneratorInternal(host, {
|
|
57
|
+
addPlugin: false,
|
|
56
58
|
projectNameAndRootFormat: 'derived',
|
|
57
59
|
...schema,
|
|
58
60
|
});
|
|
@@ -62,17 +64,41 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
62
64
|
const tasks = [];
|
|
63
65
|
const options = await (0, normalize_options_1.normalizeOptions)(host, schema);
|
|
64
66
|
(0, show_possible_warnings_1.showPossibleWarnings)(host, options);
|
|
67
|
+
const jsInitTask = await (0, js_1.initGenerator)(host, {
|
|
68
|
+
...schema,
|
|
69
|
+
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
|
|
70
|
+
skipFormat: true,
|
|
71
|
+
});
|
|
72
|
+
tasks.push(jsInitTask);
|
|
65
73
|
const initTask = await (0, init_1.default)(host, {
|
|
66
74
|
...options,
|
|
67
75
|
skipFormat: true,
|
|
68
|
-
skipHelperLibs: options.bundler === 'vite',
|
|
69
76
|
});
|
|
70
77
|
tasks.push(initTask);
|
|
78
|
+
if (options.bundler === 'webpack') {
|
|
79
|
+
const { webpackInitGenerator } = (0, devkit_1.ensurePackage)('@nx/webpack', versions_1.nxVersion);
|
|
80
|
+
const webpackInitTask = await webpackInitGenerator(host, {
|
|
81
|
+
skipPackageJson: options.skipPackageJson,
|
|
82
|
+
skipFormat: true,
|
|
83
|
+
addPlugin: options.addPlugin,
|
|
84
|
+
});
|
|
85
|
+
tasks.push(webpackInitTask);
|
|
86
|
+
if (!options.skipPackageJson) {
|
|
87
|
+
const { ensureDependencies } = await Promise.resolve().then(() => require('@nx/webpack/src/utils/ensure-dependencies'));
|
|
88
|
+
tasks.push(ensureDependencies(host, { uiFramework: 'react' }));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
71
91
|
if (!options.rootProject) {
|
|
72
92
|
(0, create_ts_config_1.extractTsConfigBase)(host);
|
|
73
93
|
}
|
|
74
94
|
(0, create_application_files_1.createApplicationFiles)(host, options);
|
|
75
95
|
(0, add_project_1.addProject)(host, options);
|
|
96
|
+
if (options.style === 'tailwind') {
|
|
97
|
+
const twTask = await (0, setup_tailwind_1.setupTailwindGenerator)(host, {
|
|
98
|
+
project: options.projectName,
|
|
99
|
+
});
|
|
100
|
+
tasks.push(twTask);
|
|
101
|
+
}
|
|
76
102
|
if (options.bundler === 'vite') {
|
|
77
103
|
const { createOrEditViteConfig, viteConfigurationGenerator } = (0, devkit_1.ensurePackage)('@nx/vite', versions_1.nxVersion);
|
|
78
104
|
// We recommend users use `import.meta.env.MODE` and other variables in their code to differentiate between production and development.
|
|
@@ -88,6 +114,7 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
88
114
|
inSourceTests: options.inSourceTests,
|
|
89
115
|
compiler: options.compiler,
|
|
90
116
|
skipFormat: true,
|
|
117
|
+
addPlugin: options.addPlugin,
|
|
91
118
|
});
|
|
92
119
|
tasks.push(viteTask);
|
|
93
120
|
createOrEditViteConfig(host, {
|
|
@@ -108,23 +135,15 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
108
135
|
plugins: ['react()'],
|
|
109
136
|
}, false);
|
|
110
137
|
}
|
|
111
|
-
else if (options.bundler === 'webpack') {
|
|
112
|
-
const { webpackInitGenerator } = (0, devkit_1.ensurePackage)('@nx/webpack', versions_1.nxVersion);
|
|
113
|
-
const webpackInitTask = await webpackInitGenerator(host, {
|
|
114
|
-
uiFramework: 'react',
|
|
115
|
-
skipFormat: true,
|
|
116
|
-
});
|
|
117
|
-
tasks.push(webpackInitTask);
|
|
118
|
-
}
|
|
119
138
|
else if (options.bundler === 'rspack') {
|
|
120
139
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/rspack', versions_1.nxRspackVersion);
|
|
121
140
|
const rspackTask = await configurationGenerator(host, {
|
|
122
141
|
project: options.projectName,
|
|
123
|
-
main: (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0,
|
|
142
|
+
main: (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)(options, `src/main.tsx`)),
|
|
124
143
|
tsConfig: (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.app.json'),
|
|
125
144
|
target: 'web',
|
|
126
145
|
newProject: true,
|
|
127
|
-
|
|
146
|
+
framework: 'react',
|
|
128
147
|
});
|
|
129
148
|
tasks.push(rspackTask);
|
|
130
149
|
}
|
|
@@ -132,10 +151,11 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
132
151
|
const { createOrEditViteConfig, vitestGenerator } = (0, devkit_1.ensurePackage)('@nx/vite', versions_1.nxVersion);
|
|
133
152
|
const vitestTask = await vitestGenerator(host, {
|
|
134
153
|
uiFramework: 'react',
|
|
135
|
-
coverageProvider: '
|
|
154
|
+
coverageProvider: 'v8',
|
|
136
155
|
project: options.projectName,
|
|
137
156
|
inSourceTests: options.inSourceTests,
|
|
138
157
|
skipFormat: true,
|
|
158
|
+
addPlugin: options.addPlugin,
|
|
139
159
|
});
|
|
140
160
|
tasks.push(vitestTask);
|
|
141
161
|
createOrEditViteConfig(host, {
|
|
@@ -181,8 +201,8 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
181
201
|
devkit_1.logger.warn(`${chalk.bold('styled-jsx')} is not supported by ${chalk.bold('Rspack')}. We've added ${chalk.bold('babel-loader')} to your project, but using babel will slow down your build.`);
|
|
182
202
|
tasks.push((0, devkit_1.addDependenciesToPackageJson)(host, {}, { 'babel-loader': versions_1.babelLoaderVersion }));
|
|
183
203
|
host.write((0, devkit_1.joinPathFragments)(options.appProjectRoot, 'rspack.config.js'), (0, devkit_1.stripIndents) `
|
|
184
|
-
const { composePlugins, withNx,
|
|
185
|
-
module.exports = composePlugins(withNx(),
|
|
204
|
+
const { composePlugins, withNx, withReact } = require('@nx/rspack');
|
|
205
|
+
module.exports = composePlugins(withNx(), withReact(), (config) => {
|
|
186
206
|
config.module.rules.push({
|
|
187
207
|
test: /\\.[jt]sx$/i,
|
|
188
208
|
use: [
|
|
@@ -202,6 +222,9 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
202
222
|
if (!options.skipFormat) {
|
|
203
223
|
await (0, devkit_1.formatFiles)(host);
|
|
204
224
|
}
|
|
225
|
+
tasks.push(() => {
|
|
226
|
+
(0, log_show_project_command_1.logShowProjectCommand)(options.projectName);
|
|
227
|
+
});
|
|
205
228
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
206
229
|
}
|
|
207
230
|
exports.applicationGeneratorInternal = applicationGeneratorInternal;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
9
9
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
10
|
-
<% if (!styledModule && style !== 'none') { %><link rel="stylesheet" href="/src/styles.<%= style %>" /><% } %>
|
|
10
|
+
<% if (!styledModule && style !== 'none') { %><link rel="stylesheet" href="/src/styles.<%= style === 'tailwind' ? 'css' : style %>" /><% } %>
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root"></div>
|
|
@@ -1,9 +1,50 @@
|
|
|
1
|
+
<% if (webpackPluginOptions) { %>
|
|
2
|
+
const { NxWebpackPlugin } = require('@nx/webpack');
|
|
3
|
+
const { NxReactWebpackPlugin } = require('@nx/react');
|
|
4
|
+
const { join } = require('path');
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
output: {
|
|
8
|
+
path: join(__dirname, '<%= offsetFromRoot %><%= webpackPluginOptions.outputPath %>'),
|
|
9
|
+
},
|
|
10
|
+
devServer: {
|
|
11
|
+
port: 4200
|
|
12
|
+
},
|
|
13
|
+
plugins: [
|
|
14
|
+
new NxWebpackPlugin({
|
|
15
|
+
tsConfig: '<%= webpackPluginOptions.tsConfig %>',
|
|
16
|
+
compiler: '<%= webpackPluginOptions.compiler %>',
|
|
17
|
+
main: '<%= webpackPluginOptions.main %>',
|
|
18
|
+
index: '<%= webpackPluginOptions.index %>',
|
|
19
|
+
baseHref: '<%= webpackPluginOptions.baseHref %>',
|
|
20
|
+
assets: <%- JSON.stringify(webpackPluginOptions.assets) %>,
|
|
21
|
+
styles: <%- JSON.stringify(webpackPluginOptions.styles) %>,
|
|
22
|
+
outputHashing: process.env['NODE_ENV'] === 'production' ? 'all' : 'none',
|
|
23
|
+
optimization: process.env['NODE_ENV'] === 'production',
|
|
24
|
+
}),
|
|
25
|
+
new NxReactWebpackPlugin({
|
|
26
|
+
// Uncomment this line if you don't want to use SVGR
|
|
27
|
+
// See: https://react-svgr.com/
|
|
28
|
+
// svgr: false
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
<% } else { %>
|
|
1
33
|
const { composePlugins, withNx } = require('@nx/webpack');
|
|
2
34
|
const { withReact } = require('@nx/react');
|
|
3
35
|
|
|
4
36
|
// Nx plugins for webpack.
|
|
5
|
-
module.exports = composePlugins(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
37
|
+
module.exports = composePlugins(
|
|
38
|
+
withNx(),
|
|
39
|
+
withReact({
|
|
40
|
+
// Uncomment this line if you don't want to use SVGR
|
|
41
|
+
// See: https://react-svgr.com/
|
|
42
|
+
// svgr: false
|
|
43
|
+
}),
|
|
44
|
+
(config) => {
|
|
45
|
+
// Update the webpack config as needed here.
|
|
46
|
+
// e.g. `config.plugins.push(new MyPlugin())`
|
|
47
|
+
return config;
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
<% } %>
|