forked from module-federation/vite
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpluginProxySharedModule_preBuild.ts
More file actions
107 lines (105 loc) · 4.07 KB
/
pluginProxySharedModule_preBuild.ts
File metadata and controls
107 lines (105 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { Plugin, UserConfig } from 'vite';
import { mapCodeToCodeWithSourcemap } from '../utils/mapCodeToCodeWithSourcemap';
import { NormalizedShared } from '../utils/normalizeModuleFederationOptions';
import { PromiseStore } from '../utils/PromiseStore';
import VirtualModule, { assertModuleFound } from '../utils/VirtualModule';
import {
addUsedShares,
generateLocalSharedImportMap,
getLoadShareModulePath,
getLocalSharedImportMapPath,
PREBUILD_TAG,
writeLoadShareModule,
writeLocalSharedImportMap,
writePreBuildLibPath,
} from '../virtualModules';
import { parsePromise } from './pluginModuleParseEnd';
export function proxySharedModule(options: {
shared?: NormalizedShared;
include?: string | string[];
exclude?: string | string[];
}): Plugin[] {
let { shared = {}, include, exclude } = options;
let _config: UserConfig;
return [
{
name: 'generateLocalSharedImportMap',
enforce: 'post',
load(id) {
if (id.includes(getLocalSharedImportMapPath())) {
return parsePromise.then((_) => generateLocalSharedImportMap());
}
},
transform(_, id) {
if (id.includes(getLocalSharedImportMapPath())) {
return mapCodeToCodeWithSourcemap(
parsePromise.then((_) => generateLocalSharedImportMap())
);
}
},
},
{
name: 'proxyPreBuildShared',
enforce: 'post',
configResolved(config) {
_config = config as any;
},
config(config: UserConfig, { command }) {
(config.resolve as any).alias.push(
...Object.keys(shared).map((key) => {
// When key ends with '/', only match subpaths (e.g., 'react/' matches 'react/jsx-runtime' but NOT 'react')
// When key does NOT end with '/', match both exact and subpaths (e.g., 'react' matches 'react' AND 'react/jsx-runtime')
const pattern = key.endsWith('/')
? `(^${key.replace(/\/$/, '')}/.+$)`
: `(^${key}(/.+)?$)`;
return {
// Intercept all shared requests and proxy them to loadShare
find: new RegExp(pattern),
replacement: '$1',
customResolver(source: string, importer: string) {
if (/\.css$/.test(source)) return;
const loadSharePath = getLoadShareModulePath(source);
writeLoadShareModule(source, shared[key], command);
writePreBuildLibPath(source);
addUsedShares(source);
writeLocalSharedImportMap();
return (this as any).resolve(loadSharePath, importer);
},
};
})
);
const savePrebuild = new PromiseStore<string>();
(config.resolve as any).alias.push(
...Object.keys(shared).map((key) => {
return command === 'build'
? {
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
replacement: function ($1: string) {
const module = assertModuleFound(PREBUILD_TAG, $1) as VirtualModule;
const pkgName = module.name;
return pkgName;
},
}
: {
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
replacement: '$1',
async customResolver(source: string, importer: string) {
const module = assertModuleFound(PREBUILD_TAG, source) as VirtualModule;
const pkgName = module.name;
const result = await (this as any)
.resolve(pkgName, importer)
.then((item: any) => item.id);
if (!result.includes(_config.cacheDir)) {
// save pre-bunding module id
savePrebuild.set(pkgName, Promise.resolve(result));
}
// Fix localSharedImportMap import id
return await (this as any).resolve(await savePrebuild.get(pkgName), importer);
},
};
})
);
},
},
];
}