@nx/module-federation 20.7.2 → 20.8.0-beta.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nx/module-federation",
3
3
  "description": "The Nx Plugin for Module Federation contains executors and utilities that support building applications using Module Federation.",
4
- "version": "20.7.2",
4
+ "version": "20.8.0-beta.0",
5
5
  "type": "commonjs",
6
6
  "repository": {
7
7
  "type": "git",
@@ -25,9 +25,9 @@
25
25
  "executors": "./executors.json",
26
26
  "dependencies": {
27
27
  "tslib": "^2.3.0",
28
- "@nx/devkit": "20.7.2",
29
- "@nx/js": "20.7.2",
30
- "@nx/web": "20.7.2",
28
+ "@nx/devkit": "20.8.0-beta.0",
29
+ "@nx/js": "20.8.0-beta.0",
30
+ "@nx/web": "20.8.0-beta.0",
31
31
  "picocolors": "^1.1.0",
32
32
  "webpack": "^5.88.0",
33
33
  "@rspack/core": "^1.1.5",
@@ -3,7 +3,6 @@ import { ModuleFederationConfig } from '../../../utils/models';
3
3
  import { NxModuleFederationDevServerConfig } from '../../models';
4
4
  export declare class NxModuleFederationDevServerPlugin implements RspackPluginInstance {
5
5
  private _options;
6
- private devServerProcess;
7
6
  private nxBin;
8
7
  constructor(_options: {
9
8
  config: ModuleFederationConfig;
@@ -17,22 +17,29 @@ class NxModuleFederationDevServerPlugin {
17
17
  };
18
18
  }
19
19
  apply(compiler) {
20
- compiler.hooks.beforeCompile.tapAsync(PLUGIN_NAME, async (params, callback) => {
21
- const staticRemotesConfig = await this.setup(compiler);
22
- devkit_1.logger.info(`NX Starting module federation dev-server for ${pc.bold(this._options.config.name)} with ${Object.keys(staticRemotesConfig).length} remotes`);
23
- const mappedLocationOfRemotes = await (0, utils_1.buildStaticRemotes)(staticRemotesConfig, this._options.devServerConfig, this.nxBin);
24
- (0, utils_1.startStaticRemotesFileServer)(staticRemotesConfig, devkit_1.workspaceRoot, this._options.devServerConfig.staticRemotesPort);
25
- (0, utils_1.startRemoteProxies)(staticRemotesConfig, mappedLocationOfRemotes, {
26
- pathToCert: this._options.devServerConfig.sslCert,
27
- pathToKey: this._options.devServerConfig.sslCert,
20
+ const isDevServer = process.env['WEBPACK_SERVE'];
21
+ if (!isDevServer) {
22
+ return;
23
+ }
24
+ compiler.hooks.watchRun.tapAsync(PLUGIN_NAME, async (compiler, callback) => {
25
+ compiler.hooks.beforeCompile.tapAsync(PLUGIN_NAME, async (params, callback) => {
26
+ const staticRemotesConfig = await this.setup();
27
+ devkit_1.logger.info(`NX Starting module federation dev-server for ${pc.bold(this._options.config.name)} with ${Object.keys(staticRemotesConfig).length} remotes`);
28
+ const mappedLocationOfRemotes = await (0, utils_1.buildStaticRemotes)(staticRemotesConfig, this._options.devServerConfig, this.nxBin);
29
+ (0, utils_1.startStaticRemotesFileServer)(staticRemotesConfig, devkit_1.workspaceRoot, this._options.devServerConfig.staticRemotesPort);
30
+ (0, utils_1.startRemoteProxies)(staticRemotesConfig, mappedLocationOfRemotes, {
31
+ pathToCert: this._options.devServerConfig.sslCert,
32
+ pathToKey: this._options.devServerConfig.sslCert,
33
+ });
34
+ new core_1.DefinePlugin({
35
+ 'process.env.NX_MF_DEV_REMOTES': process.env.NX_MF_DEV_REMOTES,
36
+ }).apply(compiler);
37
+ callback();
28
38
  });
29
- new core_1.DefinePlugin({
30
- 'process.env.NX_MF_DEV_REMOTES': process.env.NX_MF_DEV_REMOTES,
31
- }).apply(compiler);
32
39
  callback();
33
40
  });
34
41
  }
35
- async setup(compiler) {
42
+ async setup() {
36
43
  const projectGraph = (0, devkit_1.readCachedProjectGraph)();
37
44
  const { projects: workspaceProjects } = (0, devkit_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
38
45
  const project = workspaceProjects[this._options.config.name];
@@ -1,12 +1,10 @@
1
1
  import { Compiler, RspackPluginInstance } from '@rspack/core';
2
2
  import { ModuleFederationConfig, NxModuleFederationConfigOverride } from '../../../utils/models';
3
- import { NxModuleFederationDevServerConfig } from '../../models';
4
3
  export declare class NxModuleFederationPlugin implements RspackPluginInstance {
5
4
  private _options;
6
5
  private configOverride?;
7
6
  constructor(_options: {
8
7
  config: ModuleFederationConfig;
9
- devServerConfig?: NxModuleFederationDevServerConfig;
10
8
  isServer?: boolean;
11
9
  }, configOverride?: NxModuleFederationConfigOverride);
12
10
  apply(compiler: Compiler): void;
@@ -12,6 +12,7 @@ class NxModuleFederationPlugin {
12
12
  return;
13
13
  }
14
14
  // This is required to ensure Module Federation will build the project correctly
15
+ compiler.options.optimization ??= {};
15
16
  compiler.options.optimization.runtimeChunk = false;
16
17
  compiler.options.output.uniqueName = this._options.config.name;
17
18
  if (this._options.isServer) {
@@ -18,6 +18,10 @@ class NxModuleFederationSSRDevServerPlugin {
18
18
  };
19
19
  }
20
20
  apply(compiler) {
21
+ const isDevServer = process.env['WEBPACK_SERVE'];
22
+ if (!isDevServer) {
23
+ return;
24
+ }
21
25
  compiler.hooks.watchRun.tapAsync(PLUGIN_NAME, async (compiler, callback) => {
22
26
  compiler.hooks.beforeCompile.tapAsync(PLUGIN_NAME, async (params, callback) => {
23
27
  const staticRemotesConfig = await this.setup(compiler);
@@ -38,20 +42,20 @@ class NxModuleFederationSSRDevServerPlugin {
38
42
  });
39
43
  }
40
44
  async startServer(compiler) {
41
- compiler.hooks.afterEmit.tapAsync(PLUGIN_NAME, async (_, callback) => {
45
+ compiler.hooks.done.tapAsync(PLUGIN_NAME, async (_, callback) => {
42
46
  const serverPath = (0, path_1.join)(compiler.options.output.path, compiler.options.output.filename ?? 'server.js');
43
47
  if (this.devServerProcess) {
44
48
  await new Promise((res) => {
45
49
  this.devServerProcess.on('exit', () => {
46
50
  res();
47
51
  });
48
- this.devServerProcess.kill();
52
+ this.devServerProcess.kill('SIGKILL');
49
53
  this.devServerProcess = undefined;
50
54
  });
51
55
  }
52
56
  if (!(0, fs_1.existsSync)(serverPath)) {
53
57
  for (let retries = 0; retries < 10; retries++) {
54
- await new Promise((res) => setTimeout(res, 100));
58
+ await new Promise((res) => setTimeout(res, 200));
55
59
  if ((0, fs_1.existsSync)(serverPath)) {
56
60
  break;
57
61
  }
@@ -62,10 +66,10 @@ class NxModuleFederationSSRDevServerPlugin {
62
66
  }
63
67
  this.devServerProcess = (0, node_child_process_1.fork)(serverPath);
64
68
  process.on('exit', () => {
65
- this.devServerProcess?.kill();
69
+ this.devServerProcess?.kill('SIGKILL');
66
70
  });
67
71
  process.on('SIGINT', () => {
68
- this.devServerProcess?.kill();
72
+ this.devServerProcess?.kill('SIGKILL');
69
73
  });
70
74
  callback();
71
75
  });
@@ -18,7 +18,7 @@ function parseRemotesConfig(remotes, workspaceRoot, projectGraph, isServer) {
18
18
  projectRoot,
19
19
  workspaceRoot,
20
20
  });
21
- if (outputPath.startsWith(projectRoot)) {
21
+ if (!outputPath.startsWith(workspaceRoot)) {
22
22
  outputPath = (0, devkit_1.joinPathFragments)(workspaceRoot, outputPath);
23
23
  }
24
24
  const basePath = (0, path_1.dirname)(outputPath);
@@ -35,7 +35,16 @@ function collectRemoteProjects(remote, collected, context) {
35
35
  }
36
36
  collected.add(remote);
37
37
  const remoteProjectRoot = remoteProject.root;
38
- const remoteProjectTsConfig = remoteProject.targets['build'].options.tsConfig;
38
+ let remoteProjectTsConfig = remoteProject.targets['build'].options.tsConfig ??
39
+ [
40
+ (0, path_1.join)(remoteProjectRoot, 'tsconfig.app.json'),
41
+ (0, path_1.join)(remoteProjectRoot, 'tsconfig.json'),
42
+ (0, path_1.join)(context.root, 'tsconfig.json'),
43
+ (0, path_1.join)(context.root, 'tsconfig.base.json'),
44
+ ].find((p) => (0, fs_1.existsSync)(p));
45
+ if (!remoteProjectTsConfig) {
46
+ throw new Error(`Could not find a tsconfig for remote project ${remote}. Please add a tsconfig.app.json or tsconfig.json to the project.`);
47
+ }
39
48
  const remoteProjectConfig = getModuleFederationConfig(remoteProjectTsConfig, context.root, remoteProjectRoot);
40
49
  const { remotes: remoteProjectRemotes } = extractRemoteProjectsFromConfig(remoteProjectConfig);
41
50
  remoteProjectRemotes.forEach((r) => collectRemoteProjects(r, collected, context));
@@ -1,4 +1,4 @@
1
- import type { ExecutorContext } from '@nx/devkit';
1
+ import { ExecutorContext } from '@nx/devkit';
2
2
  export type StaticRemoteConfig = {
3
3
  basePath: string;
4
4
  outputPath: string;
@@ -2,14 +2,27 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseStaticRemotesConfig = parseStaticRemotesConfig;
4
4
  exports.parseStaticSsrRemotesConfig = parseStaticSsrRemotesConfig;
5
+ const devkit_1 = require("@nx/devkit");
5
6
  const path_1 = require("path");
7
+ const utils_1 = require("nx/src/tasks-runner/utils");
6
8
  function parseStaticRemotesConfig(staticRemotes, context) {
7
9
  if (!staticRemotes?.length) {
8
10
  return { remotes: [], config: undefined };
9
11
  }
10
12
  const config = {};
11
13
  for (const app of staticRemotes) {
12
- const outputPath = context.projectGraph.nodes[app].data.targets['build'].options.outputPath; // dist || dist/checkout
14
+ const projectGraph = context.projectGraph;
15
+ const projectRoot = projectGraph.nodes[app].data.root;
16
+ let outputPath = (0, utils_1.interpolate)(projectGraph.nodes[app].data.targets?.['build']?.options?.outputPath ??
17
+ projectGraph.nodes[app].data.targets?.['build']?.outputs?.[0] ??
18
+ `${context.root}/${projectGraph.nodes[app].data.root}/dist`, {
19
+ projectName: projectGraph.nodes[app].data.name,
20
+ projectRoot,
21
+ workspaceRoot: context.root,
22
+ });
23
+ if (outputPath.startsWith(projectRoot)) {
24
+ outputPath = (0, devkit_1.joinPathFragments)(context.root, outputPath);
25
+ }
13
26
  const basePath = ['', '/', '.'].some((p) => (0, path_1.dirname)(outputPath) === p)
14
27
  ? outputPath
15
28
  : (0, path_1.dirname)(outputPath); // dist || dist/checkout -> dist
@@ -25,9 +38,19 @@ function parseStaticSsrRemotesConfig(staticRemotes, context) {
25
38
  }
26
39
  const config = {};
27
40
  for (const app of staticRemotes) {
28
- let outputPath = context.projectGraph.nodes[app].data.targets['build']
29
- .options.outputPath;
30
- outputPath = (0, path_1.dirname)(outputPath); // dist/browser => dist || dist/checkout/browser -> checkout
41
+ const projectGraph = context.projectGraph;
42
+ const projectRoot = projectGraph.nodes[app].data.root;
43
+ let outputPath = (0, utils_1.interpolate)(projectGraph.nodes[app].data.targets?.['build']?.options?.outputPath ??
44
+ projectGraph.nodes[app].data.targets?.['build']?.outputs?.[0] ??
45
+ `${context.root}/${projectGraph.nodes[app].data.root}/dist`, {
46
+ projectName: projectGraph.nodes[app].data.name,
47
+ projectRoot,
48
+ workspaceRoot: context.root,
49
+ });
50
+ if (outputPath.startsWith(projectRoot)) {
51
+ outputPath = (0, devkit_1.joinPathFragments)(context.root, outputPath);
52
+ }
53
+ outputPath = (0, path_1.dirname)(outputPath);
31
54
  const basePath = ['', '/', '.'].some((p) => (0, path_1.dirname)(outputPath) === p)
32
55
  ? outputPath
33
56
  : (0, path_1.dirname)(outputPath); // dist || dist/checkout -> dist