@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.
Files changed (33) hide show
  1. package/README.md +43 -6
  2. package/package.json +16 -6
  3. package/src/index.d.ts +3 -0
  4. package/src/index.js +13 -0
  5. package/src/index.js.map +1 -0
  6. package/src/plugins/CommonJsChunkLoadingPlugin.d.ts +16 -0
  7. package/src/plugins/CommonJsChunkLoadingPlugin.js +83 -0
  8. package/src/plugins/CommonJsChunkLoadingPlugin.js.map +1 -0
  9. package/src/plugins/LoadFileChunkLoadingRuntimeModule.d.ts +29 -0
  10. package/src/plugins/LoadFileChunkLoadingRuntimeModule.js +333 -0
  11. package/src/plugins/LoadFileChunkLoadingRuntimeModule.js.map +1 -0
  12. package/src/plugins/NodeFederationPlugin.d.ts +16 -0
  13. package/src/plugins/NodeFederationPlugin.js +225 -0
  14. package/src/plugins/NodeFederationPlugin.js.map +1 -0
  15. package/src/plugins/StreamingTargetPlugin.d.ts +11 -0
  16. package/src/plugins/StreamingTargetPlugin.js +41 -0
  17. package/src/plugins/StreamingTargetPlugin.js.map +1 -0
  18. package/src/plugins/UniversalFederationPlugin.d.ts +16 -0
  19. package/src/plugins/UniversalFederationPlugin.js +26 -0
  20. package/src/plugins/UniversalFederationPlugin.js.map +1 -0
  21. package/src/plugins/loadScript.d.ts +6 -0
  22. package/src/{loadScript.js → plugins/loadScript.js} +4 -2
  23. package/src/plugins/loadScript.js.map +1 -0
  24. package/src/types/index.d.ts +3 -0
  25. package/src/types/index.js +3 -0
  26. package/src/types/index.js.map +1 -0
  27. package/LICENSE +0 -21
  28. package/index.js +0 -7
  29. package/src/CommonJsChunkLoadingPlugin.js +0 -89
  30. package/src/LoadFileChunkLoadingRuntimeModule.js +0 -410
  31. package/src/NodeFederationPlugin.js +0 -244
  32. package/src/StreamingTargetPlugin.js +0 -42
  33. 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
- module.exports = `
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,3 @@
1
+ import type { container } from 'webpack';
2
+ export declare type ModuleFederationPluginOptions = ConstructorParameters<typeof container.ModuleFederationPlugin>['0'];
3
+ export declare type RemotesObject = ModuleFederationPluginOptions['remotes'];
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -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;