Skip to content

Commit

Permalink
umf compeled
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangHongEn committed Nov 19, 2022
1 parent 01188e9 commit 7b76cbd
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 154 deletions.
4 changes: 2 additions & 2 deletions packages/umfjs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "umfjs",
"version": "0.3.0",
"version": "0.3.1",
"description": "universal module federation",
"main": "dist/index.js",
"devDependencies": {
Expand All @@ -16,7 +16,7 @@
"webpack-dev-server": "^4.0.0"
},
"dependencies": {
"semverhook": "^1.0.7",
"semverhook": "^1.1.0",
"systemjs": "^6.13.0"
},
"scripts": {
Expand Down
85 changes: 58 additions & 27 deletions packages/universal-module-federation-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,50 +70,81 @@ runtimeUmdExposes({ $umdValue, $moduleName }) {

## custom module specification

If you have modified systemjs, or you have your own module specification, you can use UniversalModuleFederationPlugin to integrate it. The following is the source code of UmdPlugin, and the explanation of each API will be updated after the documentation.
If you have your own module specification, you can use UniversalModuleFederationPlugin to integrate it.
UmdPlugin is implemented using this plugin, you can refer to the [UmdPlugin source code](./src/UmdPlugin.js)


``` js
// webpack.config.js

const PLUGIN_NAME = 'UmdPlugin';
const {UniversalModuleFederationPlugin} = require("universal-module-federation-plugin")

class UmdPlugin {
class CustomPlugin {

apply(compiler) {
new UniversalModuleFederationPlugin({
runtimeInject: ({$semverhook, $getShare, $getRemote, $containerRemoteKeyMap, $injectVars}) => {
const {interceptSystemAllDep} = require("umfjs")
const {System, eventBus} = interceptSystemAllDep()

$semverhook.on("import", (url) => {
includeRemotes: [/.*/],
excludeRemotes: [],
runtimeInject: {
// You can access "__umf__.$injectVars.testInjectVar" in any of the following runtime hooks
injectVars: {
testInjectVar: 111,
},
// any runtime hook can using "__umf__"
initial: () => {
const {$getShare, $getRemote, $containerRemoteKeyMap, $injectVars, $context} = __umf__
const testInjectVar = $injectVars
console.log("__umf__", __umf__, testInjectVar)
// $context is an empty object by default, used to pass values between multiple hooks
$context.testA = "testA"
},
beforeImport(url) {
console.log(__umf__.$context)
return new Promise(resolve => {
setTimeout(function () {
resolve(url)
}, 3000)
})
},
import(url) {
console.log("__umf__", __umf__)
return {
init(){},
async get(moduleName = "") {
const res = await System.import(url)
return function() {
return umdExposes({
$umdValue: res,
$moduleName: moduleName
})
return {
testModule: 123
}
}
}
}
})

eventBus.on("importDep", (dep) => {
if (referenceRemotes[dep]) {
return $getRemote(referenceRemotes[dep] || dep)
}
})
eventBus.on("importDep", (dep) => {
if (referenceShares[dep]) {
return $getShare(referenceShares[dep].import || dep, referenceShares[dep])
}
})
}
}
}).apply(compiler)
}

}
```
```

| options | desc | default | examles |
|----------------------------------------------|--------------------------------------------------------------------------------------------|--------------|:--------------------|
| includeRemotes | match umd remotes | [] | [/umd-app/, "app3"] |
| excludeRemotes | exclude umd remotes | [] | ["app2"] |
| runtimeInject.injectVars | Inject variables for other runtime hooks, any runtime hook can using "\_\_umf\_\_.$injectVars" | {} | {test: 123} |
| runtimeInject.initial() | initial runtime hooks | function(){} | |
| runtimeInject.beforeImport(url):promise<url> | Triggered before each remote is introduced | function(){} | |
| runtimeInject.import(url):promise<module> | Introduce the hook of remote, need to return a container{init, get} | function(){} |

#### \_\_umf\_\_

Any runtime hooks will inject the "\_\_umf\_\_" variable


| property | desc | examles |
|----------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|-------------------------------------------|
| $getRemote("request"):promise<module> | Get the remote module, same as import xxx from "xxxx/xxx" | $getRemote("app2/App") |
| $getShare(pkg, {singleton, requiredVersion, ......}):promise<module> | Get modules from shareScopes, same as "shared" configuration | $getShare("react", {singleton: true}) |
| $containerRemoteKeyMap: object | The container name corresponds to the map of the key configured by remotes
remotes: {"@app2/xx": "app3@http://xxx"} | $containerRemoteKeyMap.app3 // "@app2/xx" |
| $injectVars: object | Variables injected by plugins | |
| $context: object | $context is an empty object by default, used to pass values between multiple hooks | $context.xxx = xxx |

4 changes: 2 additions & 2 deletions packages/universal-module-federation-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "universal-module-federation-plugin",
"version": "0.3.2",
"version": "0.3.3",
"description": "Module federation supports the integration of various specifications, such as umd",
"main": "src/index.js",
"keywords": [
Expand All @@ -11,7 +11,7 @@
],
"devDependencies": {},
"dependencies": {
"semverhook": "^1.0.7",
"semverhook": "^1.1.0",
"inject-webpack": "^0.1.5",
"webpack-virtual-modules": "^0.4.6",
"umfjs": "^0.3.0"
Expand Down
107 changes: 107 additions & 0 deletions packages/universal-module-federation-plugin/src/UmdPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@

const PLUGIN_NAME = 'UmdPlugin';
const UniversalModuleFederationPlugin = require("./UniversalModuleFederationPlugin")

class UmdPlugin {
constructor(options = {}) {
options = Object.assign({
includeRemotes: [],
excludeRemotes: [],
dependencies: {
// referenceShares: {
// react: {
// singleton: true
// }
// },
// referenceRemotes: {
// "Button": "app5/Button"
// },
// automatic: ["remotes", "shareScopes"]
},
runtimeUmdExposes({$umdValue, $moduleName}) {
return $umdValue
}
}, options)
this.options = options
if (!options.dependencies.referenceShares) {
options.dependencies.referenceShares = {}
}
if (!options.dependencies.referenceRemotes) {
options.dependencies.referenceRemotes = {}
}
if (!options.dependencies.automatic) {
options.dependencies.automatic = ["remotes", "shareScopes"]
}
}

apply(compiler) {
new UniversalModuleFederationPlugin({
includeRemotes: this.options.includeRemotes,
excludeRemotes: this.options.excludeRemotes,
runtimeInject: {
injectVars: {
referenceShares: this.options.dependencies.referenceShares,
referenceRemotes: this.options.dependencies.referenceRemotes,
umdExposes: this.options.runtimeUmdExposes,
automatic: this.options.dependencies.automatic,
},
initial: () => {
const {$getShare, $getRemote, $containerRemoteKeyMap, $injectVars, $context} = __umf__
const {
referenceRemotes,
referenceShares,
automatic
} = $injectVars
const {interceptSystemAllDep} = require("umfjs")
const {System, eventBus} = interceptSystemAllDep()
$context.System = System
const isInterceptDepFromAllRemotes = automatic.indexOf("remotes") > -1
const isInterceptDepFromAllShares = automatic.indexOf("shareScopes") > -1

eventBus.on("importDep", (dep) => {
if (referenceRemotes[dep]) {
return $getRemote(referenceRemotes[dep] || dep)
}
if (isInterceptDepFromAllRemotes) {
const containerName = Object.keys($containerRemoteKeyMap).filter(function (containerName) {
const remoteKey = $containerRemoteKeyMap[containerName]
return remoteKey === dep
})[0]
return containerName && $getRemote(dep)
}
})
eventBus.on("importDep", (dep) => {
if (/^https?:/.test(dep)) return
if (referenceShares[dep]) {
return $getShare(referenceShares[dep].import || dep, referenceShares[dep])
}
if (isInterceptDepFromAllShares) {
return $getShare(dep, {singleton: true})
}
})
},
import(url) {
const {$injectVars} = __umf__
const {
umdExposes,
} = $injectVars
return {
init(){},
async get(moduleName = "") {
const res = await __umf__.$context.System.import(url)
return function() {
return umdExposes({
$umdValue: res,
$moduleName: moduleName
})
}
}
}
}
}
}).apply(compiler)
}

}

module.exports = UmdPlugin
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@ const PLUGIN_NAME = 'UniversalModuleFederationPlugin';
const {ExternalModule} = require("webpack")
const {ModuleFederationPlugin} = require("webpack").container
const stringifyHasFn = require("./utils/stringifyHasFn")

let hookIndex = 0

class UniversalModuleFederationPlugin {
constructor(options = {}) {
options = Object.assign({
includeRemotes: [],
excludeRemotes: [],
runtimeInject: function ({$semverhook, $getShare, $getRemote, $injectVars}) {},
runtimeInjectVars: {}
runtimeInject: {}
}, options)
options.runtimeInject = Object.assign({
injectVars: {},
initial(){},
beforeImport(){},
resolvePath() {},
resolveRequest() {},
import() {}
}, options.runtimeInject)
this.options = options
this.appName = ""
this.hookIndex = ++hookIndex
Expand All @@ -31,7 +39,8 @@ class UniversalModuleFederationPlugin {
$getRemote: null,
$getShare: null,
$containerRemoteKeyMap: null,
$injectVars: null
$injectVars: null,
$context: {}
}
if (!window.__umfplugin__semverhook_${this.appName}_${this.hookIndex}) {
;(function () {
Expand All @@ -56,16 +65,20 @@ class UniversalModuleFederationPlugin {
}
return (await window[containerName].get(moduleName))()
}
__umf__ = {
Object.assign(__umf__, {
$semverhook: window.__umfplugin__semverhook_${this.appName}_${this.hookIndex},
$getRemote,
$getShare,
$containerRemoteKeyMap: ${JSON.stringify(this.containerRemoteKeyMap)},
$injectVars: ${stringifyHasFn(this.options.runtimeInjectVars)}
}
})
})();
const injectFn = ${stringifyHasFn({ fn: this.options.runtimeInject })}.fn
injectFn(__umf__)
const __runtimeInject = ${stringifyHasFn(this.options.runtimeInject)}
__umf__.$injectVars = __runtimeInject.injectVars
__runtimeInject.initial()
__umf__.$semverhook.on("beforeImport", __runtimeInject.beforeImport)
__umf__.$semverhook.on("import", __runtimeInject.import)
__umf__.$semverhook.on("resolvePath", __runtimeInject.resolvePath)
__umf__.$semverhook.on("resolveRequest", __runtimeInject.resolveRequest)
}
`
new Inject(() => {
Expand Down
Loading

0 comments on commit 7b76cbd

Please sign in to comment.