22
22
* [ UniversalModuleFederationPlugin 示例] ( #UniversalModuleFederationPlugin-示例 )
23
23
* [ UniversalModuleFederationPlugin API] ( #UniversalModuleFederationPlugin-API )
24
24
* [ 运行时获取module-federation配置] ( #运行时获取module-federation配置 )
25
+ * [ 模块委托] ( #模块委托 )
25
26
26
27
## UmdPlugin示例
27
28
@@ -50,9 +51,6 @@ module.exports = {
50
51
" react-router" : " app4reactRouter@https://unpkg.com/react-router@6.4.3/dist/umd/react-router.production.min.js" ,
51
52
" @remix-run/router" : " app5remixRouter@https://unpkg.com/@remix-run/router@1.0.3/dist/router.umd.min.js"
52
53
},
53
- dependencies: {
54
- automatic: [" shareScopes" , " remotes" ],
55
- }
56
54
}),
57
55
new UmdPlugin ({
58
56
// ...
@@ -64,25 +62,26 @@ module.exports = {
64
62
65
63
## UmdPlugin API
66
64
67
- | options | desc | default | examles |
68
- | -------------------------------| --------------------------------------------| -----------------------------------| :--------------------------------------------------|
69
- | remotes | umd remotes | {} | {app2: "app@http://xxx.js"} |
70
- | dependencies.automatic | 自动匹配remotes和shared中同名的依赖项 | [ "shareScopes", "remotes"] | |
71
- | dependencies.referenceShares | 配置从 __ * shared* __ 中寻找umd的依赖 | {} | {react: {singleton: true, requiredVersion: "17"}} |
72
- | dependencies.referenceRemotes | 配置从remotes中寻找umd的依赖 | {} | {react: "app5"} |
73
- | runtimeUmdExposes | 如果umd包有多个入口,可以用这个函数解析入口 | ({$umdValue}) => return $umdValue | |
74
- | runtimeInject | 同 __ * UniversalModuleFederationPlugin* __ | | |
65
+ | options | desc | default | examles |
66
+ | -------------------------------| ------------------------------------------| ----------------------------| :--------------------------------------------------|
67
+ | remotes | umd remotes | {} | {app2: "app@http://xxx.js"} |
68
+ | dependencies.automatic | 自动匹配remotes和shared中同名的依赖项 | [ "shareScopes", "remotes"] | |
69
+ | dependencies.referenceShares | 配置从 __ * shared* __ 中寻找umd的依赖 | {} | {react: {singleton: true, requiredVersion: "17"}} |
70
+ | dependencies.referenceRemotes | 配置从remotes中寻找umd的依赖 | {} | {react: "app5"} |
71
+ | runtime | 同 __ * UniversalModuleFederationPlugin* __ | | |
75
72
76
- #### runtimeUmdExposes
73
+ #### runtime.get
77
74
``` js
78
- // $umdValue: umd模块的返回值
79
- // $moduleName: "./App" <=== import "umdRemote/App"
80
- runtimeUmdExposes ({ $umdValue, $moduleName }) {
81
- $moduleName = $moduleName .replace (/ ^ \.\/ ? / , " " )
82
- if ($moduleName) {
83
- return $umdValue[$moduleName]
75
+ // module: umd模块的返回值
76
+ // request: "./App" <=== import "umdRemote/App"
77
+ runtime: {
78
+ get ({ module , request}) {
79
+ request = request .replace (/ ^ \.\/ ? / , " " )
80
+ if (request) {
81
+ return module [request]
82
+ }
83
+ return module
84
84
}
85
- return $umdValue
86
85
}
87
86
```
88
87
@@ -99,11 +98,10 @@ const {UniversalModuleFederationPlugin} = require("universal-module-federation-p
99
98
plugins: [
100
99
new UniversalModuleFederationPlugin ({
101
100
remotes: {},
102
- runtimeInject : {
101
+ runtime : {
103
102
injectVars: {},
104
- initial : () => {},
105
- beforeImport (url , options ) {},
106
- import (url , options ) {}
103
+ initial : ({__umf__}) => {},
104
+ import ({url, name, remoteKey, __umf__}) {}
107
105
}
108
106
})
109
107
]
@@ -115,18 +113,18 @@ plugins: [
115
113
plugins: [
116
114
new UniversalModuleFederationPlugin ({
117
115
remotes: {},
118
- runtimeInject : {
119
- // 可以在以下任何runtime hooks中访问"__umf__.$ injectVars.testInjectVar"
116
+ runtime : {
117
+ // 可以在以下任何runtime hooks中访问"__umf__.injectVars.testInjectVar"
120
118
injectVars: {
121
119
testInjectVar: 111 ,
122
120
},
123
121
// 任意runtime hooks都会注入"__umf__"这个变量
124
- initial: async () => {
125
- const {$ getShare , $ getRemote , $ containerRemoteKeyMap , $ injectVars , $ context } = __umf__
126
- const testInjectVar = $ injectVars
122
+ initial: async ({__umf__} ) => {
123
+ const {getShare , getRemote , containerRemoteKeyMap , injectVars , context } = __umf__
124
+ const testInjectVar = injectVars
127
125
console .log (" __umf__" , __umf__, testInjectVar)
128
- // $ context is an empty object by default, used to pass values between multiple hooks
129
- $ context .testA = " testA"
126
+ // context is an empty object by default, used to pass values between multiple hooks
127
+ context .testA = " testA"
130
128
await new Promise (resolve => {
131
129
setTimeout (function () {
132
130
resolve ()
@@ -136,7 +134,7 @@ plugins: [
136
134
// remoteA: "a@http://remoteA.com"
137
135
// name: "a"
138
136
// remoteKey: "remoteA"
139
- import (url , { name, remoteKey}) {
137
+ import ({ url, name, remoteKey, __umf__ }) {
140
138
console .log (" __umf__" , __umf__)
141
139
return {
142
140
init (){},
@@ -156,26 +154,25 @@ plugins: [
156
154
157
155
## UniversalModuleFederationPlugin API
158
156
159
- | options | desc | default | examles |
160
- | -------------------------------------------------------| -------------------------------------------------------------------------------| --------------| :----------------------------|
161
- | remotes | umf remotes | {} | {app2: "app@http://xxx.js"} |
162
- | runtimeInject.injectVars | 为runtime hooks注入变量,任何运行时挂钩都可以使用"\_\_ umf\_\_ .$injectVars"访问 | {} | {test: 123} |
163
- | runtimeInject.initial(): promise | 初始化阶段的runtime hook | function(){} | |
164
- | runtimeInject.beforeImport(url, options): promise <url > | 准备引入remote时触发 | function(){} | |
165
- | runtimeInject.import(url, options): promise <module > | remote的引入钩子, 需要返回一个 container{init, get} | function(){} | |
157
+ | options | desc | default | examles |
158
+ | --------------------------------------------------------------| -------------------------------------------------------------------------------| --------------| :----------------------------|
159
+ | remotes | umf remotes | {} | {app2: "app@http://xxx.js"} |
160
+ | runtime.injectVars | 为runtime hooks注入变量,任何运行时挂钩都可以使用"\_\_ umf\_\_ .$injectVars"访问 | {} | {test: 123} |
161
+ | runtime.initial(): promise | 初始化阶段的runtime hook | function(){} | |
162
+ | runtime.import({url, name, remoteKey}): promise <module > | remote的引入钩子, 需要返回一个 container{init, get} | function(){} | |
166
163
167
164
#### \_\_ umf\_\_
168
165
169
166
任何运行时挂钩都会注入"\_\_ umf\_\_ "变量
170
167
171
- | property | desc | examles |
172
- | ----------------------------------------------------------------------| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------|
173
- | $ getRemote("request"): promise <module > | 用于获取远程模块, 与from处语法一致: import xxx from "xxxx/xxx" | $getRemote("app2/App") |
174
- | $ getShare(pkgname: string, {singleton, requiredVersion, ......}): promise <module > | 用于获取share, 第二个参数与shared.xxx配置一致 | $getShare("react", {singleton: true}) |
175
- | $ containerRemoteKeyMap: object | 如果配置了 remotes: {"@app2/xx ": "app3@http://xxx"} | 则可以这么获取remotes的映射: $ containerRemoteKeyMap.app3 --> "@app2/xx " |
176
- | $ injectVars: object | 插件配置的注入运行时的变量 | |
177
- | $ context: object | $context 默认为空对象,用于多个hook之间传递值 | $context.xxx = xxx |
178
- | - | - | - |
168
+ | property | desc | examles |
169
+ | ---------------------------------------------------------------------------------| ---------------------------------------------------------------| ------------------------------------------------------------------------|
170
+ | getRemote("request"): promise <module > | 用于获取远程模块, 与from处语法一致: import xxx from "xxxx/xxx" | getRemote("app2/App") |
171
+ | getShare(pkgname: string, {singleton, requiredVersion, ......}): promise <module > | 用于获取share, 第二个参数与shared.xxx配置一致 | getShare("react", {singleton: true}) |
172
+ | containerRemoteKeyMap: object | 如果配置了 remotes: {"@app2/xx ": "app3@http://xxx"} | 则可以这么获取remotes的映射: containerRemoteKeyMap.app3 --> "@app2/xx " |
173
+ | injectVars: object | 插件配置的注入运行时的变量 | |
174
+ | context: object | $context 默认为空对象,用于多个hook之间传递值 | context.xxx = xxx |
175
+ | - | - | - |
179
176
180
177
181
178
## 动态远程url示例
@@ -198,11 +195,11 @@ module.exports = {
198
195
app2: " app2@http://localhost:3000/remoteEntry.js" ,
199
196
" mf-app-01" : " mfapp01@mf-app-01@1.0.2/dist/remoteEntry.js"
200
197
},
201
- runtimeInject : {
198
+ runtime : {
202
199
resolvePath ({name, version, entry, query}) {
203
200
return ` https://cdn.jsdelivr.net/npm/${ name} @${ version} /${ entry} ?${ query} `
204
201
},
205
- async import (url , { name}) {
202
+ async import ({ url, name}) {
206
203
await new Promise (resolve => {
207
204
__webpack_require__ .l (url, resolve)
208
205
})
@@ -216,7 +213,7 @@ module.exports = {
216
213
217
214
## 运行时获取module-federation配置
218
215
219
- "runtimeInject " 可以设置为 function
216
+ "runtime " 可以设置为 function
220
217
221
218
``` js
222
219
// webpack.config.js
@@ -225,15 +222,57 @@ const {UniversalModuleFederationPlugin} = require("universal-module-federation-p
225
222
module .exports = {
226
223
plugins: [
227
224
new UniversalModuleFederationPlugin ({
228
- runtimeInject : (mfOptions ) => ({
225
+ runtime : (umfInstance ) => ({
229
226
injectVars: {
230
- mfOptions
227
+ mfOptions: umfInstance . mfOptions
231
228
},
232
- initial () {
229
+ initial ({__umf__} ) {
233
230
console .log (" mfOptions" , __umf__ .$injectVars .mfOptions )
234
231
}
235
232
})
236
233
}),
237
234
]
238
235
}
236
+ ```
237
+
238
+ ## 模块委托
239
+ ``` js
240
+ // webpack.config.js
241
+ const {UniversalModuleFederationPlugin } = require (" universal-module-federation-plugin" )
242
+
243
+ module .exports = {
244
+ plugins: [
245
+ new ModuleFederationPlugin ({
246
+ shared: { react: { singleton: true } },
247
+ }),
248
+ new UniversalModuleFederationPlugin ({
249
+ remotes: {
250
+ " mf-app-01" : " mfapp01@https://cdn.jsdelivr.net/npm/mf-app-01/dist/remoteEntry.js" ,
251
+ },
252
+ runtime: " ./src/remote-delegate.js"
253
+ }),
254
+ ]
255
+ }
256
+ ```
257
+ ``` js
258
+ // src/remote-delegate.js
259
+ console .log (" initial" )
260
+ module .exports .import = function ({url, name, remoteKey, __umf__}) {
261
+ return new Promise ((resolve , reject ) => {
262
+ const global = name
263
+ const __webpack_error__ = new Error ()
264
+ __webpack_require__ .l (
265
+ url,
266
+ function (event ) {
267
+ if (typeof window [global ] !== ' undefined' ) return resolve (window [global ]);
268
+ var realSrc = event && event .target && event .target .src ;
269
+ __webpack_error__ .message = ' Loading script failed.\\ n(' + event .message + ' : ' + realSrc + ' )' ;
270
+ __webpack_error__ .name = ' ScriptExternalLoadError' ;
271
+ __webpack_error__ .stack = event .stack ;
272
+ reject (__webpack_error__);
273
+ },
274
+ global ,
275
+ );
276
+ })
277
+ }
239
278
```
0 commit comments