@module-federation/vite 1.7.0 → 1.7.2
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/lib/index.cjs +271 -141
- package/lib/index.esm.js +272 -142
- package/lib/index.modern.js +243 -129
- package/lib/index.umd.js +271 -141
- package/lib/plugins/pluginMFManifest.d.ts +1 -1
- package/lib/utils/VirtualModule.d.ts +1 -0
- package/lib/utils/__tests__/VirtualModule.test.d.ts +1 -0
- package/lib/utils/__tests__/cssModuleHelpers.test.d.ts +1 -0
- package/lib/utils/cssModuleHelpers.d.ts +75 -0
- package/package.json +20 -17
package/lib/index.modern.js
CHANGED
|
@@ -2,7 +2,7 @@ import defu from 'defu';
|
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import { mkdirSync, writeFileSync, existsSync, writeFile } from 'fs';
|
|
4
4
|
import * as path from 'pathe';
|
|
5
|
-
import path__default, { resolve, parse, join, dirname
|
|
5
|
+
import path__default, { resolve, basename, parse, join, dirname } from 'pathe';
|
|
6
6
|
import { createFilter } from '@rollup/pluginutils';
|
|
7
7
|
import { walk } from 'estree-walker';
|
|
8
8
|
import MagicString from 'magic-string';
|
|
@@ -97,7 +97,7 @@ const addEntry = ({
|
|
|
97
97
|
emitFileOptions.fileName = fileName;
|
|
98
98
|
}
|
|
99
99
|
emitFileId = this.emitFile(emitFileOptions);
|
|
100
|
-
if (htmlFilePath) {
|
|
100
|
+
if (htmlFilePath && fs.existsSync(htmlFilePath)) {
|
|
101
101
|
const htmlContent = fs.readFileSync(htmlFilePath, 'utf-8');
|
|
102
102
|
const scriptRegex = /<script\s+[^>]*src=["']([^"']+)["'][^>]*>/gi;
|
|
103
103
|
let match;
|
|
@@ -138,10 +138,14 @@ const addEntry = ({
|
|
|
138
138
|
*/
|
|
139
139
|
function PluginDevProxyModuleTopLevelAwait() {
|
|
140
140
|
const filterFunction = createFilter();
|
|
141
|
+
const processedFlag = '/* already-processed-by-dev-proxy-module-top-level-await */';
|
|
141
142
|
return {
|
|
142
143
|
name: 'dev-proxy-module-top-level-await',
|
|
143
144
|
apply: 'serve',
|
|
144
145
|
transform(code, id) {
|
|
146
|
+
if (code.includes(processedFlag)) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
145
149
|
if (!code.includes('/*mf top-level-await placeholder replacement mf*/')) {
|
|
146
150
|
return null;
|
|
147
151
|
}
|
|
@@ -200,8 +204,9 @@ function PluginDevProxyModuleTopLevelAwait() {
|
|
|
200
204
|
}
|
|
201
205
|
}
|
|
202
206
|
});
|
|
207
|
+
const transformedCode = magicString.toString();
|
|
203
208
|
return {
|
|
204
|
-
code:
|
|
209
|
+
code: `${processedFlag}\n${transformedCode}`,
|
|
205
210
|
map: magicString.generateMap({
|
|
206
211
|
hires: true
|
|
207
212
|
})
|
|
@@ -481,6 +486,14 @@ function getNodeModulesDir() {
|
|
|
481
486
|
}
|
|
482
487
|
return cachedNodeModulesDir;
|
|
483
488
|
}
|
|
489
|
+
function getSuffix(name) {
|
|
490
|
+
const base = basename(name);
|
|
491
|
+
const dotIndex = base.lastIndexOf('.');
|
|
492
|
+
if (dotIndex > 0 && dotIndex < base.length - 1) {
|
|
493
|
+
return base.slice(dotIndex);
|
|
494
|
+
}
|
|
495
|
+
return '.js';
|
|
496
|
+
}
|
|
484
497
|
const patternMap = {};
|
|
485
498
|
const cacheMap = {};
|
|
486
499
|
/**
|
|
@@ -521,14 +534,13 @@ class VirtualModule {
|
|
|
521
534
|
return undefined;
|
|
522
535
|
}
|
|
523
536
|
constructor(name, tag = '__mf_v__', suffix = '') {
|
|
524
|
-
var _name$split$slice$pop;
|
|
525
537
|
this.name = void 0;
|
|
526
538
|
this.tag = void 0;
|
|
527
539
|
this.suffix = void 0;
|
|
528
540
|
this.inited = false;
|
|
529
541
|
this.name = name;
|
|
530
542
|
this.tag = tag;
|
|
531
|
-
this.suffix = suffix || (
|
|
543
|
+
this.suffix = suffix || getSuffix(name);
|
|
532
544
|
if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
|
|
533
545
|
cacheMap[this.tag][this.name] = this;
|
|
534
546
|
}
|
|
@@ -693,7 +705,7 @@ function generateLocalSharedImportMap() {
|
|
|
693
705
|
const options = getNormalizeModuleFederationOptions();
|
|
694
706
|
return `
|
|
695
707
|
const importMap = {
|
|
696
|
-
${Array.from(getUsedShares()).map(pkg => `
|
|
708
|
+
${Array.from(getUsedShares()).sort().map(pkg => `
|
|
697
709
|
${JSON.stringify(pkg)}: async () => {
|
|
698
710
|
let pkg = await import("${getPreBuildLibImportId(pkg)}")
|
|
699
711
|
return pkg
|
|
@@ -701,7 +713,7 @@ function generateLocalSharedImportMap() {
|
|
|
701
713
|
`).join(',')}
|
|
702
714
|
}
|
|
703
715
|
const usedShared = {
|
|
704
|
-
${Array.from(getUsedShares()).map(key => {
|
|
716
|
+
${Array.from(getUsedShares()).sort().map(key => {
|
|
705
717
|
const shareItem = getNormalizeShareItem(key);
|
|
706
718
|
if (!shareItem) return null;
|
|
707
719
|
return `
|
|
@@ -836,6 +848,129 @@ function initVirtualModules() {
|
|
|
836
848
|
writeRuntimeInitStatus();
|
|
837
849
|
}
|
|
838
850
|
|
|
851
|
+
const ASSET_TYPES = ['js', 'css'];
|
|
852
|
+
const LOAD_TIMINGS = ['sync', 'async'];
|
|
853
|
+
const JS_EXTENSIONS = ['.ts', '.tsx', '.jsx', '.mjs', '.cjs'];
|
|
854
|
+
/**
|
|
855
|
+
* Creates an empty asset map structure for tracking JS and CSS assets
|
|
856
|
+
* @returns Initialized asset map with sync/async arrays for JS and CSS
|
|
857
|
+
*/
|
|
858
|
+
const createEmptyAssetMap = () => ({
|
|
859
|
+
js: {
|
|
860
|
+
sync: [],
|
|
861
|
+
async: []
|
|
862
|
+
},
|
|
863
|
+
css: {
|
|
864
|
+
sync: [],
|
|
865
|
+
async: []
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
/**
|
|
869
|
+
* Tracks an asset in the preload map with deduplication
|
|
870
|
+
* @param map - The preload map to update
|
|
871
|
+
* @param key - The module key to track under
|
|
872
|
+
* @param fileName - The asset filename to track
|
|
873
|
+
* @param isAsync - Whether the asset is loaded async
|
|
874
|
+
* @param type - The asset type ('js' or 'css')
|
|
875
|
+
*/
|
|
876
|
+
const trackAsset = (map, key, fileName, isAsync, type) => {
|
|
877
|
+
if (!map[key]) {
|
|
878
|
+
map[key] = createEmptyAssetMap();
|
|
879
|
+
}
|
|
880
|
+
const target = isAsync ? map[key][type].async : map[key][type].sync;
|
|
881
|
+
if (!target.includes(fileName)) {
|
|
882
|
+
target.push(fileName);
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
/**
|
|
886
|
+
* Checks if a file is a CSS file by extension
|
|
887
|
+
* @param fileName - The filename to check
|
|
888
|
+
* @returns True if file has a CSS extension (.css, .scss, .less)
|
|
889
|
+
*/
|
|
890
|
+
const isCSSFile = fileName => {
|
|
891
|
+
return fileName.endsWith('.css') || fileName.endsWith('.scss') || fileName.endsWith('.less');
|
|
892
|
+
};
|
|
893
|
+
/**
|
|
894
|
+
* Collects all CSS assets from the bundle
|
|
895
|
+
* @param bundle - The Rollup output bundle
|
|
896
|
+
* @returns Set of CSS asset filenames
|
|
897
|
+
*/
|
|
898
|
+
const collectCssAssets = bundle => {
|
|
899
|
+
const cssAssets = new Set();
|
|
900
|
+
for (const [fileName, fileData] of Object.entries(bundle)) {
|
|
901
|
+
if (fileData.type === 'asset' && isCSSFile(fileName)) {
|
|
902
|
+
cssAssets.add(fileName);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
return cssAssets;
|
|
906
|
+
};
|
|
907
|
+
/**
|
|
908
|
+
* Processes module assets and tracks them in the files map
|
|
909
|
+
* @param bundle - The Rollup output bundle
|
|
910
|
+
* @param filesMap - The preload map to populate
|
|
911
|
+
* @param moduleMatcher - Function that matches module paths to keys
|
|
912
|
+
*/
|
|
913
|
+
const processModuleAssets = (bundle, filesMap, moduleMatcher) => {
|
|
914
|
+
for (const [fileName, fileData] of Object.entries(bundle)) {
|
|
915
|
+
if (fileData.type !== 'chunk') continue;
|
|
916
|
+
if (!fileData.modules) continue;
|
|
917
|
+
for (const modulePath of Object.keys(fileData.modules)) {
|
|
918
|
+
const matchKey = moduleMatcher(modulePath);
|
|
919
|
+
if (!matchKey) continue;
|
|
920
|
+
// Track main JS chunk
|
|
921
|
+
trackAsset(filesMap, matchKey, fileName, false, 'js');
|
|
922
|
+
// Handle dynamic imports
|
|
923
|
+
if (fileData.dynamicImports) {
|
|
924
|
+
for (const dynamicImport of fileData.dynamicImports) {
|
|
925
|
+
const importData = bundle[dynamicImport];
|
|
926
|
+
if (!importData) continue;
|
|
927
|
+
const isCss = isCSSFile(dynamicImport);
|
|
928
|
+
trackAsset(filesMap, matchKey, dynamicImport, true, isCss ? 'css' : 'js');
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
/**
|
|
935
|
+
* Deduplicates assets in the files map
|
|
936
|
+
* @param filesMap - The preload map to deduplicate
|
|
937
|
+
* @returns New deduplicated preload map
|
|
938
|
+
*/
|
|
939
|
+
const deduplicateAssets = filesMap => {
|
|
940
|
+
const result = {};
|
|
941
|
+
for (const [key, assetMaps] of Object.entries(filesMap)) {
|
|
942
|
+
result[key] = createEmptyAssetMap();
|
|
943
|
+
for (const type of ASSET_TYPES) {
|
|
944
|
+
for (const timing of LOAD_TIMINGS) {
|
|
945
|
+
result[key][type][timing] = Array.from(new Set(assetMaps[type][timing]));
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
return result;
|
|
950
|
+
};
|
|
951
|
+
/**
|
|
952
|
+
* Builds a mapping between module files and their share keys
|
|
953
|
+
* @param shareKeys - Set of share keys to map
|
|
954
|
+
* @param resolveFn - Function to resolve module paths
|
|
955
|
+
* @returns Map of file paths to their corresponding share keys
|
|
956
|
+
*/
|
|
957
|
+
const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
|
|
958
|
+
const fileToShareKey = new Map();
|
|
959
|
+
const resolutions = await Promise.all(Array.from(shareKeys).map(shareKey => resolveFn(getPreBuildLibImportId(shareKey)).then(resolution => {
|
|
960
|
+
var _resolution$id;
|
|
961
|
+
return {
|
|
962
|
+
shareKey,
|
|
963
|
+
file: resolution == null || (_resolution$id = resolution.id) == null ? void 0 : _resolution$id.split('?')[0]
|
|
964
|
+
};
|
|
965
|
+
}).catch(() => null)));
|
|
966
|
+
for (const resolution of resolutions) {
|
|
967
|
+
if (resolution != null && resolution.file) {
|
|
968
|
+
fileToShareKey.set(resolution.file, resolution.shareKey);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return fileToShareKey;
|
|
972
|
+
};
|
|
973
|
+
|
|
839
974
|
const Manifest = () => {
|
|
840
975
|
const mfOptions = getNormalizeModuleFederationOptions();
|
|
841
976
|
const {
|
|
@@ -849,21 +984,43 @@ const Manifest = () => {
|
|
|
849
984
|
mfManifestName = 'mf-manifest.json';
|
|
850
985
|
}
|
|
851
986
|
if (typeof manifestOptions !== 'boolean') {
|
|
852
|
-
mfManifestName = join((manifestOptions == null ? void 0 : manifestOptions.filePath) || '', (manifestOptions == null ? void 0 : manifestOptions.fileName) || '');
|
|
987
|
+
mfManifestName = path.join((manifestOptions == null ? void 0 : manifestOptions.filePath) || '', (manifestOptions == null ? void 0 : manifestOptions.fileName) || '');
|
|
853
988
|
}
|
|
854
|
-
let extensions;
|
|
855
989
|
let root;
|
|
856
990
|
let remoteEntryFile;
|
|
857
991
|
let publicPath;
|
|
858
992
|
let _command;
|
|
859
993
|
let _originalConfigBase;
|
|
860
994
|
let viteConfig;
|
|
995
|
+
/**
|
|
996
|
+
* Adds global CSS assets to all module exports
|
|
997
|
+
* @param filesMap - The preload map to update
|
|
998
|
+
* @param cssAssets - Set of CSS asset filenames to add
|
|
999
|
+
*/
|
|
1000
|
+
const addCssAssetsToAllExports = (filesMap, cssAssets) => {
|
|
1001
|
+
Object.keys(filesMap).forEach(key => {
|
|
1002
|
+
cssAssets.forEach(cssAsset => {
|
|
1003
|
+
trackAsset(filesMap, key, cssAsset, false, 'css');
|
|
1004
|
+
});
|
|
1005
|
+
});
|
|
1006
|
+
};
|
|
861
1007
|
return [{
|
|
862
1008
|
name: 'module-federation-manifest',
|
|
863
1009
|
apply: 'serve',
|
|
1010
|
+
/**
|
|
1011
|
+
* Stores resolved Vite config for later use
|
|
1012
|
+
*/
|
|
1013
|
+
/**
|
|
1014
|
+
* Finalizes configuration after all plugins are resolved
|
|
1015
|
+
* @param config - Fully resolved Vite config
|
|
1016
|
+
*/
|
|
864
1017
|
configResolved(config) {
|
|
865
1018
|
viteConfig = config;
|
|
866
1019
|
},
|
|
1020
|
+
/**
|
|
1021
|
+
* Configures dev server middleware to handle manifest requests
|
|
1022
|
+
* @param server - Vite dev server instance
|
|
1023
|
+
*/
|
|
867
1024
|
configureServer(server) {
|
|
868
1025
|
server.middlewares.use((req, res, next) => {
|
|
869
1026
|
var _req$url;
|
|
@@ -911,119 +1068,85 @@ const Manifest = () => {
|
|
|
911
1068
|
}, {
|
|
912
1069
|
name: 'module-federation-manifest',
|
|
913
1070
|
enforce: 'post',
|
|
1071
|
+
/**
|
|
1072
|
+
* Initial plugin configuration
|
|
1073
|
+
* @param config - Vite config object
|
|
1074
|
+
* @param command - Current Vite command (serve/build)
|
|
1075
|
+
*/
|
|
914
1076
|
config(config, {
|
|
915
1077
|
command
|
|
916
1078
|
}) {
|
|
917
1079
|
if (!config.build) config.build = {};
|
|
918
|
-
if (!config.build.manifest)
|
|
1080
|
+
if (!config.build.manifest) {
|
|
1081
|
+
config.build.manifest = config.build.manifest || !!manifestOptions;
|
|
1082
|
+
}
|
|
919
1083
|
_command = command;
|
|
920
1084
|
_originalConfigBase = config.base;
|
|
921
1085
|
},
|
|
922
1086
|
configResolved(config) {
|
|
923
1087
|
root = config.root;
|
|
924
|
-
extensions = config.resolve.extensions || ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'];
|
|
925
1088
|
let base = config.base;
|
|
926
1089
|
if (_command === 'serve') {
|
|
927
1090
|
base = (config.server.origin || '') + config.base;
|
|
928
1091
|
}
|
|
929
1092
|
publicPath = _originalConfigBase === '' ? 'auto' : base ? base.replace(/\/?$/, '/') : 'auto';
|
|
930
1093
|
},
|
|
1094
|
+
/**
|
|
1095
|
+
* Generates the module federation manifest file
|
|
1096
|
+
* @param options - Rollup output options
|
|
1097
|
+
* @param bundle - Generated bundle assets
|
|
1098
|
+
*/
|
|
931
1099
|
async generateBundle(options, bundle) {
|
|
932
1100
|
if (!mfManifestName) return;
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
const isModuleMatched = (relativeModulePath, preloadModule) => {
|
|
937
|
-
// 先尝试直接匹配
|
|
938
|
-
if (relativeModulePath === preloadModule) return true;
|
|
939
|
-
// 如果 preloadModule 没有后缀,尝试添加可能的后缀进行匹配
|
|
940
|
-
for (const ext of extensions) {
|
|
941
|
-
if (relativeModulePath === `${preloadModule}${ext}`) {
|
|
942
|
-
return true;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
return false;
|
|
946
|
-
};
|
|
947
|
-
// 遍历打包生成的每个文件
|
|
948
|
-
for (const [fileName, fileData] of Object.entries(bundle)) {
|
|
1101
|
+
let filesMap = {};
|
|
1102
|
+
// First pass: Find remoteEntry file
|
|
1103
|
+
for (const [_, fileData] of Object.entries(bundle)) {
|
|
949
1104
|
if (mfOptions.filename.replace(/[\[\]]/g, '_').replace(/\.[^/.]+$/, '') === fileData.name || fileData.name === 'remoteEntry') {
|
|
950
1105
|
remoteEntryFile = fileData.fileName;
|
|
951
|
-
|
|
952
|
-
if (fileData.type === 'chunk') {
|
|
953
|
-
// 遍历该文件的所有模块
|
|
954
|
-
for (const modulePath of Object.keys(fileData.modules)) {
|
|
955
|
-
// 将绝对路径转换为相对于 Vite root 的相对路径
|
|
956
|
-
const relativeModulePath = relative(root, modulePath);
|
|
957
|
-
// 检查模块是否在 preloadModules 列表中
|
|
958
|
-
for (const preloadModule of exposesModules) {
|
|
959
|
-
const formatPreloadModule = preloadModule.replace('./', '');
|
|
960
|
-
if (isModuleMatched(relativeModulePath, formatPreloadModule)) {
|
|
961
|
-
if (!filesContainingModules[preloadModule]) {
|
|
962
|
-
filesContainingModules[preloadModule] = {
|
|
963
|
-
sync: [],
|
|
964
|
-
async: []
|
|
965
|
-
};
|
|
966
|
-
}
|
|
967
|
-
console.log(Object.keys(fileData.modules));
|
|
968
|
-
filesContainingModules[preloadModule].sync.push(fileName);
|
|
969
|
-
filesContainingModules[preloadModule].async.push(...(fileData.dynamicImports || []));
|
|
970
|
-
findSynchronousImports(fileName, filesContainingModules[preloadModule].sync);
|
|
971
|
-
break; // 如果找到匹配,跳出循环
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
}
|
|
1106
|
+
break; // We can break early since we only need to find remoteEntry once
|
|
975
1107
|
}
|
|
976
1108
|
}
|
|
977
|
-
//
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
const fileToShareKey = {};
|
|
991
|
-
await Promise.all(Array.from(getUsedShares()).map(async shareKey => {
|
|
992
|
-
const file = (await this.resolve(getPreBuildLibImportId(shareKey))).id.split('?')[0];
|
|
993
|
-
fileToShareKey[file] = shareKey;
|
|
994
|
-
}));
|
|
995
|
-
// 遍历打包生成的每个文件
|
|
996
|
-
for (const [fileName, fileData] of Object.entries(bundle)) {
|
|
997
|
-
if (fileData.type === 'chunk') {
|
|
998
|
-
// 遍历该文件的所有模块
|
|
999
|
-
for (const modulePath of Object.keys(fileData.modules)) {
|
|
1000
|
-
const sharedKey = fileToShareKey[modulePath];
|
|
1001
|
-
if (sharedKey) {
|
|
1002
|
-
if (!filesContainingModules[sharedKey]) {
|
|
1003
|
-
filesContainingModules[sharedKey] = {
|
|
1004
|
-
sync: [],
|
|
1005
|
-
async: []
|
|
1006
|
-
};
|
|
1007
|
-
}
|
|
1008
|
-
filesContainingModules[sharedKey].sync.push(fileName);
|
|
1009
|
-
filesContainingModules[sharedKey].async.push(...(fileData.dynamicImports || []));
|
|
1010
|
-
findSynchronousImports(fileName, filesContainingModules[sharedKey].sync);
|
|
1011
|
-
break; // 如果找到匹配,跳出循环
|
|
1012
|
-
}
|
|
1109
|
+
// Second pass: Collect all CSS assets
|
|
1110
|
+
const allCssAssets = collectCssAssets(bundle);
|
|
1111
|
+
const exposesModules = Object.keys(mfOptions.exposes).map(item => mfOptions.exposes[item].import);
|
|
1112
|
+
// Process exposed modules
|
|
1113
|
+
processModuleAssets(bundle, filesMap, modulePath => {
|
|
1114
|
+
const absoluteModulePath = path.resolve(root, modulePath);
|
|
1115
|
+
return exposesModules.find(exposeModule => {
|
|
1116
|
+
const exposePath = path.resolve(root, exposeModule);
|
|
1117
|
+
// First try exact path match
|
|
1118
|
+
if (absoluteModulePath === exposePath) {
|
|
1119
|
+
return true;
|
|
1013
1120
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1121
|
+
// Then try path match without known extensions
|
|
1122
|
+
const getPathWithoutKnownExt = filePath => {
|
|
1123
|
+
const ext = path.extname(filePath);
|
|
1124
|
+
return JS_EXTENSIONS.includes(ext) ? path.join(path.dirname(filePath), path.basename(filePath, ext)) : filePath;
|
|
1125
|
+
};
|
|
1126
|
+
const modulePathNoExt = getPathWithoutKnownExt(absoluteModulePath);
|
|
1127
|
+
const exposePathNoExt = getPathWithoutKnownExt(exposePath);
|
|
1128
|
+
return modulePathNoExt === exposePathNoExt;
|
|
1129
|
+
});
|
|
1019
1130
|
});
|
|
1131
|
+
// Process shared modules
|
|
1132
|
+
const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
|
|
1133
|
+
processModuleAssets(bundle, filesMap, modulePath => fileToShareKey.get(modulePath));
|
|
1134
|
+
// Add all CSS assets to every export
|
|
1135
|
+
addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
1136
|
+
// Final deduplication of all assets
|
|
1137
|
+
filesMap = deduplicateAssets(filesMap);
|
|
1020
1138
|
this.emitFile({
|
|
1021
1139
|
type: 'asset',
|
|
1022
1140
|
fileName: mfManifestName,
|
|
1023
|
-
source: JSON.stringify(generateMFManifest(
|
|
1141
|
+
source: JSON.stringify(generateMFManifest(filesMap))
|
|
1024
1142
|
});
|
|
1025
1143
|
}
|
|
1026
1144
|
}];
|
|
1145
|
+
/**
|
|
1146
|
+
* Generates the final manifest JSON structure
|
|
1147
|
+
* @param preloadMap - Map of module assets to include
|
|
1148
|
+
* @returns Complete manifest object
|
|
1149
|
+
*/
|
|
1027
1150
|
function generateMFManifest(preloadMap) {
|
|
1028
1151
|
const options = getNormalizeModuleFederationOptions();
|
|
1029
1152
|
const {
|
|
@@ -1034,23 +1157,17 @@ const Manifest = () => {
|
|
|
1034
1157
|
path: '',
|
|
1035
1158
|
type: 'module'
|
|
1036
1159
|
};
|
|
1037
|
-
|
|
1038
|
-
const
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
alias: remoteKey,
|
|
1046
|
-
entry: '*'
|
|
1047
|
-
});
|
|
1048
|
-
});
|
|
1049
|
-
});
|
|
1050
|
-
// @ts-ignore
|
|
1160
|
+
// Process remotes
|
|
1161
|
+
const remotes = Array.from(Object.entries(getUsedRemotesMap())).flatMap(([remoteKey, modules]) => Array.from(modules).map(moduleKey => ({
|
|
1162
|
+
federationContainerName: options.remotes[remoteKey].entry,
|
|
1163
|
+
moduleName: moduleKey.replace(remoteKey, '').replace('/', ''),
|
|
1164
|
+
alias: remoteKey,
|
|
1165
|
+
entry: '*'
|
|
1166
|
+
})));
|
|
1167
|
+
// Process shared dependencies
|
|
1051
1168
|
const shared = Array.from(getUsedShares()).map(shareKey => {
|
|
1052
|
-
var _preloadMap$shareKey, _preloadMap$shareKey2;
|
|
1053
1169
|
const shareItem = getNormalizeShareItem(shareKey);
|
|
1170
|
+
const assets = preloadMap[shareKey] || createEmptyAssetMap();
|
|
1054
1171
|
return {
|
|
1055
1172
|
id: `${name}:${shareKey}`,
|
|
1056
1173
|
name: shareKey,
|
|
@@ -1058,42 +1175,42 @@ const Manifest = () => {
|
|
|
1058
1175
|
requiredVersion: shareItem.shareConfig.requiredVersion,
|
|
1059
1176
|
assets: {
|
|
1060
1177
|
js: {
|
|
1061
|
-
async:
|
|
1062
|
-
sync:
|
|
1178
|
+
async: assets.js.async,
|
|
1179
|
+
sync: assets.js.sync
|
|
1063
1180
|
},
|
|
1064
1181
|
css: {
|
|
1065
|
-
async:
|
|
1066
|
-
sync:
|
|
1182
|
+
async: assets.css.async,
|
|
1183
|
+
sync: assets.css.sync
|
|
1067
1184
|
}
|
|
1068
1185
|
}
|
|
1069
1186
|
};
|
|
1070
|
-
}).filter(
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
// assets(.css, .jpg, .svg等)其他资源, 不重要, 暂未处理
|
|
1187
|
+
}).filter(Boolean);
|
|
1188
|
+
// Process exposed modules
|
|
1189
|
+
const exposes = Object.entries(options.exposes).map(([key, value]) => {
|
|
1074
1190
|
const formatKey = key.replace('./', '');
|
|
1075
|
-
const sourceFile =
|
|
1191
|
+
const sourceFile = value.import;
|
|
1192
|
+
const assets = preloadMap[sourceFile] || createEmptyAssetMap();
|
|
1076
1193
|
return {
|
|
1077
|
-
id: name
|
|
1194
|
+
id: `${name}:${formatKey}`,
|
|
1078
1195
|
name: formatKey,
|
|
1079
1196
|
assets: {
|
|
1080
1197
|
js: {
|
|
1081
|
-
async:
|
|
1082
|
-
sync:
|
|
1198
|
+
async: assets.js.async,
|
|
1199
|
+
sync: assets.js.sync
|
|
1083
1200
|
},
|
|
1084
1201
|
css: {
|
|
1085
|
-
|
|
1086
|
-
|
|
1202
|
+
async: assets.css.async,
|
|
1203
|
+
sync: assets.css.sync
|
|
1087
1204
|
}
|
|
1088
1205
|
},
|
|
1089
1206
|
path: key
|
|
1090
1207
|
};
|
|
1091
|
-
}).filter(
|
|
1092
|
-
|
|
1208
|
+
}).filter(Boolean);
|
|
1209
|
+
return {
|
|
1093
1210
|
id: name,
|
|
1094
|
-
name
|
|
1211
|
+
name,
|
|
1095
1212
|
metaData: _extends({
|
|
1096
|
-
name
|
|
1213
|
+
name,
|
|
1097
1214
|
type: 'app',
|
|
1098
1215
|
buildInfo: {
|
|
1099
1216
|
buildVersion: '1.0.0',
|
|
@@ -1104,8 +1221,6 @@ const Manifest = () => {
|
|
|
1104
1221
|
types: {
|
|
1105
1222
|
path: '',
|
|
1106
1223
|
name: ''
|
|
1107
|
-
// "zip": "@mf-types.zip",
|
|
1108
|
-
// "api": "@mf-types.d.ts"
|
|
1109
1224
|
},
|
|
1110
1225
|
globalName: name,
|
|
1111
1226
|
pluginVersion: '0.2.5'
|
|
@@ -1118,7 +1233,6 @@ const Manifest = () => {
|
|
|
1118
1233
|
remotes,
|
|
1119
1234
|
exposes
|
|
1120
1235
|
};
|
|
1121
|
-
return result;
|
|
1122
1236
|
}
|
|
1123
1237
|
};
|
|
1124
1238
|
|