@module-federation/vite 1.8.1 → 1.9.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 +10 -0
- package/lib/index.cjs +47 -26
- package/lib/index.esm.js +47 -26
- package/lib/index.modern.js +66 -34
- package/lib/index.umd.js +50 -29
- package/lib/plugins/pluginAddEntry.d.ts +2 -1
- package/lib/utils/mapCodeToCodeWithSourcemap.d.ts +4 -0
- package/lib/utils/normalizeModuleFederationOptions.d.ts +18 -1
- package/package.json +21 -18
package/README.md
CHANGED
|
@@ -109,6 +109,15 @@ export default defineConfig({
|
|
|
109
109
|
},
|
|
110
110
|
filename: "remoteEntry.js",
|
|
111
111
|
shared: ["vue"],
|
|
112
|
+
// Optional parameter that controls where the host initialization script is injected.
|
|
113
|
+
// By default, it is injected into the index.html file.
|
|
114
|
+
// You can set this to "entry" to inject it into the entry script instead.
|
|
115
|
+
// Useful if your application does not load from index.html.
|
|
116
|
+
hostInitInjectLocation: "html", // or "entry"
|
|
117
|
+
// Controls whether all CSS assets from the bundle should be added to every exposed module.
|
|
118
|
+
// When false (default), the plugin will not process any CSS assets.
|
|
119
|
+
// When true, all CSS assets are bundled into every exposed module.
|
|
120
|
+
bundleAllCSS: false, // or true
|
|
112
121
|
}),
|
|
113
122
|
],
|
|
114
123
|
server: {
|
|
@@ -124,6 +133,7 @@ export default defineConfig({
|
|
|
124
133
|
```
|
|
125
134
|
|
|
126
135
|
The host app configuration specifies its name, the filename of its exposed remote entry remoteEntry.js, and importantly, the configuration of the remote application to load.
|
|
136
|
+
You can specify the place the host initialization file is injected with the **hostInitInjectLocation** option, which is described in the example code above.
|
|
127
137
|
|
|
128
138
|
## Load the Remote App
|
|
129
139
|
|
package/lib/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var defu = require('defu');
|
|
2
2
|
var fs = require('fs');
|
|
3
3
|
var path = require('pathe');
|
|
4
|
+
var MagicString = require('magic-string');
|
|
4
5
|
var pluginutils = require('@rollup/pluginutils');
|
|
5
6
|
var estreeWalker = require('estree-walker');
|
|
6
|
-
var MagicString = require('magic-string');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
9
|
|
|
@@ -31,6 +31,21 @@ var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
|
31
31
|
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
32
32
|
var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
|
|
33
33
|
|
|
34
|
+
var mapCodeToCodeWithSourcemap = function mapCodeToCodeWithSourcemap(code) {
|
|
35
|
+
return Promise.resolve(code).then(function (resolvedCode) {
|
|
36
|
+
if (resolvedCode === undefined) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
var s = new MagicString__default["default"](resolvedCode);
|
|
40
|
+
return {
|
|
41
|
+
code: s.toString(),
|
|
42
|
+
map: s.generateMap({
|
|
43
|
+
hires: true
|
|
44
|
+
})
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
34
49
|
function getFirstHtmlEntryFile(entryFiles) {
|
|
35
50
|
return entryFiles.find(function (file) {
|
|
36
51
|
return file.endsWith('.html');
|
|
@@ -150,7 +165,7 @@ var addEntry = function addEntry(_ref) {
|
|
|
150
165
|
return id.endsWith(file);
|
|
151
166
|
})) {
|
|
152
167
|
var injection = "\n import " + JSON.stringify(entryPath) + ";\n ";
|
|
153
|
-
return injection + code;
|
|
168
|
+
return mapCodeToCodeWithSourcemap(injection + code);
|
|
154
169
|
}
|
|
155
170
|
}
|
|
156
171
|
}];
|
|
@@ -383,6 +398,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
383
398
|
scope: 'default',
|
|
384
399
|
from: '',
|
|
385
400
|
shareConfig: {
|
|
401
|
+
"import": undefined,
|
|
386
402
|
singleton: false,
|
|
387
403
|
requiredVersion: version ? "^" + version : '*'
|
|
388
404
|
}
|
|
@@ -394,6 +410,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
394
410
|
version: shareItem.version || version,
|
|
395
411
|
scope: shareItem.shareScope || 'default',
|
|
396
412
|
shareConfig: {
|
|
413
|
+
"import": typeof shareItem === 'object' ? shareItem["import"] : undefined,
|
|
397
414
|
singleton: shareItem.singleton || false,
|
|
398
415
|
requiredVersion: shareItem.requiredVersion || (version ? "^" + version : '*'),
|
|
399
416
|
strictVersion: !!shareItem.strictVersion
|
|
@@ -468,7 +485,9 @@ function normalizeModuleFederationOptions(options) {
|
|
|
468
485
|
publicPath: options.publicPath,
|
|
469
486
|
shareStrategy: options.shareStrategy || 'version-first',
|
|
470
487
|
ignoreOrigin: options.ignoreOrigin || false,
|
|
471
|
-
virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
|
|
488
|
+
virtualModuleDir: options.virtualModuleDir || '__mf__virtual',
|
|
489
|
+
hostInitInjectLocation: options.hostInitInjectLocation || 'html',
|
|
490
|
+
bundleAllCSS: options.bundleAllCSS || false
|
|
472
491
|
};
|
|
473
492
|
}
|
|
474
493
|
|
|
@@ -732,12 +751,13 @@ function writeLocalSharedImportMap() {
|
|
|
732
751
|
}
|
|
733
752
|
function generateLocalSharedImportMap() {
|
|
734
753
|
var options = getNormalizeModuleFederationOptions();
|
|
735
|
-
return "\n const importMap = {\n " + Array.from(getUsedShares()).sort().map(function (pkg) {
|
|
736
|
-
|
|
754
|
+
return "\n import {loadShare} from \"@module-federation/runtime\";\n const importMap = {\n " + Array.from(getUsedShares()).sort().map(function (pkg) {
|
|
755
|
+
var shareItem = getNormalizeShareItem(pkg);
|
|
756
|
+
return "\n " + JSON.stringify(pkg) + ": async () => {\n " + ((shareItem == null ? void 0 : shareItem.shareConfig["import"]) === false ? "throw new Error(`Shared module '${" + JSON.stringify(pkg) + "}' must be provided by host`);" : "let pkg = await import(\"" + getPreBuildLibImportId(pkg) + "\");\n return pkg;") + "\n }\n ";
|
|
737
757
|
}).join(',') + "\n }\n const usedShared = {\n " + Array.from(getUsedShares()).sort().map(function (key) {
|
|
738
758
|
var shareItem = getNormalizeShareItem(key);
|
|
739
759
|
if (!shareItem) return null;
|
|
740
|
-
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n usedShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = importMap
|
|
760
|
+
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n if (" + (shareItem.shareConfig["import"] === false) + ") {\n throw new Error(`Shared module '${" + JSON.stringify(key) + "}' must be provided by host`);\n }\n usedShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = importMap\n const res = await pkgDynamicImport()\n const exportModule = {...res}\n // All npm packages pre-built by vite will be converted to esm\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return function () {\n return exportModule\n }\n },\n shareConfig: {\n singleton: " + shareItem.shareConfig.singleton + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + ",\n " + (shareItem.shareConfig["import"] === false ? 'import: false,' : '') + "\n }\n }\n ";
|
|
741
761
|
}).filter(function (x) {
|
|
742
762
|
return x !== null;
|
|
743
763
|
}).join(',') + "\n }\n const usedRemotes = [" + Object.keys(getUsedRemotesMap()).map(function (key) {
|
|
@@ -767,7 +787,7 @@ function generateRemoteEntry(options) {
|
|
|
767
787
|
var HOST_AUTO_INIT_TAG = '__H_A_I__';
|
|
768
788
|
var hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
|
|
769
789
|
function writeHostAutoInit() {
|
|
770
|
-
hostAutoInitModule.writeSync("\n const remoteEntryPromise = import(\"" + REMOTE_ENTRY_ID + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await
|
|
790
|
+
hostAutoInitModule.writeSync("\n const remoteEntryPromise = import(\"" + REMOTE_ENTRY_ID + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
|
|
771
791
|
}
|
|
772
792
|
function getHostAutoInitImportId() {
|
|
773
793
|
return hostAutoInitModule.getImportId();
|
|
@@ -1092,7 +1112,7 @@ var Manifest = function Manifest() {
|
|
|
1092
1112
|
}
|
|
1093
1113
|
}
|
|
1094
1114
|
// Second pass: Collect all CSS assets
|
|
1095
|
-
var allCssAssets = collectCssAssets(bundle);
|
|
1115
|
+
var allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : new Set();
|
|
1096
1116
|
var exposesModules = Object.keys(mfOptions.exposes).map(function (item) {
|
|
1097
1117
|
return mfOptions.exposes[item]["import"];
|
|
1098
1118
|
});
|
|
@@ -1120,8 +1140,10 @@ var Manifest = function Manifest() {
|
|
|
1120
1140
|
processModuleAssets(bundle, filesMap, function (modulePath) {
|
|
1121
1141
|
return fileToShareKey.get(modulePath);
|
|
1122
1142
|
});
|
|
1123
|
-
// Add all CSS assets to every export
|
|
1124
|
-
|
|
1143
|
+
// Add all CSS assets to every export if bundleAllCSS is enabled
|
|
1144
|
+
if (mfOptions.bundleAllCSS) {
|
|
1145
|
+
addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
1146
|
+
}
|
|
1125
1147
|
// Final deduplication of all assets
|
|
1126
1148
|
filesMap = deduplicateAssets(filesMap);
|
|
1127
1149
|
_this.emitFile({
|
|
@@ -1320,15 +1342,15 @@ function pluginProxyRemoteEntry () {
|
|
|
1320
1342
|
}
|
|
1321
1343
|
},
|
|
1322
1344
|
transform: function transform(code, id) {
|
|
1323
|
-
|
|
1324
|
-
if (!filter(id)) return
|
|
1345
|
+
var transformedCode = function () {
|
|
1346
|
+
if (!filter(id)) return;
|
|
1325
1347
|
if (id.includes(REMOTE_ENTRY_ID)) {
|
|
1326
|
-
return
|
|
1348
|
+
return parsePromise.then(function (_) {
|
|
1327
1349
|
return generateRemoteEntry(getNormalizeModuleFederationOptions());
|
|
1328
|
-
})
|
|
1350
|
+
});
|
|
1329
1351
|
}
|
|
1330
1352
|
if (id === VIRTUAL_EXPOSES) {
|
|
1331
|
-
return
|
|
1353
|
+
return generateExposes();
|
|
1332
1354
|
}
|
|
1333
1355
|
if (id.includes(getHostAutoInitPath())) {
|
|
1334
1356
|
var options = getNormalizeModuleFederationOptions();
|
|
@@ -1336,14 +1358,12 @@ function pluginProxyRemoteEntry () {
|
|
|
1336
1358
|
var _viteConfig$server, _viteConfig$server2;
|
|
1337
1359
|
var host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
|
|
1338
1360
|
var publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
|
|
1339
|
-
return
|
|
1361
|
+
return "\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + " + publicPath + ")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ";
|
|
1340
1362
|
}
|
|
1341
|
-
return
|
|
1363
|
+
return code;
|
|
1342
1364
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
return Promise.reject(e);
|
|
1346
|
-
}
|
|
1365
|
+
}();
|
|
1366
|
+
return mapCodeToCodeWithSourcemap(transformedCode);
|
|
1347
1367
|
}
|
|
1348
1368
|
};
|
|
1349
1369
|
}
|
|
@@ -1422,11 +1442,11 @@ function proxySharedModule(options) {
|
|
|
1422
1442
|
});
|
|
1423
1443
|
}
|
|
1424
1444
|
},
|
|
1425
|
-
transform: function transform(
|
|
1445
|
+
transform: function transform(_, id) {
|
|
1426
1446
|
if (id.includes(getLocalSharedImportMapPath())) {
|
|
1427
|
-
return parsePromise.then(function (_) {
|
|
1447
|
+
return mapCodeToCodeWithSourcemap(parsePromise.then(function (_) {
|
|
1428
1448
|
return generateLocalSharedImportMap();
|
|
1429
|
-
});
|
|
1449
|
+
}));
|
|
1430
1450
|
}
|
|
1431
1451
|
}
|
|
1432
1452
|
}, {
|
|
@@ -1533,7 +1553,8 @@ function federation(mfUserOptions) {
|
|
|
1533
1553
|
var options = normalizeModuleFederationOptions(mfUserOptions);
|
|
1534
1554
|
var name = options.name,
|
|
1535
1555
|
shared = options.shared,
|
|
1536
|
-
filename = options.filename
|
|
1556
|
+
filename = options.filename,
|
|
1557
|
+
hostInitInjectLocation = options.hostInitInjectLocation;
|
|
1537
1558
|
if (!name) throw new Error('name is required');
|
|
1538
1559
|
return [{
|
|
1539
1560
|
name: 'vite:module-federation-config',
|
|
@@ -1552,7 +1573,7 @@ function federation(mfUserOptions) {
|
|
|
1552
1573
|
}), addEntry({
|
|
1553
1574
|
entryName: 'hostInit',
|
|
1554
1575
|
entryPath: getHostAutoInitPath(),
|
|
1555
|
-
inject:
|
|
1576
|
+
inject: hostInitInjectLocation
|
|
1556
1577
|
}), addEntry({
|
|
1557
1578
|
entryName: 'virtualExposes',
|
|
1558
1579
|
entryPath: VIRTUAL_EXPOSES
|
package/lib/index.esm.js
CHANGED
|
@@ -3,9 +3,24 @@ import * as fs from 'fs';
|
|
|
3
3
|
import { mkdirSync, writeFileSync, existsSync, writeFile } from 'fs';
|
|
4
4
|
import * as path from 'pathe';
|
|
5
5
|
import path__default, { resolve, basename, parse, join, dirname } from 'pathe';
|
|
6
|
+
import MagicString from 'magic-string';
|
|
6
7
|
import { createFilter } from '@rollup/pluginutils';
|
|
7
8
|
import { walk } from 'estree-walker';
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
var mapCodeToCodeWithSourcemap = function mapCodeToCodeWithSourcemap(code) {
|
|
11
|
+
return Promise.resolve(code).then(function (resolvedCode) {
|
|
12
|
+
if (resolvedCode === undefined) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
var s = new MagicString(resolvedCode);
|
|
16
|
+
return {
|
|
17
|
+
code: s.toString(),
|
|
18
|
+
map: s.generateMap({
|
|
19
|
+
hires: true
|
|
20
|
+
})
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
};
|
|
9
24
|
|
|
10
25
|
function getFirstHtmlEntryFile(entryFiles) {
|
|
11
26
|
return entryFiles.find(function (file) {
|
|
@@ -126,7 +141,7 @@ var addEntry = function addEntry(_ref) {
|
|
|
126
141
|
return id.endsWith(file);
|
|
127
142
|
})) {
|
|
128
143
|
var injection = "\n import " + JSON.stringify(entryPath) + ";\n ";
|
|
129
|
-
return injection + code;
|
|
144
|
+
return mapCodeToCodeWithSourcemap(injection + code);
|
|
130
145
|
}
|
|
131
146
|
}
|
|
132
147
|
}];
|
|
@@ -359,6 +374,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
359
374
|
scope: 'default',
|
|
360
375
|
from: '',
|
|
361
376
|
shareConfig: {
|
|
377
|
+
"import": undefined,
|
|
362
378
|
singleton: false,
|
|
363
379
|
requiredVersion: version ? "^" + version : '*'
|
|
364
380
|
}
|
|
@@ -370,6 +386,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
370
386
|
version: shareItem.version || version,
|
|
371
387
|
scope: shareItem.shareScope || 'default',
|
|
372
388
|
shareConfig: {
|
|
389
|
+
"import": typeof shareItem === 'object' ? shareItem["import"] : undefined,
|
|
373
390
|
singleton: shareItem.singleton || false,
|
|
374
391
|
requiredVersion: shareItem.requiredVersion || (version ? "^" + version : '*'),
|
|
375
392
|
strictVersion: !!shareItem.strictVersion
|
|
@@ -444,7 +461,9 @@ function normalizeModuleFederationOptions(options) {
|
|
|
444
461
|
publicPath: options.publicPath,
|
|
445
462
|
shareStrategy: options.shareStrategy || 'version-first',
|
|
446
463
|
ignoreOrigin: options.ignoreOrigin || false,
|
|
447
|
-
virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
|
|
464
|
+
virtualModuleDir: options.virtualModuleDir || '__mf__virtual',
|
|
465
|
+
hostInitInjectLocation: options.hostInitInjectLocation || 'html',
|
|
466
|
+
bundleAllCSS: options.bundleAllCSS || false
|
|
448
467
|
};
|
|
449
468
|
}
|
|
450
469
|
|
|
@@ -708,12 +727,13 @@ function writeLocalSharedImportMap() {
|
|
|
708
727
|
}
|
|
709
728
|
function generateLocalSharedImportMap() {
|
|
710
729
|
var options = getNormalizeModuleFederationOptions();
|
|
711
|
-
return "\n const importMap = {\n " + Array.from(getUsedShares()).sort().map(function (pkg) {
|
|
712
|
-
|
|
730
|
+
return "\n import {loadShare} from \"@module-federation/runtime\";\n const importMap = {\n " + Array.from(getUsedShares()).sort().map(function (pkg) {
|
|
731
|
+
var shareItem = getNormalizeShareItem(pkg);
|
|
732
|
+
return "\n " + JSON.stringify(pkg) + ": async () => {\n " + ((shareItem == null ? void 0 : shareItem.shareConfig["import"]) === false ? "throw new Error(`Shared module '${" + JSON.stringify(pkg) + "}' must be provided by host`);" : "let pkg = await import(\"" + getPreBuildLibImportId(pkg) + "\");\n return pkg;") + "\n }\n ";
|
|
713
733
|
}).join(',') + "\n }\n const usedShared = {\n " + Array.from(getUsedShares()).sort().map(function (key) {
|
|
714
734
|
var shareItem = getNormalizeShareItem(key);
|
|
715
735
|
if (!shareItem) return null;
|
|
716
|
-
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n usedShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = importMap
|
|
736
|
+
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n if (" + (shareItem.shareConfig["import"] === false) + ") {\n throw new Error(`Shared module '${" + JSON.stringify(key) + "}' must be provided by host`);\n }\n usedShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = importMap\n const res = await pkgDynamicImport()\n const exportModule = {...res}\n // All npm packages pre-built by vite will be converted to esm\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return function () {\n return exportModule\n }\n },\n shareConfig: {\n singleton: " + shareItem.shareConfig.singleton + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + ",\n " + (shareItem.shareConfig["import"] === false ? 'import: false,' : '') + "\n }\n }\n ";
|
|
717
737
|
}).filter(function (x) {
|
|
718
738
|
return x !== null;
|
|
719
739
|
}).join(',') + "\n }\n const usedRemotes = [" + Object.keys(getUsedRemotesMap()).map(function (key) {
|
|
@@ -743,7 +763,7 @@ function generateRemoteEntry(options) {
|
|
|
743
763
|
var HOST_AUTO_INIT_TAG = '__H_A_I__';
|
|
744
764
|
var hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
|
|
745
765
|
function writeHostAutoInit() {
|
|
746
|
-
hostAutoInitModule.writeSync("\n const remoteEntryPromise = import(\"" + REMOTE_ENTRY_ID + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await
|
|
766
|
+
hostAutoInitModule.writeSync("\n const remoteEntryPromise = import(\"" + REMOTE_ENTRY_ID + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
|
|
747
767
|
}
|
|
748
768
|
function getHostAutoInitImportId() {
|
|
749
769
|
return hostAutoInitModule.getImportId();
|
|
@@ -1068,7 +1088,7 @@ var Manifest = function Manifest() {
|
|
|
1068
1088
|
}
|
|
1069
1089
|
}
|
|
1070
1090
|
// Second pass: Collect all CSS assets
|
|
1071
|
-
var allCssAssets = collectCssAssets(bundle);
|
|
1091
|
+
var allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : new Set();
|
|
1072
1092
|
var exposesModules = Object.keys(mfOptions.exposes).map(function (item) {
|
|
1073
1093
|
return mfOptions.exposes[item]["import"];
|
|
1074
1094
|
});
|
|
@@ -1096,8 +1116,10 @@ var Manifest = function Manifest() {
|
|
|
1096
1116
|
processModuleAssets(bundle, filesMap, function (modulePath) {
|
|
1097
1117
|
return fileToShareKey.get(modulePath);
|
|
1098
1118
|
});
|
|
1099
|
-
// Add all CSS assets to every export
|
|
1100
|
-
|
|
1119
|
+
// Add all CSS assets to every export if bundleAllCSS is enabled
|
|
1120
|
+
if (mfOptions.bundleAllCSS) {
|
|
1121
|
+
addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
1122
|
+
}
|
|
1101
1123
|
// Final deduplication of all assets
|
|
1102
1124
|
filesMap = deduplicateAssets(filesMap);
|
|
1103
1125
|
_this.emitFile({
|
|
@@ -1296,15 +1318,15 @@ function pluginProxyRemoteEntry () {
|
|
|
1296
1318
|
}
|
|
1297
1319
|
},
|
|
1298
1320
|
transform: function transform(code, id) {
|
|
1299
|
-
|
|
1300
|
-
if (!filter(id)) return
|
|
1321
|
+
var transformedCode = function () {
|
|
1322
|
+
if (!filter(id)) return;
|
|
1301
1323
|
if (id.includes(REMOTE_ENTRY_ID)) {
|
|
1302
|
-
return
|
|
1324
|
+
return parsePromise.then(function (_) {
|
|
1303
1325
|
return generateRemoteEntry(getNormalizeModuleFederationOptions());
|
|
1304
|
-
})
|
|
1326
|
+
});
|
|
1305
1327
|
}
|
|
1306
1328
|
if (id === VIRTUAL_EXPOSES) {
|
|
1307
|
-
return
|
|
1329
|
+
return generateExposes();
|
|
1308
1330
|
}
|
|
1309
1331
|
if (id.includes(getHostAutoInitPath())) {
|
|
1310
1332
|
var options = getNormalizeModuleFederationOptions();
|
|
@@ -1312,14 +1334,12 @@ function pluginProxyRemoteEntry () {
|
|
|
1312
1334
|
var _viteConfig$server, _viteConfig$server2;
|
|
1313
1335
|
var host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
|
|
1314
1336
|
var publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
|
|
1315
|
-
return
|
|
1337
|
+
return "\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + " + publicPath + ")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ";
|
|
1316
1338
|
}
|
|
1317
|
-
return
|
|
1339
|
+
return code;
|
|
1318
1340
|
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
return Promise.reject(e);
|
|
1322
|
-
}
|
|
1341
|
+
}();
|
|
1342
|
+
return mapCodeToCodeWithSourcemap(transformedCode);
|
|
1323
1343
|
}
|
|
1324
1344
|
};
|
|
1325
1345
|
}
|
|
@@ -1398,11 +1418,11 @@ function proxySharedModule(options) {
|
|
|
1398
1418
|
});
|
|
1399
1419
|
}
|
|
1400
1420
|
},
|
|
1401
|
-
transform: function transform(
|
|
1421
|
+
transform: function transform(_, id) {
|
|
1402
1422
|
if (id.includes(getLocalSharedImportMapPath())) {
|
|
1403
|
-
return parsePromise.then(function (_) {
|
|
1423
|
+
return mapCodeToCodeWithSourcemap(parsePromise.then(function (_) {
|
|
1404
1424
|
return generateLocalSharedImportMap();
|
|
1405
|
-
});
|
|
1425
|
+
}));
|
|
1406
1426
|
}
|
|
1407
1427
|
}
|
|
1408
1428
|
}, {
|
|
@@ -1509,7 +1529,8 @@ function federation(mfUserOptions) {
|
|
|
1509
1529
|
var options = normalizeModuleFederationOptions(mfUserOptions);
|
|
1510
1530
|
var name = options.name,
|
|
1511
1531
|
shared = options.shared,
|
|
1512
|
-
filename = options.filename
|
|
1532
|
+
filename = options.filename,
|
|
1533
|
+
hostInitInjectLocation = options.hostInitInjectLocation;
|
|
1513
1534
|
if (!name) throw new Error('name is required');
|
|
1514
1535
|
return [{
|
|
1515
1536
|
name: 'vite:module-federation-config',
|
|
@@ -1528,7 +1549,7 @@ function federation(mfUserOptions) {
|
|
|
1528
1549
|
}), addEntry({
|
|
1529
1550
|
entryName: 'hostInit',
|
|
1530
1551
|
entryPath: getHostAutoInitPath(),
|
|
1531
|
-
inject:
|
|
1552
|
+
inject: hostInitInjectLocation
|
|
1532
1553
|
}), addEntry({
|
|
1533
1554
|
entryName: 'virtualExposes',
|
|
1534
1555
|
entryPath: VIRTUAL_EXPOSES
|
package/lib/index.modern.js
CHANGED
|
@@ -3,9 +3,23 @@ import * as fs from 'fs';
|
|
|
3
3
|
import { mkdirSync, writeFileSync, existsSync, writeFile } from 'fs';
|
|
4
4
|
import * as path from 'pathe';
|
|
5
5
|
import path__default, { resolve, basename, parse, join, dirname } from 'pathe';
|
|
6
|
+
import MagicString from 'magic-string';
|
|
6
7
|
import { createFilter } from '@rollup/pluginutils';
|
|
7
8
|
import { walk } from 'estree-walker';
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
async function mapCodeToCodeWithSourcemap(code) {
|
|
11
|
+
const resolvedCode = await code;
|
|
12
|
+
if (resolvedCode === undefined) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const s = new MagicString(resolvedCode);
|
|
16
|
+
return {
|
|
17
|
+
code: s.toString(),
|
|
18
|
+
map: s.generateMap({
|
|
19
|
+
hires: true
|
|
20
|
+
})
|
|
21
|
+
};
|
|
22
|
+
}
|
|
9
23
|
|
|
10
24
|
function getFirstHtmlEntryFile(entryFiles) {
|
|
11
25
|
return entryFiles.find(file => file.endsWith('.html'));
|
|
@@ -127,7 +141,7 @@ const addEntry = ({
|
|
|
127
141
|
const injection = `
|
|
128
142
|
import ${JSON.stringify(entryPath)};
|
|
129
143
|
`;
|
|
130
|
-
return injection + code;
|
|
144
|
+
return mapCodeToCodeWithSourcemap(injection + code);
|
|
131
145
|
}
|
|
132
146
|
}
|
|
133
147
|
}];
|
|
@@ -332,6 +346,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
332
346
|
scope: 'default',
|
|
333
347
|
from: '',
|
|
334
348
|
shareConfig: {
|
|
349
|
+
import: undefined,
|
|
335
350
|
singleton: false,
|
|
336
351
|
requiredVersion: version ? `^${version}` : '*'
|
|
337
352
|
}
|
|
@@ -343,6 +358,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
343
358
|
version: shareItem.version || version,
|
|
344
359
|
scope: shareItem.shareScope || 'default',
|
|
345
360
|
shareConfig: {
|
|
361
|
+
import: typeof shareItem === 'object' ? shareItem.import : undefined,
|
|
346
362
|
singleton: shareItem.singleton || false,
|
|
347
363
|
requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : '*'),
|
|
348
364
|
strictVersion: !!shareItem.strictVersion
|
|
@@ -414,7 +430,9 @@ function normalizeModuleFederationOptions(options) {
|
|
|
414
430
|
publicPath: options.publicPath,
|
|
415
431
|
shareStrategy: options.shareStrategy || 'version-first',
|
|
416
432
|
ignoreOrigin: options.ignoreOrigin || false,
|
|
417
|
-
virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
|
|
433
|
+
virtualModuleDir: options.virtualModuleDir || '__mf__virtual',
|
|
434
|
+
hostInitInjectLocation: options.hostInitInjectLocation || 'html',
|
|
435
|
+
bundleAllCSS: options.bundleAllCSS || false
|
|
418
436
|
};
|
|
419
437
|
}
|
|
420
438
|
|
|
@@ -712,13 +730,17 @@ function writeLocalSharedImportMap() {
|
|
|
712
730
|
function generateLocalSharedImportMap() {
|
|
713
731
|
const options = getNormalizeModuleFederationOptions();
|
|
714
732
|
return `
|
|
733
|
+
import {loadShare} from "@module-federation/runtime";
|
|
715
734
|
const importMap = {
|
|
716
|
-
${Array.from(getUsedShares()).sort().map(pkg =>
|
|
735
|
+
${Array.from(getUsedShares()).sort().map(pkg => {
|
|
736
|
+
const shareItem = getNormalizeShareItem(pkg);
|
|
737
|
+
return `
|
|
717
738
|
${JSON.stringify(pkg)}: async () => {
|
|
718
|
-
let pkg = await import("${getPreBuildLibImportId(pkg)}")
|
|
719
|
-
|
|
739
|
+
${(shareItem == null ? void 0 : shareItem.shareConfig.import) === false ? `throw new Error(\`Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` : `let pkg = await import("${getPreBuildLibImportId(pkg)}");
|
|
740
|
+
return pkg;`}
|
|
720
741
|
}
|
|
721
|
-
|
|
742
|
+
`;
|
|
743
|
+
}).join(',')}
|
|
722
744
|
}
|
|
723
745
|
const usedShared = {
|
|
724
746
|
${Array.from(getUsedShares()).sort().map(key => {
|
|
@@ -732,8 +754,11 @@ function generateLocalSharedImportMap() {
|
|
|
732
754
|
loaded: false,
|
|
733
755
|
from: ${JSON.stringify(options.name)},
|
|
734
756
|
async get () {
|
|
757
|
+
if (${shareItem.shareConfig.import === false}) {
|
|
758
|
+
throw new Error(\`Shared module '\${${JSON.stringify(key)}}' must be provided by host\`);
|
|
759
|
+
}
|
|
735
760
|
usedShared[${JSON.stringify(key)}].loaded = true
|
|
736
|
-
const {${JSON.stringify(key)}: pkgDynamicImport} = importMap
|
|
761
|
+
const {${JSON.stringify(key)}: pkgDynamicImport} = importMap
|
|
737
762
|
const res = await pkgDynamicImport()
|
|
738
763
|
const exportModule = {...res}
|
|
739
764
|
// All npm packages pre-built by vite will be converted to esm
|
|
@@ -747,7 +772,8 @@ function generateLocalSharedImportMap() {
|
|
|
747
772
|
},
|
|
748
773
|
shareConfig: {
|
|
749
774
|
singleton: ${shareItem.shareConfig.singleton},
|
|
750
|
-
requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)}
|
|
775
|
+
requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)},
|
|
776
|
+
${shareItem.shareConfig.import === false ? 'import: false,' : ''}
|
|
751
777
|
}
|
|
752
778
|
}
|
|
753
779
|
`;
|
|
@@ -835,7 +861,7 @@ const hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG)
|
|
|
835
861
|
function writeHostAutoInit() {
|
|
836
862
|
hostAutoInitModule.writeSync(`
|
|
837
863
|
const remoteEntryPromise = import("${REMOTE_ENTRY_ID}")
|
|
838
|
-
// __tla only serves as a hack for vite-plugin-top-level-await.
|
|
864
|
+
// __tla only serves as a hack for vite-plugin-top-level-await.
|
|
839
865
|
Promise.resolve(remoteEntryPromise)
|
|
840
866
|
.then(remoteEntry => {
|
|
841
867
|
return Promise.resolve(remoteEntry.__tla)
|
|
@@ -1139,7 +1165,7 @@ const Manifest = () => {
|
|
|
1139
1165
|
}
|
|
1140
1166
|
}
|
|
1141
1167
|
// Second pass: Collect all CSS assets
|
|
1142
|
-
const allCssAssets = collectCssAssets(bundle);
|
|
1168
|
+
const allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : new Set();
|
|
1143
1169
|
const exposesModules = Object.keys(mfOptions.exposes).map(item => mfOptions.exposes[item].import);
|
|
1144
1170
|
// Process exposed modules
|
|
1145
1171
|
processModuleAssets(bundle, filesMap, modulePath => {
|
|
@@ -1163,8 +1189,10 @@ const Manifest = () => {
|
|
|
1163
1189
|
// Process shared modules
|
|
1164
1190
|
const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
|
|
1165
1191
|
processModuleAssets(bundle, filesMap, modulePath => fileToShareKey.get(modulePath));
|
|
1166
|
-
// Add all CSS assets to every export
|
|
1167
|
-
|
|
1192
|
+
// Add all CSS assets to every export if bundleAllCSS is enabled
|
|
1193
|
+
if (mfOptions.bundleAllCSS) {
|
|
1194
|
+
addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
1195
|
+
}
|
|
1168
1196
|
// Final deduplication of all assets
|
|
1169
1197
|
filesMap = deduplicateAssets(filesMap);
|
|
1170
1198
|
this.emitFile({
|
|
@@ -1351,21 +1379,22 @@ function pluginProxyRemoteEntry () {
|
|
|
1351
1379
|
return id;
|
|
1352
1380
|
}
|
|
1353
1381
|
},
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1382
|
+
transform(code, id) {
|
|
1383
|
+
const transformedCode = (() => {
|
|
1384
|
+
if (!filter(id)) return;
|
|
1385
|
+
if (id.includes(REMOTE_ENTRY_ID)) {
|
|
1386
|
+
return parsePromise.then(_ => generateRemoteEntry(getNormalizeModuleFederationOptions()));
|
|
1387
|
+
}
|
|
1388
|
+
if (id === VIRTUAL_EXPOSES) {
|
|
1389
|
+
return generateExposes();
|
|
1390
|
+
}
|
|
1391
|
+
if (id.includes(getHostAutoInitPath())) {
|
|
1392
|
+
const options = getNormalizeModuleFederationOptions();
|
|
1393
|
+
if (_command === 'serve') {
|
|
1394
|
+
var _viteConfig$server, _viteConfig$server2;
|
|
1395
|
+
const host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
|
|
1396
|
+
const publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
|
|
1397
|
+
return `
|
|
1369
1398
|
const origin = (window && ${!options.ignoreOrigin}) ? window.origin : "//${host}:${(_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port}"
|
|
1370
1399
|
const remoteEntryPromise = await import(origin + ${publicPath})
|
|
1371
1400
|
// __tla only serves as a hack for vite-plugin-top-level-await.
|
|
@@ -1375,9 +1404,11 @@ function pluginProxyRemoteEntry () {
|
|
|
1375
1404
|
.then(remoteEntry.init).catch(remoteEntry.init)
|
|
1376
1405
|
})
|
|
1377
1406
|
`;
|
|
1407
|
+
}
|
|
1408
|
+
return code;
|
|
1378
1409
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1410
|
+
})();
|
|
1411
|
+
return mapCodeToCodeWithSourcemap(transformedCode);
|
|
1381
1412
|
}
|
|
1382
1413
|
};
|
|
1383
1414
|
}
|
|
@@ -1457,9 +1488,9 @@ function proxySharedModule(options) {
|
|
|
1457
1488
|
return parsePromise.then(_ => generateLocalSharedImportMap());
|
|
1458
1489
|
}
|
|
1459
1490
|
},
|
|
1460
|
-
transform(
|
|
1491
|
+
transform(_, id) {
|
|
1461
1492
|
if (id.includes(getLocalSharedImportMapPath())) {
|
|
1462
|
-
return parsePromise.then(_ => generateLocalSharedImportMap());
|
|
1493
|
+
return mapCodeToCodeWithSourcemap(parsePromise.then(_ => generateLocalSharedImportMap()));
|
|
1463
1494
|
}
|
|
1464
1495
|
}
|
|
1465
1496
|
}, {
|
|
@@ -1561,7 +1592,8 @@ function federation(mfUserOptions) {
|
|
|
1561
1592
|
name,
|
|
1562
1593
|
remotes,
|
|
1563
1594
|
shared,
|
|
1564
|
-
filename
|
|
1595
|
+
filename,
|
|
1596
|
+
hostInitInjectLocation
|
|
1565
1597
|
} = options;
|
|
1566
1598
|
if (!name) throw new Error('name is required');
|
|
1567
1599
|
return [{
|
|
@@ -1581,7 +1613,7 @@ function federation(mfUserOptions) {
|
|
|
1581
1613
|
}), ...addEntry({
|
|
1582
1614
|
entryName: 'hostInit',
|
|
1583
1615
|
entryPath: getHostAutoInitPath(),
|
|
1584
|
-
inject:
|
|
1616
|
+
inject: hostInitInjectLocation
|
|
1585
1617
|
}), ...addEntry({
|
|
1586
1618
|
entryName: 'virtualExposes',
|
|
1587
1619
|
entryPath: VIRTUAL_EXPOSES
|
package/lib/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('defu'), require('fs'), require('pathe'), require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'defu', 'fs', 'pathe', '@rollup/pluginutils', 'estree-walker'
|
|
4
|
-
(global = global || self, factory(global.vite = {}, global.defu, global.fs, global.pathe, global.
|
|
5
|
-
})(this, (function (exports, defu, fs, path, pluginutils, estreeWalker
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('defu'), require('fs'), require('pathe'), require('magic-string'), require('@rollup/pluginutils'), require('estree-walker')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'defu', 'fs', 'pathe', 'magic-string', '@rollup/pluginutils', 'estree-walker'], factory) :
|
|
4
|
+
(global = global || self, factory(global.vite = {}, global.defu, global.fs, global.pathe, global.magicString, global.pluginutils, global.estreeWalker));
|
|
5
|
+
})(this, (function (exports, defu, fs, path, MagicString, pluginutils, estreeWalker) {
|
|
6
6
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
7
7
|
|
|
8
8
|
function _interopNamespace(e) {
|
|
@@ -29,6 +29,21 @@
|
|
|
29
29
|
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
30
30
|
var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
|
|
31
31
|
|
|
32
|
+
var mapCodeToCodeWithSourcemap = function mapCodeToCodeWithSourcemap(code) {
|
|
33
|
+
return Promise.resolve(code).then(function (resolvedCode) {
|
|
34
|
+
if (resolvedCode === undefined) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
var s = new MagicString__default["default"](resolvedCode);
|
|
38
|
+
return {
|
|
39
|
+
code: s.toString(),
|
|
40
|
+
map: s.generateMap({
|
|
41
|
+
hires: true
|
|
42
|
+
})
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
32
47
|
function getFirstHtmlEntryFile(entryFiles) {
|
|
33
48
|
return entryFiles.find(function (file) {
|
|
34
49
|
return file.endsWith('.html');
|
|
@@ -148,7 +163,7 @@
|
|
|
148
163
|
return id.endsWith(file);
|
|
149
164
|
})) {
|
|
150
165
|
var injection = "\n import " + JSON.stringify(entryPath) + ";\n ";
|
|
151
|
-
return injection + code;
|
|
166
|
+
return mapCodeToCodeWithSourcemap(injection + code);
|
|
152
167
|
}
|
|
153
168
|
}
|
|
154
169
|
}];
|
|
@@ -381,6 +396,7 @@
|
|
|
381
396
|
scope: 'default',
|
|
382
397
|
from: '',
|
|
383
398
|
shareConfig: {
|
|
399
|
+
"import": undefined,
|
|
384
400
|
singleton: false,
|
|
385
401
|
requiredVersion: version ? "^" + version : '*'
|
|
386
402
|
}
|
|
@@ -392,6 +408,7 @@
|
|
|
392
408
|
version: shareItem.version || version,
|
|
393
409
|
scope: shareItem.shareScope || 'default',
|
|
394
410
|
shareConfig: {
|
|
411
|
+
"import": typeof shareItem === 'object' ? shareItem["import"] : undefined,
|
|
395
412
|
singleton: shareItem.singleton || false,
|
|
396
413
|
requiredVersion: shareItem.requiredVersion || (version ? "^" + version : '*'),
|
|
397
414
|
strictVersion: !!shareItem.strictVersion
|
|
@@ -466,7 +483,9 @@
|
|
|
466
483
|
publicPath: options.publicPath,
|
|
467
484
|
shareStrategy: options.shareStrategy || 'version-first',
|
|
468
485
|
ignoreOrigin: options.ignoreOrigin || false,
|
|
469
|
-
virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
|
|
486
|
+
virtualModuleDir: options.virtualModuleDir || '__mf__virtual',
|
|
487
|
+
hostInitInjectLocation: options.hostInitInjectLocation || 'html',
|
|
488
|
+
bundleAllCSS: options.bundleAllCSS || false
|
|
470
489
|
};
|
|
471
490
|
}
|
|
472
491
|
|
|
@@ -730,12 +749,13 @@
|
|
|
730
749
|
}
|
|
731
750
|
function generateLocalSharedImportMap() {
|
|
732
751
|
var options = getNormalizeModuleFederationOptions();
|
|
733
|
-
return "\n const importMap = {\n " + Array.from(getUsedShares()).sort().map(function (pkg) {
|
|
734
|
-
|
|
752
|
+
return "\n import {loadShare} from \"@module-federation/runtime\";\n const importMap = {\n " + Array.from(getUsedShares()).sort().map(function (pkg) {
|
|
753
|
+
var shareItem = getNormalizeShareItem(pkg);
|
|
754
|
+
return "\n " + JSON.stringify(pkg) + ": async () => {\n " + ((shareItem == null ? void 0 : shareItem.shareConfig["import"]) === false ? "throw new Error(`Shared module '${" + JSON.stringify(pkg) + "}' must be provided by host`);" : "let pkg = await import(\"" + getPreBuildLibImportId(pkg) + "\");\n return pkg;") + "\n }\n ";
|
|
735
755
|
}).join(',') + "\n }\n const usedShared = {\n " + Array.from(getUsedShares()).sort().map(function (key) {
|
|
736
756
|
var shareItem = getNormalizeShareItem(key);
|
|
737
757
|
if (!shareItem) return null;
|
|
738
|
-
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n usedShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = importMap
|
|
758
|
+
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n if (" + (shareItem.shareConfig["import"] === false) + ") {\n throw new Error(`Shared module '${" + JSON.stringify(key) + "}' must be provided by host`);\n }\n usedShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = importMap\n const res = await pkgDynamicImport()\n const exportModule = {...res}\n // All npm packages pre-built by vite will be converted to esm\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return function () {\n return exportModule\n }\n },\n shareConfig: {\n singleton: " + shareItem.shareConfig.singleton + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + ",\n " + (shareItem.shareConfig["import"] === false ? 'import: false,' : '') + "\n }\n }\n ";
|
|
739
759
|
}).filter(function (x) {
|
|
740
760
|
return x !== null;
|
|
741
761
|
}).join(',') + "\n }\n const usedRemotes = [" + Object.keys(getUsedRemotesMap()).map(function (key) {
|
|
@@ -765,7 +785,7 @@
|
|
|
765
785
|
var HOST_AUTO_INIT_TAG = '__H_A_I__';
|
|
766
786
|
var hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
|
|
767
787
|
function writeHostAutoInit() {
|
|
768
|
-
hostAutoInitModule.writeSync("\n const remoteEntryPromise = import(\"" + REMOTE_ENTRY_ID + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await
|
|
788
|
+
hostAutoInitModule.writeSync("\n const remoteEntryPromise = import(\"" + REMOTE_ENTRY_ID + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
|
|
769
789
|
}
|
|
770
790
|
function getHostAutoInitImportId() {
|
|
771
791
|
return hostAutoInitModule.getImportId();
|
|
@@ -1090,7 +1110,7 @@
|
|
|
1090
1110
|
}
|
|
1091
1111
|
}
|
|
1092
1112
|
// Second pass: Collect all CSS assets
|
|
1093
|
-
var allCssAssets = collectCssAssets(bundle);
|
|
1113
|
+
var allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : new Set();
|
|
1094
1114
|
var exposesModules = Object.keys(mfOptions.exposes).map(function (item) {
|
|
1095
1115
|
return mfOptions.exposes[item]["import"];
|
|
1096
1116
|
});
|
|
@@ -1118,8 +1138,10 @@
|
|
|
1118
1138
|
processModuleAssets(bundle, filesMap, function (modulePath) {
|
|
1119
1139
|
return fileToShareKey.get(modulePath);
|
|
1120
1140
|
});
|
|
1121
|
-
// Add all CSS assets to every export
|
|
1122
|
-
|
|
1141
|
+
// Add all CSS assets to every export if bundleAllCSS is enabled
|
|
1142
|
+
if (mfOptions.bundleAllCSS) {
|
|
1143
|
+
addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
1144
|
+
}
|
|
1123
1145
|
// Final deduplication of all assets
|
|
1124
1146
|
filesMap = deduplicateAssets(filesMap);
|
|
1125
1147
|
_this.emitFile({
|
|
@@ -1318,15 +1340,15 @@
|
|
|
1318
1340
|
}
|
|
1319
1341
|
},
|
|
1320
1342
|
transform: function transform(code, id) {
|
|
1321
|
-
|
|
1322
|
-
if (!filter(id)) return
|
|
1343
|
+
var transformedCode = function () {
|
|
1344
|
+
if (!filter(id)) return;
|
|
1323
1345
|
if (id.includes(REMOTE_ENTRY_ID)) {
|
|
1324
|
-
return
|
|
1346
|
+
return parsePromise.then(function (_) {
|
|
1325
1347
|
return generateRemoteEntry(getNormalizeModuleFederationOptions());
|
|
1326
|
-
})
|
|
1348
|
+
});
|
|
1327
1349
|
}
|
|
1328
1350
|
if (id === VIRTUAL_EXPOSES) {
|
|
1329
|
-
return
|
|
1351
|
+
return generateExposes();
|
|
1330
1352
|
}
|
|
1331
1353
|
if (id.includes(getHostAutoInitPath())) {
|
|
1332
1354
|
var options = getNormalizeModuleFederationOptions();
|
|
@@ -1334,14 +1356,12 @@
|
|
|
1334
1356
|
var _viteConfig$server, _viteConfig$server2;
|
|
1335
1357
|
var host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
|
|
1336
1358
|
var publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
|
|
1337
|
-
return
|
|
1359
|
+
return "\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + " + publicPath + ")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ";
|
|
1338
1360
|
}
|
|
1339
|
-
return
|
|
1361
|
+
return code;
|
|
1340
1362
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
return Promise.reject(e);
|
|
1344
|
-
}
|
|
1363
|
+
}();
|
|
1364
|
+
return mapCodeToCodeWithSourcemap(transformedCode);
|
|
1345
1365
|
}
|
|
1346
1366
|
};
|
|
1347
1367
|
}
|
|
@@ -1420,11 +1440,11 @@
|
|
|
1420
1440
|
});
|
|
1421
1441
|
}
|
|
1422
1442
|
},
|
|
1423
|
-
transform: function transform(
|
|
1443
|
+
transform: function transform(_, id) {
|
|
1424
1444
|
if (id.includes(getLocalSharedImportMapPath())) {
|
|
1425
|
-
return parsePromise.then(function (_) {
|
|
1445
|
+
return mapCodeToCodeWithSourcemap(parsePromise.then(function (_) {
|
|
1426
1446
|
return generateLocalSharedImportMap();
|
|
1427
|
-
});
|
|
1447
|
+
}));
|
|
1428
1448
|
}
|
|
1429
1449
|
}
|
|
1430
1450
|
}, {
|
|
@@ -1531,7 +1551,8 @@
|
|
|
1531
1551
|
var options = normalizeModuleFederationOptions(mfUserOptions);
|
|
1532
1552
|
var name = options.name,
|
|
1533
1553
|
shared = options.shared,
|
|
1534
|
-
filename = options.filename
|
|
1554
|
+
filename = options.filename,
|
|
1555
|
+
hostInitInjectLocation = options.hostInitInjectLocation;
|
|
1535
1556
|
if (!name) throw new Error('name is required');
|
|
1536
1557
|
return [{
|
|
1537
1558
|
name: 'vite:module-federation-config',
|
|
@@ -1550,7 +1571,7 @@
|
|
|
1550
1571
|
}), addEntry({
|
|
1551
1572
|
entryName: 'hostInit',
|
|
1552
1573
|
entryPath: getHostAutoInitPath(),
|
|
1553
|
-
inject:
|
|
1574
|
+
inject: hostInitInjectLocation
|
|
1554
1575
|
}), addEntry({
|
|
1555
1576
|
entryName: 'virtualExposes',
|
|
1556
1577
|
entryPath: VIRTUAL_EXPOSES
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
+
import { NormalizedModuleFederationOptions } from '../utils/normalizeModuleFederationOptions';
|
|
2
3
|
interface AddEntryOptions {
|
|
3
4
|
entryName: string;
|
|
4
5
|
entryPath: string;
|
|
5
6
|
fileName?: string;
|
|
6
|
-
inject?: '
|
|
7
|
+
inject?: NormalizedModuleFederationOptions['hostInitInjectLocation'];
|
|
7
8
|
}
|
|
8
9
|
declare const addEntry: ({ entryName, entryPath, fileName, inject, }: AddEntryOptions) => Plugin[];
|
|
9
10
|
export default addEntry;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SharedConfig, ShareStrategy } from '@module-federation/runtime/types';
|
|
2
|
+
import type { sharePlugin } from '@module-federation/sdk';
|
|
2
3
|
export type RemoteEntryType = 'var' | 'module' | 'assign' | 'assign-properties' | 'this' | 'window' | 'self' | 'global' | 'commonjs' | 'commonjs2' | 'commonjs-module' | 'commonjs-static' | 'amd' | 'amd-require' | 'umd' | 'umd2' | 'jsonp' | 'system' | string;
|
|
3
4
|
interface ExposesItem {
|
|
4
5
|
import: string;
|
|
@@ -19,7 +20,7 @@ export interface ShareItem {
|
|
|
19
20
|
version: string | undefined;
|
|
20
21
|
scope: string;
|
|
21
22
|
from: string;
|
|
22
|
-
shareConfig: SharedConfig;
|
|
23
|
+
shareConfig: SharedConfig & sharePlugin.SharedConfig;
|
|
23
24
|
}
|
|
24
25
|
interface ManifestOptions {
|
|
25
26
|
filePath?: string;
|
|
@@ -41,6 +42,12 @@ export type ModuleFederationOptions = {
|
|
|
41
42
|
* Defaults to Vite's base config or "auto" if base is empty
|
|
42
43
|
*/
|
|
43
44
|
publicPath?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Controls whether all CSS assets from the bundle should be added to every exposed module.
|
|
47
|
+
* When false (default), the plugin will not process any CSS assets.
|
|
48
|
+
* When true, all CSS assets are bundled into every exposed module.
|
|
49
|
+
*/
|
|
50
|
+
bundleAllCSS?: boolean;
|
|
44
51
|
shared?: string[] | Record<string, string | {
|
|
45
52
|
name?: string;
|
|
46
53
|
version?: string;
|
|
@@ -48,6 +55,7 @@ export type ModuleFederationOptions = {
|
|
|
48
55
|
singleton?: boolean;
|
|
49
56
|
requiredVersion?: string;
|
|
50
57
|
strictVersion?: boolean;
|
|
58
|
+
import?: sharePlugin.SharedConfig['import'];
|
|
51
59
|
}> | undefined;
|
|
52
60
|
runtimePlugins?: string[];
|
|
53
61
|
getPublicPath?: string;
|
|
@@ -58,6 +66,7 @@ export type ModuleFederationOptions = {
|
|
|
58
66
|
shareStrategy?: ShareStrategy;
|
|
59
67
|
ignoreOrigin?: boolean;
|
|
60
68
|
virtualModuleDir?: string;
|
|
69
|
+
hostInitInjectLocation?: HostInitInjectLocationOptions;
|
|
61
70
|
};
|
|
62
71
|
export interface NormalizedModuleFederationOptions {
|
|
63
72
|
exposes: Record<string, ExposesItem>;
|
|
@@ -78,7 +87,15 @@ export interface NormalizedModuleFederationOptions {
|
|
|
78
87
|
publicPath?: string;
|
|
79
88
|
ignoreOrigin?: boolean;
|
|
80
89
|
virtualModuleDir: string;
|
|
90
|
+
hostInitInjectLocation: HostInitInjectLocationOptions;
|
|
91
|
+
/**
|
|
92
|
+
* Controls whether all CSS assets from the bundle should be added to every exposed module.
|
|
93
|
+
* When false (default), the plugin will not process any CSS assets.
|
|
94
|
+
* When true, all CSS assets are bundled into every exposed module.
|
|
95
|
+
*/
|
|
96
|
+
bundleAllCSS: boolean;
|
|
81
97
|
}
|
|
98
|
+
type HostInitInjectLocationOptions = 'entry' | 'html';
|
|
82
99
|
interface PluginDevOptions {
|
|
83
100
|
disableLiveReload?: boolean;
|
|
84
101
|
disableHotTypesReload?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/vite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Vite plugin for Module Federation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "src/index.ts",
|
|
@@ -9,6 +9,22 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"lib/**/*"
|
|
11
11
|
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"prepare": "husky install",
|
|
14
|
+
"fmt": "prettier --write src",
|
|
15
|
+
"fmt.check": "prettier --check src",
|
|
16
|
+
"format": "pretty-quick",
|
|
17
|
+
"dev": "microbundle watch --no-sourcemap --compress=false",
|
|
18
|
+
"build": "rimraf lib && microbundle --no-sourcemap --compress=false",
|
|
19
|
+
"dev-rv": "pnpm -filter 'examples-rust-vite*' run dev",
|
|
20
|
+
"preview-rv": "pnpm -filter 'examples-rust-vite*' run preview",
|
|
21
|
+
"dev-vv": "pnpm -filter 'examples-vite-vite*' run dev",
|
|
22
|
+
"dev-nv": "pnpm -filter 'examples-nuxt-vite-host' -filter 'examples-vite-vite-remote' run dev",
|
|
23
|
+
"preview-vv": "pnpm -filter 'examples-vite-vite*' run preview",
|
|
24
|
+
"multi-example": "pnpm --filter \"multi-example-*\" --parallel run start",
|
|
25
|
+
"test": "vitest",
|
|
26
|
+
"e2e": "playwright test"
|
|
27
|
+
},
|
|
12
28
|
"repository": {
|
|
13
29
|
"type": "git",
|
|
14
30
|
"url": "git+https://github.com/module-federation/vite.git"
|
|
@@ -28,8 +44,10 @@
|
|
|
28
44
|
"url": "https://github.com/module-federation/vite/issues"
|
|
29
45
|
},
|
|
30
46
|
"homepage": "https://github.com/module-federation/vite#readme",
|
|
47
|
+
"packageManager": "pnpm@9.1.3",
|
|
31
48
|
"dependencies": {
|
|
32
|
-
"@module-federation/runtime": "^0.
|
|
49
|
+
"@module-federation/runtime": "^0.18.3",
|
|
50
|
+
"@module-federation/sdk": "^0.18.3",
|
|
33
51
|
"@rollup/pluginutils": "^5.1.0",
|
|
34
52
|
"defu": "^6.1.4",
|
|
35
53
|
"estree-walker": "^2",
|
|
@@ -49,20 +67,5 @@
|
|
|
49
67
|
"vite": "^5.4.3",
|
|
50
68
|
"vitest": "^2.1.1",
|
|
51
69
|
"wait-on": "^8.0.1"
|
|
52
|
-
},
|
|
53
|
-
"scripts": {
|
|
54
|
-
"fmt": "prettier --write src",
|
|
55
|
-
"fmt.check": "prettier --check src",
|
|
56
|
-
"format": "pretty-quick",
|
|
57
|
-
"dev": "microbundle watch --no-sourcemap --compress=false",
|
|
58
|
-
"build": "rimraf lib && microbundle --no-sourcemap --compress=false",
|
|
59
|
-
"dev-rv": "pnpm -filter 'examples-rust-vite*' run dev",
|
|
60
|
-
"preview-rv": "pnpm -filter 'examples-rust-vite*' run preview",
|
|
61
|
-
"dev-vv": "pnpm -filter 'examples-vite-vite*' run dev",
|
|
62
|
-
"dev-nv": "pnpm -filter 'examples-nuxt-vite-host' -filter 'examples-vite-vite-remote' run dev",
|
|
63
|
-
"preview-vv": "pnpm -filter 'examples-vite-vite*' run preview",
|
|
64
|
-
"multi-example": "pnpm --filter \"multi-example-*\" --parallel run start",
|
|
65
|
-
"test": "vitest",
|
|
66
|
-
"e2e": "playwright test"
|
|
67
70
|
}
|
|
68
|
-
}
|
|
71
|
+
}
|