Skip to content

Commit 7d836a4

Browse files
jaysooFrozenPandaz
authored andcommitted
fix(webpack): fix support for module federation plugin (#14653)
(cherry picked from commit 795e4d6)
1 parent 7e36fc7 commit 7d836a4

File tree

7 files changed

+114
-26
lines changed

7 files changed

+114
-26
lines changed

packages/react/plugins/storybook/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ExecutorContext, logger } from '@nrwl/devkit';
2-
import { composePlugins } from '@nrwl/webpack/src/utils/config';
1+
import { ExecutorContext, logger, workspaceRoot } from '@nrwl/devkit';
2+
import { composePluginsSync } from '@nrwl/webpack/src/utils/config';
33
import { NormalizedWebpackExecutorOptions } from '@nrwl/webpack/src/executors/webpack/schema';
44
import { join } from 'path';
55
import {
@@ -95,14 +95,14 @@ export const webpack = async (
9595

9696
// ESM build for modern browsers.
9797
let baseWebpackConfig: Configuration = {};
98-
const configure = composePlugins(
98+
const configure = composePluginsSync(
9999
withNx({ skipTypeChecking: true }),
100100
withWeb(),
101101
withReact()
102102
);
103103
const finalConfig = configure(baseWebpackConfig, {
104104
options: builderOptions,
105-
context: {} as ExecutorContext, // The context is not used here.
105+
context: { root: workspaceRoot } as ExecutorContext, // The context is not used here.
106106
});
107107

108108
return {

packages/react/src/generators/host/files/module-federation-ssr/webpack.server.config.js__tmpl__

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { composePlugins, withNx } from '@nrwl/webpack';
2-
import { withReact } from '@nrwl/react';
3-
import { withModuleFederationForSSR } from '@nrwl/react/module-federation';
1+
const { composePlugins, withNx } = require('@nrwl/webpack');
2+
const { withReact } = require('@nrwl/react');
3+
const { withModuleFederationForSSR } = require('@nrwl/react/module-federation');
44

55
const baseConfig = require('./module-federation.config');
66

packages/react/src/module-federation/with-module-federation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ export async function withModuleFederation(options: ModuleFederationConfig) {
2727
const { sharedDependencies, sharedLibraries, mappedRemotes } =
2828
await getModuleFederationConfig(options, determineRemoteUrl);
2929

30-
return (config) => {
31-
config = reactWebpackConfig(config);
30+
return (config, ctx) => {
31+
config = reactWebpackConfig(config, ctx);
3232
config.output.uniqueName = options.name;
3333
config.output.publicPath = 'auto';
3434

packages/webpack/src/executors/webpack/lib/get-webpack-config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ExecutorContext } from '@nrwl/devkit';
44
import { NormalizedWebpackExecutorOptions } from '../schema';
55
import { withNx } from '../../../utils/with-nx';
66
import { withWeb } from '../../../utils/with-web';
7-
import { composePlugins } from '@nrwl/webpack';
7+
import { composePluginsSync } from '../../../utils/config';
88

99
interface GetWebpackConfigOverrides {
1010
root: string;
@@ -20,6 +20,8 @@ export function getWebpackConfig(
2020
): Configuration {
2121
const config: Configuration = {};
2222
const configure =
23-
options.target === 'node' ? withNx() : composePlugins(withNx(), withWeb());
23+
options.target === 'node'
24+
? withNx()
25+
: composePluginsSync(withNx(), withWeb());
2426
return configure(config, { options, context });
2527
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {
2+
composePluginsSync,
3+
composePlugins,
4+
NxWebpackExecutionContext,
5+
} from './config';
6+
7+
describe('composePlugins', () => {
8+
it('should support sync and async plugin functions', async () => {
9+
const callOrder = [];
10+
const a = () => (config) => {
11+
callOrder.push('a');
12+
config.plugins.push(new (class A {})());
13+
return config;
14+
};
15+
const b = async () => (config) => {
16+
callOrder.push('b');
17+
config.plugins.push(new (class B {})());
18+
return config;
19+
};
20+
const c = () => async (config) => {
21+
callOrder.push('c');
22+
config.plugins.push(new (class C {})());
23+
return config;
24+
};
25+
const d = async () => async (config) => {
26+
callOrder.push('d');
27+
config.plugins.push(new (class D {})());
28+
return config;
29+
};
30+
31+
const combined = composePlugins(a(), b(), c(), d());
32+
const config = await combined(
33+
{ plugins: [] },
34+
{} as NxWebpackExecutionContext
35+
);
36+
37+
expect(config.plugins.map((p) => p.constructor.name)).toEqual([
38+
'A',
39+
'B',
40+
'C',
41+
'D',
42+
]);
43+
expect(callOrder).toEqual(['a', 'b', 'c', 'd']);
44+
});
45+
});
46+
47+
describe('composePluginsSync', () => {
48+
it('should support sync plugin functions', async () => {
49+
const callOrder = [];
50+
const a = () => (config) => {
51+
callOrder.push('a');
52+
config.plugins.push(new (class A {})());
53+
return config;
54+
};
55+
const b = () => (config) => {
56+
callOrder.push('b');
57+
config.plugins.push(new (class B {})());
58+
return config;
59+
};
60+
61+
const combined = composePluginsSync(a(), b());
62+
const config = await combined(
63+
{ plugins: [] },
64+
{} as NxWebpackExecutionContext
65+
);
66+
67+
expect(config.plugins.map((p) => p.constructor.name)).toEqual(['A', 'B']);
68+
expect(callOrder).toEqual(['a', 'b']);
69+
});
70+
});

packages/webpack/src/utils/config.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function getBaseWebpackPartial(
1111
context?: ExecutorContext
1212
): Configuration {
1313
const config: Configuration = {};
14-
const configure = composePlugins(withNx(), withWeb());
14+
const configure = composePluginsSync(withNx(), withWeb());
1515
return configure(config, { options, context });
1616
}
1717

@@ -20,28 +20,41 @@ export interface NxWebpackExecutionContext {
2020
context: ExecutorContext;
2121
}
2222

23-
export type NxWebpackPlugin = (
24-
config: Configuration,
25-
ctx: NxWebpackExecutionContext
26-
) => Configuration;
27-
28-
export type NxWebpackPluginAsyncResolver = Promise<NxWebpackPlugin>;
23+
export interface NxWebpackPlugin {
24+
(config: Configuration, ctx: NxWebpackExecutionContext): Configuration;
25+
}
26+
export interface AsyncNxWebpackPlugin {
27+
(config: Configuration, ctx: NxWebpackExecutionContext):
28+
| Configuration
29+
| Promise<Configuration>;
30+
}
2931

3032
export function composePlugins(
31-
...plugins: (NxWebpackPlugin | NxWebpackPluginAsyncResolver)[]
33+
...plugins: (
34+
| NxWebpackPlugin
35+
| AsyncNxWebpackPlugin
36+
| Promise<NxWebpackPlugin | AsyncNxWebpackPlugin>
37+
)[]
3238
) {
39+
return async function combined(
40+
config: Configuration,
41+
ctx: NxWebpackExecutionContext
42+
): Promise<Configuration> {
43+
for (const plugin of plugins) {
44+
const fn = await plugin;
45+
config = await fn(config, ctx);
46+
}
47+
return config;
48+
};
49+
}
50+
51+
export function composePluginsSync(...plugins: NxWebpackPlugin[]) {
3352
return function combined(
3453
config: Configuration,
3554
ctx: NxWebpackExecutionContext
3655
): Configuration {
3756
for (const plugin of plugins) {
38-
if ('then' in plugin) {
39-
plugin.then((resolvedPlugin) => {
40-
config = resolvedPlugin(config, ctx);
41-
});
42-
} else {
43-
config = plugin(config, ctx);
44-
}
57+
config = plugin(config, ctx);
4558
}
4659
return config;
4760
};

packages/webpack/src/utils/with-nx.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ export function withNx(opts?: { skipTypeChecking?: boolean }) {
125125

126126
const updated = {
127127
...config,
128+
context: context
129+
? path.join(context.root, options.projectRoot)
130+
: undefined,
128131
target: options.target,
129132
node: false as const,
130133
// When mode is development or production, webpack will automatically

0 commit comments

Comments
 (0)