@module-federation/node 0.1.0 → 0.2.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/README.md +43 -6
- package/package.json +16 -6
- package/src/index.d.ts +3 -0
- package/src/index.js +13 -0
- package/src/index.js.map +1 -0
- package/src/plugins/CommonJsChunkLoadingPlugin.d.ts +16 -0
- package/src/plugins/CommonJsChunkLoadingPlugin.js +83 -0
- package/src/plugins/CommonJsChunkLoadingPlugin.js.map +1 -0
- package/src/plugins/LoadFileChunkLoadingRuntimeModule.d.ts +29 -0
- package/src/plugins/LoadFileChunkLoadingRuntimeModule.js +333 -0
- package/src/plugins/LoadFileChunkLoadingRuntimeModule.js.map +1 -0
- package/src/plugins/NodeFederationPlugin.d.ts +16 -0
- package/src/plugins/NodeFederationPlugin.js +225 -0
- package/src/plugins/NodeFederationPlugin.js.map +1 -0
- package/src/plugins/StreamingTargetPlugin.d.ts +11 -0
- package/src/plugins/StreamingTargetPlugin.js +41 -0
- package/src/plugins/StreamingTargetPlugin.js.map +1 -0
- package/src/plugins/UniversalFederationPlugin.d.ts +16 -0
- package/src/plugins/UniversalFederationPlugin.js +26 -0
- package/src/plugins/UniversalFederationPlugin.js.map +1 -0
- package/src/plugins/loadScript.d.ts +6 -0
- package/src/{loadScript.js → plugins/loadScript.js} +4 -2
- package/src/plugins/loadScript.js.map +1 -0
- package/src/types/index.d.ts +3 -0
- package/src/types/index.js +3 -0
- package/src/types/index.js.map +1 -0
- package/LICENSE +0 -21
- package/index.js +0 -7
- package/src/CommonJsChunkLoadingPlugin.js +0 -89
- package/src/LoadFileChunkLoadingRuntimeModule.js +0 -410
- package/src/NodeFederationPlugin.js +0 -244
- package/src/StreamingTargetPlugin.js +0 -42
- package/src/UniversalFederationPlugin.js +0 -28
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// possible remote evaluators
|
|
4
|
+
// this depends on the chunk format selected.
|
|
5
|
+
// commonjs2 - it think, is lazily evaluated - beware
|
|
6
|
+
// const remote = eval(scriptContent + '\n try{' + moduleName + '}catch(e) { null; };');
|
|
7
|
+
// commonjs - fine to use but exports marker doesnt exist
|
|
8
|
+
// const remote = eval('let exports = {};' + scriptContent + 'exports');
|
|
9
|
+
// commonjs-module, ideal since it returns a commonjs module format
|
|
10
|
+
// const remote = eval(scriptContent + 'module.exports')
|
|
11
|
+
// Note on ESM.
|
|
12
|
+
// Its possible to use ESM import, but its impossible to invalidate the module cache
|
|
13
|
+
// So once something is imported, its stuck. This is problematic with at-runtime since we want to hot reload node
|
|
14
|
+
// if ESM were used, youd be forced to restart the process to re-import modules or use a worker pool
|
|
15
|
+
// Workaround is possible with query string on end of request, but this leaks memory badly
|
|
16
|
+
// with commonjs, we can at least reset the require cache to "reboot" webpack runtime
|
|
17
|
+
// It *can* leak memory, but ive not been able to replicate this to an extent that would be concerning.
|
|
18
|
+
// ESM WILL leak memory, big difference.
|
|
19
|
+
// Im talking with TC39 about a proposal around "virtual module trees" which would solve many problems.
|
|
20
|
+
// VMT is like Realms but better - easiest analogy would be like forking the main thread, without going off main thread
|
|
21
|
+
// VMT allows for scope isolation, but still allows reflection and non-primitive memory pointers to be shared - perfect for MFP
|
|
22
|
+
//TODO: should use extractUrlAndGlobal from internal.js
|
|
23
|
+
//TODO: should use Template system like LoadFileChunk runtime does.
|
|
24
|
+
//TODO: should use Template system like LoadFileChunk runtime does.
|
|
25
|
+
//TODO: global.webpackChunkLoad could use a better convention? I have to use a special http client to get out of my infra firewall
|
|
26
|
+
const executeLoadTemplate = `
|
|
27
|
+
function executeLoad(remoteUrl) {
|
|
28
|
+
function extractUrlAndGlobal(urlAndGlobal) {
|
|
29
|
+
var index = urlAndGlobal.indexOf("@");
|
|
30
|
+
if (index <= 0 || index === urlAndGlobal.length - 1) {
|
|
31
|
+
throw new Error("Invalid request " + urlAndGlobal);
|
|
32
|
+
}
|
|
33
|
+
return [urlAndGlobal.substring(index + 1), urlAndGlobal.substring(0, index)];
|
|
34
|
+
}
|
|
35
|
+
console.log('remoteUrl',remoteUrl)
|
|
36
|
+
const [scriptUrl, moduleName] = extractUrlAndGlobal(remoteUrl);
|
|
37
|
+
console.log("executing remote load", scriptUrl);
|
|
38
|
+
const vm = require('vm');
|
|
39
|
+
return new Promise(function (resolve, reject) {
|
|
40
|
+
|
|
41
|
+
(global.webpackChunkLoad || global.fetch || require("node-fetch"))(scriptUrl).then(function(res){
|
|
42
|
+
return res.text();
|
|
43
|
+
}).then(function(scriptContent){
|
|
44
|
+
try {
|
|
45
|
+
const vmContext = { exports, require, module, global, __filename, __dirname, URL };
|
|
46
|
+
|
|
47
|
+
const remote = vm.runInNewContext(scriptContent + '\\nmodule.exports', vmContext, { filename: 'node-federation-loader-' + moduleName + '.vm' });
|
|
48
|
+
|
|
49
|
+
/* TODO: need something like a chunk loading queue, this can lead to async issues
|
|
50
|
+
if two containers load the same remote, they can overwrite global scope
|
|
51
|
+
should check someone is already loading remote and await that */
|
|
52
|
+
global.__remote_scope__[moduleName] = remote[moduleName] || remote
|
|
53
|
+
resolve(global.__remote_scope__[moduleName])
|
|
54
|
+
} catch(e) {
|
|
55
|
+
console.error('problem executing remote module', moduleName);
|
|
56
|
+
reject(e);
|
|
57
|
+
}
|
|
58
|
+
}).catch((e)=>{
|
|
59
|
+
console.error('failed to fetch remote', moduleName, scriptUrl);
|
|
60
|
+
console.error(e);
|
|
61
|
+
reject(null)
|
|
62
|
+
})
|
|
63
|
+
}).catch((e)=>{
|
|
64
|
+
console.error('error',e);
|
|
65
|
+
console.warn(moduleName,'is offline, returning fake remote')
|
|
66
|
+
return {
|
|
67
|
+
fake: true,
|
|
68
|
+
get:(arg)=>{
|
|
69
|
+
console.log('faking', arg,'module on', moduleName);
|
|
70
|
+
|
|
71
|
+
return ()=> Promise.resolve();
|
|
72
|
+
},
|
|
73
|
+
init:()=>{}
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
function buildRemotes(mfConf, webpack) {
|
|
79
|
+
return Object.entries(mfConf.remotes || {}).reduce((acc, [name, config]) => {
|
|
80
|
+
// if its already been converted into promise, dont do it again
|
|
81
|
+
if (config.startsWith('promise ') || config.startsWith('external ')) {
|
|
82
|
+
acc.buildTime[name] = config;
|
|
83
|
+
return acc;
|
|
84
|
+
}
|
|
85
|
+
/*
|
|
86
|
+
TODO: global remote scope object should go into webpack runtime as a runtime requirement
|
|
87
|
+
this can be done by referencing my LoadFile, CommonJs plugins in this directory.
|
|
88
|
+
*/
|
|
89
|
+
const [global, url] = config.split('@');
|
|
90
|
+
const loadTemplate = `promise new Promise((resolve)=>{
|
|
91
|
+
if(!global.__remote_scope__) {
|
|
92
|
+
// create a global scope for container, similar to how remotes are set on window in the browser
|
|
93
|
+
global.__remote_scope__ = {
|
|
94
|
+
_config: {},
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
global.__remote_scope__._config[${JSON.stringify(global)}] = ${JSON.stringify(url)};
|
|
99
|
+
|
|
100
|
+
${executeLoadTemplate}
|
|
101
|
+
resolve(executeLoad(${JSON.stringify(config)}))
|
|
102
|
+
}).then(remote=>{
|
|
103
|
+
console.log(remote);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
get: remote.get,
|
|
107
|
+
init: (args)=> {
|
|
108
|
+
console.log(args)
|
|
109
|
+
return remote.init(args)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
`;
|
|
114
|
+
acc.buildTime[name] = loadTemplate;
|
|
115
|
+
return acc;
|
|
116
|
+
}, { runtime: {}, buildTime: {}, hot: {} });
|
|
117
|
+
//old design
|
|
118
|
+
return Object.entries(mfConf.remotes || {}).reduce((acc, [name, config]) => {
|
|
119
|
+
const hasMiddleware = config.startsWith('middleware ');
|
|
120
|
+
let middleware;
|
|
121
|
+
if (hasMiddleware) {
|
|
122
|
+
middleware = config.split('middleware ')[1];
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
middleware = `Promise.resolve(${JSON.stringify(config)})`;
|
|
126
|
+
}
|
|
127
|
+
const templateStart = `
|
|
128
|
+
var ${webpack.RuntimeGlobals.require} = ${webpack.RuntimeGlobals.require} ? ${webpack.RuntimeGlobals.require} : typeof arguments !== 'undefined' ? arguments[2] : false;
|
|
129
|
+
${executeLoadTemplate}
|
|
130
|
+
global.loadedRemotes = global.loadedRemotes || {};
|
|
131
|
+
if (global.loadedRemotes[${JSON.stringify(name)}]) {
|
|
132
|
+
return global.loadedRemotes[${JSON.stringify(name)}]
|
|
133
|
+
}
|
|
134
|
+
// if using modern output, then there are no arguments on the parent function scope, thus we need to get it via a window global.
|
|
135
|
+
|
|
136
|
+
var shareScope = (${webpack.RuntimeGlobals.require} && ${webpack.RuntimeGlobals.shareScopeMap}) ? ${webpack.RuntimeGlobals.shareScopeMap} : global.__webpack_share_scopes__
|
|
137
|
+
var name = ${JSON.stringify(name)}
|
|
138
|
+
`;
|
|
139
|
+
const template = `(remotesConfig) => new Promise((res) => {
|
|
140
|
+
console.log('in template promise',JSON.stringify(remotesConfig))
|
|
141
|
+
executeLoad(remotesConfig).then((remote) => {
|
|
142
|
+
|
|
143
|
+
return Promise.resolve(remote.init(shareScope.default)).then(() => {
|
|
144
|
+
return remote
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
.then(function (remote) {
|
|
148
|
+
const proxy = {
|
|
149
|
+
get: remote.get,
|
|
150
|
+
chunkMap: remote.chunkMap,
|
|
151
|
+
path: remotesConfig.toString(),
|
|
152
|
+
init: (arg) => {
|
|
153
|
+
try {
|
|
154
|
+
return remote.init(shareScope.default)
|
|
155
|
+
} catch (e) {
|
|
156
|
+
console.log('remote container already initialized')
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (remote.fake) {
|
|
161
|
+
res(proxy);
|
|
162
|
+
return null
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
Object.assign(global.loadedRemotes, {
|
|
166
|
+
[name]: proxy
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
res(global.loadedRemotes[name])
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
})`;
|
|
174
|
+
acc.runtime[name] = `()=> ${middleware}.then((remoteConfig)=>{
|
|
175
|
+
console.log('remoteConfig runtime',remoteConfig);
|
|
176
|
+
if(!global.REMOTE_CONFIG) {
|
|
177
|
+
global.REMOTE_CONFIG = {};
|
|
178
|
+
}
|
|
179
|
+
global.REMOTE_CONFIG[${JSON.stringify(name)}] = remoteConfig;
|
|
180
|
+
${templateStart}
|
|
181
|
+
const loadTemplate = ${template};
|
|
182
|
+
return loadTemplate(remoteConfig)
|
|
183
|
+
})`;
|
|
184
|
+
acc.buildTime[name] = `promise ${middleware}.then((remoteConfig)=>{
|
|
185
|
+
if(!global.REMOTE_CONFIG) {
|
|
186
|
+
global.REMOTE_CONFIG = {};
|
|
187
|
+
}
|
|
188
|
+
console.log('remoteConfig buildtime',remoteConfig);
|
|
189
|
+
global.REMOTE_CONFIG[${JSON.stringify(name)}] = remoteConfig;
|
|
190
|
+
${templateStart};
|
|
191
|
+
const loadTemplate = ${template};
|
|
192
|
+
return loadTemplate(remoteConfig)
|
|
193
|
+
})`;
|
|
194
|
+
acc.hot[name] = `()=> ${middleware}`;
|
|
195
|
+
return acc;
|
|
196
|
+
}, { runtime: {}, buildTime: {}, hot: {} });
|
|
197
|
+
}
|
|
198
|
+
class NodeFederationPlugin {
|
|
199
|
+
constructor({ experiments, ...options }, context) {
|
|
200
|
+
this.options = options || {};
|
|
201
|
+
this.context = context || {};
|
|
202
|
+
this.experiments = experiments || {};
|
|
203
|
+
}
|
|
204
|
+
apply(compiler) {
|
|
205
|
+
// When used with Next.js, context is needed to use Next.js webpack
|
|
206
|
+
const { webpack } = compiler;
|
|
207
|
+
const { buildTime, runtime, hot } = buildRemotes(this.options, webpack || require('webpack'));
|
|
208
|
+
const defs = {
|
|
209
|
+
'process.env.REMOTES': runtime,
|
|
210
|
+
'process.env.REMOTE_CONFIG': hot,
|
|
211
|
+
};
|
|
212
|
+
// new ((webpack && webpack.DefinePlugin) || require("webpack").DefinePlugin)(
|
|
213
|
+
// defs
|
|
214
|
+
// ).apply(compiler);
|
|
215
|
+
const pluginOptions = {
|
|
216
|
+
...this.options,
|
|
217
|
+
remotes: buildTime,
|
|
218
|
+
};
|
|
219
|
+
new (this.context.ModuleFederationPlugin ||
|
|
220
|
+
(webpack && webpack.container.ModuleFederationPlugin) ||
|
|
221
|
+
require('webpack/lib/container/ModuleFederationPlugin'))(pluginOptions).apply(compiler);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exports.default = NodeFederationPlugin;
|
|
225
|
+
//# sourceMappingURL=NodeFederationPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeFederationPlugin.js","sourceRoot":"","sources":["../../../../../packages/node/src/plugins/NodeFederationPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Compiler } from 'webpack';
|
|
2
|
+
import type { ModuleFederationPluginOptions } from '../types';
|
|
3
|
+
interface StreamingTargetOptions extends ModuleFederationPluginOptions {
|
|
4
|
+
promiseBaseURI?: string;
|
|
5
|
+
}
|
|
6
|
+
declare class StreamingTargetPlugin {
|
|
7
|
+
private options;
|
|
8
|
+
constructor(options: StreamingTargetOptions);
|
|
9
|
+
apply(compiler: Compiler): void;
|
|
10
|
+
}
|
|
11
|
+
export default StreamingTargetPlugin;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const CommonJsChunkLoadingPlugin_1 = tslib_1.__importDefault(require("./CommonJsChunkLoadingPlugin"));
|
|
5
|
+
class StreamingTargetPlugin {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = options || {};
|
|
8
|
+
}
|
|
9
|
+
apply(compiler) {
|
|
10
|
+
if (compiler.options.target) {
|
|
11
|
+
console.warn(`target should be set to false while using NodeSoftwareStreamRuntime plugin, actual target: ${compiler.options.target}`);
|
|
12
|
+
}
|
|
13
|
+
// When used with Next.js, context is needed to use Next.js webpack
|
|
14
|
+
const { webpack } = compiler;
|
|
15
|
+
// This will enable CommonJsChunkFormatPlugin
|
|
16
|
+
compiler.options.output.chunkFormat = 'commonjs';
|
|
17
|
+
// This will force async chunk loading
|
|
18
|
+
compiler.options.output.chunkLoading = 'async-node';
|
|
19
|
+
// Disable default config
|
|
20
|
+
// FIXME: enabledChunkLoadingTypes is of type 'string[] | undefined'
|
|
21
|
+
// Can't use the 'false' value as it isn't the right format,
|
|
22
|
+
// Perhaps delete the option might solve our use case.
|
|
23
|
+
// compiler.options.output.enabledChunkLoadingTypes = false;
|
|
24
|
+
delete compiler.options.output.enabledChunkLoadingTypes;
|
|
25
|
+
new ((webpack && webpack.node && webpack.node.NodeEnvironmentPlugin) ||
|
|
26
|
+
require('webpack/lib/node/NodeEnvironmentPlugin'))({
|
|
27
|
+
infrastructureLogging: compiler.options.infrastructureLogging,
|
|
28
|
+
}).apply(compiler);
|
|
29
|
+
new ((webpack && webpack.node && webpack.node.NodeTargetPlugin) ||
|
|
30
|
+
require('webpack/lib/node/NodeTargetPlugin'))().apply(compiler);
|
|
31
|
+
new CommonJsChunkLoadingPlugin_1.default({
|
|
32
|
+
asyncChunkLoading: true,
|
|
33
|
+
name: this.options.name,
|
|
34
|
+
remotes: this.options.remotes,
|
|
35
|
+
baseURI: compiler.options.output.publicPath,
|
|
36
|
+
promiseBaseURI: this.options.promiseBaseURI,
|
|
37
|
+
}).apply(compiler);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.default = StreamingTargetPlugin;
|
|
41
|
+
//# sourceMappingURL=StreamingTargetPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingTargetPlugin.js","sourceRoot":"","sources":["../../../../../packages/node/src/plugins/StreamingTargetPlugin.ts"],"names":[],"mappings":";;;AAGA,sGAAsE;AAStE,MAAM,qBAAqB;IAGzB,YAAY,OAA+B;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,QAAkB;QACtB,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE;YAC3B,OAAO,CAAC,IAAI,CACV,8FAA8F,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,CACxH,CAAC;SACH;QAED,mEAAmE;QACnE,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;QAE7B,6CAA6C;QAC7C,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,GAAG,UAAU,CAAC;QACjD,sCAAsC;QACtC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;QAEpD,yBAAyB;QACzB,oEAAoE;QACpE,4DAA4D;QAC5D,sDAAsD;QAEtD,4DAA4D;QAC5D,OAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC;QAExD,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC;YAClE,OAAO,CAAC,wCAAwC,CAAC,CAAC,CAAC;YACnD,qBAAqB,EAAE,QAAQ,CAAC,OAAO,CAAC,qBAAqB;SAC9D,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAEnB,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC;YAC7D,OAAO,CAAC,mCAAmC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElE,IAAI,oCAA0B,CAAC;YAC7B,iBAAiB,EAAE,IAAI;YACvB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAiC;YACvD,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU;YAC3C,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;SAC5C,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;CACF;AAED,kBAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ModuleFederationPluginOptions } from '../types';
|
|
2
|
+
import type { Compiler, container } from 'webpack';
|
|
3
|
+
interface NodeFederationOptions extends ModuleFederationPluginOptions {
|
|
4
|
+
isServer: boolean;
|
|
5
|
+
promiseBaseURI?: string;
|
|
6
|
+
}
|
|
7
|
+
interface NodeFederationContext {
|
|
8
|
+
ModuleFederationPlugin?: typeof container.ModuleFederationPlugin;
|
|
9
|
+
}
|
|
10
|
+
declare class UniversalFederationPlugin {
|
|
11
|
+
private options;
|
|
12
|
+
private context;
|
|
13
|
+
constructor(options: NodeFederationOptions, context: NodeFederationContext);
|
|
14
|
+
apply(compiler: Compiler): void;
|
|
15
|
+
}
|
|
16
|
+
export default UniversalFederationPlugin;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const StreamingTargetPlugin_1 = tslib_1.__importDefault(require("./StreamingTargetPlugin"));
|
|
5
|
+
const NodeFederationPlugin_1 = tslib_1.__importDefault(require("./NodeFederationPlugin"));
|
|
6
|
+
class UniversalFederationPlugin {
|
|
7
|
+
constructor(options, context) {
|
|
8
|
+
this.options = options || {};
|
|
9
|
+
this.context = context || {};
|
|
10
|
+
}
|
|
11
|
+
apply(compiler) {
|
|
12
|
+
const isServer = this.options.isServer || compiler.options.name === 'server';
|
|
13
|
+
const { webpack } = compiler;
|
|
14
|
+
if (isServer) {
|
|
15
|
+
new NodeFederationPlugin_1.default(this.options, this.context).apply(compiler);
|
|
16
|
+
new StreamingTargetPlugin_1.default(this.options).apply(compiler);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
new (this.context.ModuleFederationPlugin ||
|
|
20
|
+
(webpack && webpack.container.ModuleFederationPlugin) ||
|
|
21
|
+
require('webpack/lib/container/ModuleFederationPlugin'))(this.options).apply(compiler);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.default = UniversalFederationPlugin;
|
|
26
|
+
//# sourceMappingURL=UniversalFederationPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UniversalFederationPlugin.js","sourceRoot":"","sources":["../../../../../packages/node/src/plugins/UniversalFederationPlugin.ts"],"names":[],"mappings":";;;AAAA,4FAA4D;AAC5D,0FAA0D;AAa1D,MAAM,yBAAyB;IAI7B,YAAY,OAA8B,EAAE,OAA8B;QACxE,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,QAAkB;QACtB,MAAM,QAAQ,GACZ,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC;QAC9D,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;QAE7B,IAAI,QAAQ,EAAE;YACZ,IAAI,8BAAoB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACrE,IAAI,+BAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;SACzD;aAAM;YACL,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB;gBACtC,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,sBAAsB,CAAC;gBACrD,OAAO,CAAC,8CAA8C,CAAC,CAAC,CACxD,IAAI,CAAC,OAAO,CACb,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;SACnB;IACH,CAAC;CACF;AAED,kBAAe,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loadScript(baseURI, fileName, cb)
|
|
3
|
+
* loadScript(scriptUrl, cb)
|
|
4
|
+
*/
|
|
5
|
+
declare const _default: "\n function loadScript(url,cb,chunkID) {\n var url;\n var cb = arguments[arguments.length - 1];\n if (typeof cb !== \"function\") {\n throw new Error(\"last argument should be a function\");\n }\n if (arguments.length === 2) {\n url = arguments[0];\n } else if (arguments.length === 3) {\n url = new URL(arguments[1], arguments[0]).toString();\n } else {\n throw new Error(\"invalid number of arguments\");\n }\n if(global.webpackChunkLoad){\n global.webpackChunkLoad(url).then(function(resp){\n return resp.text();\n }).then(function(rawData){\n cb(null, rawData);\n }).catch(function(err){\n console.error('Federated Chunk load failed', error);\n return cb(error)\n });\n } else {\n //TODO https support\n let request = (url.startsWith('https') ? require('https') : require('http')).get(url, function (resp) {\n if (resp.statusCode === 200) {\n let rawData = '';\n resp.setEncoding('utf8');\n resp.on('data', chunk => {\n rawData += chunk;\n });\n resp.on('end', () => {\n cb(null, rawData);\n });\n } else {\n cb(resp);\n }\n });\n request.on('error', error => {\n console.error('Federated Chunk load failed', error);\n return cb(error)\n });\n }\n }\n";
|
|
6
|
+
export default _default;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* loadScript(baseURI, fileName, cb)
|
|
3
4
|
* loadScript(scriptUrl, cb)
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.default = `
|
|
7
8
|
function loadScript(url,cb,chunkID) {
|
|
8
9
|
var url;
|
|
9
10
|
var cb = arguments[arguments.length - 1];
|
|
@@ -49,3 +50,4 @@ module.exports = `
|
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
`;
|
|
53
|
+
//# sourceMappingURL=loadScript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadScript.js","sourceRoot":"","sources":["../../../../../packages/node/src/plugins/loadScript.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,kBAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Cd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/node/src/types/index.ts"],"names":[],"mappings":""}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2020 ScriptedAlchemy LLC (Zack Jackson)
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/index.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const NodeFederationPlugin = require('./src/NodeFederationPlugin');
|
|
2
|
-
const StreamingTargetPlugin = require('./src/StreamingTargetPlugin');
|
|
3
|
-
const UniversalFederationPlugin = require('./src/UniversalFederationPlugin');
|
|
4
|
-
|
|
5
|
-
module.exports.NodeFederationPlugin = NodeFederationPlugin;
|
|
6
|
-
module.exports.StreamingTargetPlugin = StreamingTargetPlugin;
|
|
7
|
-
module.exports.UniversalFederationPlugin = UniversalFederationPlugin;
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const RuntimeGlobals = require('webpack/lib/RuntimeGlobals');
|
|
2
|
-
const StartupChunkDependenciesPlugin = require('webpack/lib/runtime/StartupChunkDependenciesPlugin');
|
|
3
|
-
const ChunkLoadingRuntimeModule = require('./LoadFileChunkLoadingRuntimeModule');
|
|
4
|
-
|
|
5
|
-
class CommonJsChunkLoadingPlugin {
|
|
6
|
-
constructor(options) {
|
|
7
|
-
this.options = options || {};
|
|
8
|
-
this._asyncChunkLoading = this.options.asyncChunkLoading;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Apply the plugin
|
|
13
|
-
* @param {Compiler} compiler the compiler instance
|
|
14
|
-
* @returns {void}
|
|
15
|
-
*/
|
|
16
|
-
apply(compiler) {
|
|
17
|
-
const chunkLoadingValue = this._asyncChunkLoading
|
|
18
|
-
? 'async-node'
|
|
19
|
-
: 'require';
|
|
20
|
-
new StartupChunkDependenciesPlugin({
|
|
21
|
-
chunkLoading: chunkLoadingValue,
|
|
22
|
-
asyncChunkLoading: this._asyncChunkLoading,
|
|
23
|
-
}).apply(compiler);
|
|
24
|
-
compiler.hooks.thisCompilation.tap(
|
|
25
|
-
'CommonJsChunkLoadingPlugin',
|
|
26
|
-
(compilation) => {
|
|
27
|
-
// Always enabled
|
|
28
|
-
const isEnabledForChunk = () => true;
|
|
29
|
-
const onceForChunkSet = new WeakSet();
|
|
30
|
-
const handler = (chunk, set) => {
|
|
31
|
-
if (onceForChunkSet.has(chunk)) return;
|
|
32
|
-
onceForChunkSet.add(chunk);
|
|
33
|
-
if (!isEnabledForChunk(chunk)) return;
|
|
34
|
-
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
|
35
|
-
set.add(RuntimeGlobals.hasOwnProperty);
|
|
36
|
-
compilation.addRuntimeModule(
|
|
37
|
-
chunk,
|
|
38
|
-
new ChunkLoadingRuntimeModule(set, this.options, {
|
|
39
|
-
webpack: compiler.webpack,
|
|
40
|
-
})
|
|
41
|
-
);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
compilation.hooks.runtimeRequirementInTree
|
|
45
|
-
.for(RuntimeGlobals.ensureChunkHandlers)
|
|
46
|
-
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
47
|
-
compilation.hooks.runtimeRequirementInTree
|
|
48
|
-
.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
|
49
|
-
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
50
|
-
compilation.hooks.runtimeRequirementInTree
|
|
51
|
-
.for(RuntimeGlobals.hmrDownloadManifest)
|
|
52
|
-
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
53
|
-
compilation.hooks.runtimeRequirementInTree
|
|
54
|
-
.for(RuntimeGlobals.baseURI)
|
|
55
|
-
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
56
|
-
compilation.hooks.runtimeRequirementInTree
|
|
57
|
-
.for(RuntimeGlobals.externalInstallChunk)
|
|
58
|
-
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
59
|
-
compilation.hooks.runtimeRequirementInTree
|
|
60
|
-
.for(RuntimeGlobals.onChunksLoaded)
|
|
61
|
-
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
62
|
-
|
|
63
|
-
compilation.hooks.runtimeRequirementInTree
|
|
64
|
-
.for(RuntimeGlobals.ensureChunkHandlers)
|
|
65
|
-
.tap('CommonJsChunkLoadingPlugin', (chunk, set) => {
|
|
66
|
-
if (!isEnabledForChunk(chunk)) return;
|
|
67
|
-
set.add(RuntimeGlobals.getChunkScriptFilename);
|
|
68
|
-
});
|
|
69
|
-
compilation.hooks.runtimeRequirementInTree
|
|
70
|
-
.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
|
71
|
-
.tap('CommonJsChunkLoadingPlugin', (chunk, set) => {
|
|
72
|
-
if (!isEnabledForChunk(chunk)) return;
|
|
73
|
-
set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
|
|
74
|
-
set.add(RuntimeGlobals.moduleCache);
|
|
75
|
-
set.add(RuntimeGlobals.hmrModuleData);
|
|
76
|
-
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
|
77
|
-
});
|
|
78
|
-
compilation.hooks.runtimeRequirementInTree
|
|
79
|
-
.for(RuntimeGlobals.hmrDownloadManifest)
|
|
80
|
-
.tap('CommonJsChunkLoadingPlugin', (chunk, set) => {
|
|
81
|
-
if (!isEnabledForChunk(chunk)) return;
|
|
82
|
-
set.add(RuntimeGlobals.getUpdateManifestFilename);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
module.exports = CommonJsChunkLoadingPlugin;
|