Skip to content

Commit f4fb242

Browse files
feat(enhanced): support shared module layers (#3276)
Co-authored-by: Hanric <[email protected]>
1 parent 39d7271 commit f4fb242

File tree

241 files changed

+20429
-4726
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

241 files changed

+20429
-4726
lines changed

.changeset/ai-hungry-bear.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@module-federation/enhanced": minor
3+
---
4+
5+
Enhancements to layer handling in module federation tests and configuration.
6+
7+
- Introduced new layer configurations to support more nuanced federation scenarios that consider multiple layers of dependency.
8+

.changeset/ai-sleepy-fox.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@module-federation/enhanced": patch
3+
---
4+
5+
Refactored module sharing configuration handling.
6+
7+
- Simplified plugin schema for better maintainability
8+
- Improved layer-based module sharing test coverage
9+
- Removed redundant plugin exports

.changeset/ai-sleepy-tiger.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@module-federation/runtime": minor
3+
---
4+
5+
- Added a new property 'layer' of type string or null to SharedConfig.

.changeset/brown-badgers-fetch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/enhanced': minor
3+
---
4+
5+
support request option on ConsumeSharePlugin. Allows matching requests like the object key of shared does

.changeset/rotten-bears-trade.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@module-federation/webpack-bundler-runtime': minor
3+
'@module-federation/runtime-core': minor
4+
'@module-federation/enhanced': minor
5+
'@module-federation/managers': minor
6+
'@module-federation/sdk': minor
7+
'@module-federation/nextjs-mf': patch
8+
---
9+
10+
Support share layers and multiple share scopes

.changeset/shy-snails-battle.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/enhanced': minor
3+
---
4+
5+
Layer support for Provide Share Plugin

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# dependencies
1111
node_modules
1212
./webpack-lib
13+
next.js
1314
# IDEs and editors
1415
/.idea
1516
.project
@@ -71,4 +72,6 @@ packages/enhanced/test/js
7172
!apps/rslib-module/@mf-types/**
7273

7374
**/vite.config.{js,ts,mjs,mts,cjs,cts}.timestamp*
74-
/webpack-lib/
75+
76+
# Federation
77+
**/.federation

apps/next-app-router/next-app-router-4000/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"name": "app-router-4000",
23
"private": true,
34
"scripts": {
45
"build": "next build",

apps/next-app-router/next-app-router-4000/prettier.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ module.exports = {
55
singleQuote: true,
66
// pnpm doesn't support plugin autoloading
77
// https://github.com/tailwindlabs/prettier-plugin-tailwindcss#installation
8-
// plugins: ['prettier-plugin-tailwindcss'],
8+
plugins: ['prettier-plugin-tailwindcss'],
99
};

apps/next-app-router/next-app-router-4001/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"private": true,
3+
"name": "app-router-4001",
34
"scripts": {
45
"build": "next build",
56
"dev": "NEXT_PRIVATE_LOCAL_WEBPACK=true next dev -p 4001",

apps/next-app-router/next-app-router-4001/prettier.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ module.exports = {
55
singleQuote: true,
66
// pnpm doesn't support plugin autoloading
77
// https://github.com/tailwindlabs/prettier-plugin-tailwindcss#installation
8-
// plugins: ['prettier-plugin-tailwindcss'],
8+
plugins: ['prettier-plugin-tailwindcss'],
99
};

package.json

+6-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"commit": "cz",
2424
"docs": "typedoc",
2525
"f": "nx format:write",
26+
"enhanced:jest": "pnpm build && cd packages/enhanced && NODE_OPTIONS=--experimental-vm-modules npx jest test/ConfigTestCases.basictest.js test/unit",
2627
"lint": "nx run-many --target=lint",
2728
"test": "nx run-many --target=test",
2829
"build": "nx run-many --target=build --parallel=5 --projects=tag:type:pkg",
@@ -31,6 +32,8 @@
3132
"lint-fix": "nx format:write --uncommitted",
3233
"trigger-release": "node -e 'import(\"open\").then(open => open.default(\"https://github.com/module-federation/core/actions/workflows/trigger-release.yml\"))'",
3334
"serve:next": "nx run-many --target=serve --all --parallel=3 -exclude='*,!tag:nextjs'",
35+
"app:router:dev": "nx run-many --target=serve --parallel=10 --projects='router-*'",
36+
"app:next-router:dev": "nx run-many --target=serve --projects=next-app-router-4000,next-app-router-4001 --parallel",
3437
"serve:website": "nx run website-new:serve",
3538
"build:website": "nx run website-new:build",
3639
"extract-i18n:website": "nx run website:extract-i18n",
@@ -40,7 +43,6 @@
4043
"app:next:prod": "nx run-many --target=serve --configuration=production -p 3000-home,3001-shop,3002-checkout",
4144
"app:node:dev": "nx run-many --target=serve --parallel=10 --configuration=development -p node-host,node-local-remote,node-remote,node-dynamic-remote-new-version,node-dynamic-remote",
4245
"app:runtime:dev": "nx run-many --target=serve -p 3005-runtime-host,3006-runtime-remote,3007-runtime-remote",
43-
"app:router:dev": "nx run-many --target=serve --parallel=10 --projects='router-*'",
4446
"app:manifest:dev": "nx run-many --target=serve --configuration=development --parallel=100 -p modernjs,manifest-webpack-host,3009-webpack-provider,3010-rspack-provider,3011-rspack-manifest-provider,3012-rspack-js-entry-provider",
4547
"app:manifest:prod": "nx run-many --target=serve --configuration=production --parallel=100 -p modernjs,manifest-webpack-host,3009-webpack-provider,3010-rspack-provider,3011-rspack-manifest-provider,3012-rspack-js-entry-provider",
4648
"app:ts:dev": "nx run-many --target=serve -p react_ts_host,react_ts_nested_remote,react_ts_remote",
@@ -90,7 +92,6 @@
9092
"sharp": "^0.33.4",
9193
"storybook": "8.3.5",
9294
"tapable": "2.2.1",
93-
"tsup": "7.2.0",
9495
"typedoc": "0.25.8",
9596
"undici": "5.28.5",
9697
"unplugin": "1.9.0"
@@ -219,7 +220,7 @@
219220
"terser-webpack-plugin": "^5.3.10",
220221
"ts-jest": "29.1.5",
221222
"tslib": "2.8.1",
222-
"tsup": "7.2.0",
223+
"tsup": "7.3.0",
223224
"typescript": "5.5.2",
224225
"url-loader": "4.1.1",
225226
"verdaccio": "5.29.2",
@@ -229,7 +230,8 @@
229230
"vitest-fetch-mock": "^0.2.2",
230231
"vue-tsc": "^2.0.26",
231232
"wait-on": "^7.2.0",
232-
"webpack": "5.93.0",
233+
"webpack": "5.94.0",
234+
"webpack-cli": "^5.1.4",
233235
"webpack-virtual-modules": "0.6.2",
234236
"whatwg-fetch": "^3.6.20",
235237
"yargs": "^17.7.2"

packages/create-module-federation/project.json

+18-12
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
"targets": {
88
"build": {
99
"executor": "nx:run-commands",
10+
"dependsOn": [
11+
{
12+
"target": "build",
13+
"dependencies": true
14+
}
15+
],
1016
"options": {
1117
"parallel": false,
12-
"dependsOn": [
13-
{
14-
"target": "build",
15-
"dependencies": true
16-
}
17-
],
1818
"commands": [
1919
"cd packages/create-module-federation; pnpm run build",
2020
"cp packages/create-module-federation/LICENSE packages/create-module-federation/dist"
@@ -33,19 +33,25 @@
3333
},
3434
"test": {
3535
"executor": "nx:run-commands",
36+
"dependsOn": [
37+
{
38+
"target": "build",
39+
"dependencies": true
40+
}
41+
],
3642
"options": {
3743
"parallel": false,
38-
"dependsOn": [
39-
{
40-
"target": "build",
41-
"dependencies": true
42-
}
43-
],
4444
"commands": ["echo 'no test'"]
4545
}
4646
},
4747
"pre-release": {
4848
"executor": "nx:run-commands",
49+
"dependsOn": [
50+
{
51+
"target": "build",
52+
"dependencies": true
53+
}
54+
],
4955
"options": {
5056
"parallel": false,
5157
"commands": [

packages/enhanced/jest.config.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ export default {
3333
moduleFileExtensions: ['ts', 'js', 'html'],
3434
coverageDirectory: '../../coverage/packages/enhanced',
3535
rootDir: __dirname,
36-
testMatch: ['<rootDir>/test/*.basictest.js'],
36+
testMatch: [
37+
'<rootDir>/test/*.basictest.js',
38+
'<rootDir>/test/unit/**/*.test.ts',
39+
],
3740

3841
testEnvironment: path.resolve(__dirname, './test/patch-node-env.js'),
3942
setupFilesAfterEnv: ['<rootDir>/test/setupTestFramework.js'],

packages/enhanced/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"@module-federation/sdk": "workspace:*",
103103
"@module-federation/cli": "workspace:*",
104104
"btoa": "^1.2.1",
105-
"upath": "2.0.1"
105+
"upath": "2.0.1",
106+
"schema-utils": "^4.3.0"
106107
}
107108
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
export type ConsumeOptions = {
2+
/**
3+
* fallback request
4+
*/
5+
import?: string | undefined;
6+
/**
7+
* resolved fallback request
8+
*/
9+
importResolved?: string | undefined;
10+
/**
11+
* The actual request to use for importing the module. If not specified, the property name/key will be used.
12+
*/
13+
request?: string;
14+
/**
15+
* global share key
16+
*/
17+
shareKey: string;
18+
/**
19+
* share scope
20+
*/
21+
shareScope: string | string[];
22+
/**
23+
* version requirement
24+
*/
25+
requiredVersion:
26+
| import('webpack/lib/util/semver').SemVerRange
27+
| false
28+
| undefined;
29+
/**
30+
* package name to determine required version automatically
31+
*/
32+
packageName: string;
33+
/**
34+
* don't use shared version even if version isn't valid
35+
*/
36+
strictVersion: boolean;
37+
/**
38+
* use single global version
39+
*/
40+
singleton: boolean;
41+
/**
42+
* include the fallback module in a sync way
43+
*/
44+
eager: boolean;
45+
/**
46+
* Share a specific layer of the module, if the module supports layers
47+
*/
48+
layer?: string | null;
49+
/**
50+
* Issuer layer in which the module should be resolved
51+
*/
52+
issuerLayer?: string | null;
53+
};

packages/enhanced/src/declarations/plugins/sharing/ConsumeSharedPlugin.d.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export interface ConsumeSharedPluginOptions {
2424
/**
2525
* Share scope name used for all consumed modules (defaults to 'default').
2626
*/
27-
shareScope?: string;
27+
shareScope?: string | string[];
2828
}
2929
/**
3030
* Modules that should be consumed from share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.
@@ -62,7 +62,7 @@ export interface ConsumesConfig {
6262
/**
6363
* Share scope name.
6464
*/
65-
shareScope?: string;
65+
shareScope?: string | string[];
6666
/**
6767
* Allow only a single version of the shared module in share scope (disabled by default).
6868
*/
@@ -71,4 +71,16 @@ export interface ConsumesConfig {
7171
* Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).
7272
*/
7373
strictVersion?: boolean;
74+
/**
75+
* Issuer layer in which the module should be resolved.
76+
*/
77+
issuerLayer?: string;
78+
/**
79+
* Layer for the shared module.
80+
*/
81+
layer?: string;
82+
/**
83+
* The actual request to use for importing the module. If not specified, the property name/key will be used.
84+
*/
85+
request?: string;
7486
}

packages/enhanced/src/declarations/plugins/sharing/ProvideSharedPlugin.d.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export interface ProvideSharedPluginOptions {
2121
/**
2222
* Share scope name used for all provided modules (defaults to 'default').
2323
*/
24-
shareScope?: string;
24+
shareScope?: string | string[];
2525
}
2626
/**
2727
* Modules that should be provided as shared modules to the share scope. Property names are used as share keys.
@@ -47,7 +47,7 @@ export interface ProvidesConfig {
4747
/**
4848
* Share scope name.
4949
*/
50-
shareScope?: string;
50+
shareScope?: string | string[];
5151
/**
5252
* Version of the provided module. Will replace lower matching versions, but not higher.
5353
*/
@@ -64,4 +64,12 @@ export interface ProvidesConfig {
6464
* Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).
6565
*/
6666
strictVersion?: boolean;
67+
/**
68+
* Layer for the shared module.
69+
*/
70+
layer?: string;
71+
/**
72+
* The actual request to use for importing the module. If not specified, the property name/key will be used.
73+
*/
74+
request?: string;
6775
}

packages/enhanced/src/declarations/plugins/sharing/SharePlugin.d.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface SharePluginOptions {
2020
/**
2121
* Share scope name used for all shared modules (defaults to 'default').
2222
*/
23-
shareScope?: string;
23+
shareScope?: string | string[];
2424
/**
2525
* Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.
2626
*/
@@ -62,7 +62,7 @@ export interface SharedConfig {
6262
/**
6363
* Share scope name.
6464
*/
65-
shareScope?: string;
65+
shareScope?: string | string[];
6666
/**
6767
* Allow only a single version of the shared module in share scope (disabled by default).
6868
*/
@@ -75,4 +75,16 @@ export interface SharedConfig {
7575
* Version of the provided module. Will replace lower matching versions, but not higher.
7676
*/
7777
version?: false | string;
78+
/**
79+
* Issuer layer in which the module should be resolved.
80+
*/
81+
issuerLayer?: string;
82+
/**
83+
* Layer for the shared module.
84+
*/
85+
layer?: string;
86+
/**
87+
* The actual request to use for importing the module. Defaults to the property name.
88+
*/
89+
request?: string;
7890
}

packages/enhanced/src/lib/container/ContainerEntryDependency.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,21 @@ const { Dependency } = require(
1818
class ContainerEntryDependency extends Dependency {
1919
public name: string;
2020
public exposes: [string, ExposeOptions][];
21-
public shareScope: string;
21+
public shareScope: string | string[];
2222
public injectRuntimeEntry: string;
2323
public dataPrefetch: containerPlugin.ContainerPluginOptions['dataPrefetch'];
2424

2525
/**
2626
* @param {string} name entry name
2727
* @param {[string, ExposeOptions][]} exposes list of exposed modules
28-
* @param {string} shareScope name of the share scope
28+
* @param {string|string[]} shareScope name of the share scope
2929
* @param {string[]} injectRuntimeEntry the path of injectRuntime file.
3030
* @param {containerPlugin.ContainerPluginOptions['dataPrefetch']} dataPrefetch whether enable dataPrefetch
3131
*/
3232
constructor(
3333
name: string,
3434
exposes: [string, ExposeOptions][],
35-
shareScope: string,
35+
shareScope: string | string[],
3636
injectRuntimeEntry: string,
3737
dataPrefetch: containerPlugin.ContainerPluginOptions['dataPrefetch'],
3838
) {

0 commit comments

Comments
 (0)