@jiayouzuo/vite-module-federation-core 0.6.1
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 +416 -0
- package/dist/dev/expose.d.ts +3 -0
- package/dist/dev/expose.d.ts.map +1 -0
- package/dist/dev/expose.js +17 -0
- package/dist/dev/remote.d.ts +3 -0
- package/dist/dev/remote.d.ts.map +1 -0
- package/dist/dev/remote.js +274 -0
- package/dist/dev/shared.d.ts +3 -0
- package/dist/dev/shared.d.ts.map +1 -0
- package/dist/dev/shared.js +22 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +181 -0
- package/dist/prod/expose.d.ts +3 -0
- package/dist/prod/expose.d.ts.map +1 -0
- package/dist/prod/expose.js +231 -0
- package/dist/prod/remote.d.ts +3 -0
- package/dist/prod/remote.d.ts.map +1 -0
- package/dist/prod/remote.js +392 -0
- package/dist/prod/shared.d.ts +4 -0
- package/dist/prod/shared.d.ts.map +1 -0
- package/dist/prod/shared.js +247 -0
- package/dist/types.d.ts +160 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +51 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +327 -0
- package/dist/virtual.d.ts +6 -0
- package/dist/virtual.d.ts.map +1 -0
- package/dist/virtual.js +34 -0
- package/dist/walker.d.ts +16 -0
- package/dist/walker.d.ts.map +1 -0
- package/dist/walker.js +110 -0
- package/package.json +48 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 开发环境 - 远程模块插件
|
|
3
|
+
*/
|
|
4
|
+
import MagicString from 'magic-string';
|
|
5
|
+
import { parsedOptions, parseRemoteOptions, devRemotes, createRemotesMap, getModuleMarker, getFileExtname, normalizePath, REMOTE_FROM_PARAMETER } from '../utils.js';
|
|
6
|
+
import { walk } from '../walker.js';
|
|
7
|
+
// 默认需要转换的文件类型
|
|
8
|
+
const defaultTransformFileTypes = ['.js', '.ts', '.jsx', '.tsx', '.mjs', '.cjs', '.vue', '.svelte'];
|
|
9
|
+
export function devRemotePlugin(options) {
|
|
10
|
+
parsedOptions.devRemote = parseRemoteOptions(options);
|
|
11
|
+
for (const item of parsedOptions.devRemote) {
|
|
12
|
+
devRemotes.push({
|
|
13
|
+
id: item[0],
|
|
14
|
+
regexp: new RegExp(`^${item[0]}/.+?`),
|
|
15
|
+
config: item[1]
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
// 合并文件类型配置
|
|
19
|
+
const transformFileTypes = (options.transformFileTypes ?? [])
|
|
20
|
+
.concat(defaultTransformFileTypes)
|
|
21
|
+
.map((item) => item.toLowerCase());
|
|
22
|
+
const transformFileTypeSet = new Set(transformFileTypes);
|
|
23
|
+
let viteDevServer;
|
|
24
|
+
return {
|
|
25
|
+
name: 'federation:remote-development',
|
|
26
|
+
virtualFile: options.remotes ? {
|
|
27
|
+
__federation__: `
|
|
28
|
+
${createRemotesMap(devRemotes)}
|
|
29
|
+
const loadJS = async (url, fn) => {
|
|
30
|
+
const resolvedUrl = typeof url === 'function' ? await url() : url;
|
|
31
|
+
const script = document.createElement('script')
|
|
32
|
+
script.type = 'text/javascript';
|
|
33
|
+
script.onload = fn;
|
|
34
|
+
script.src = resolvedUrl;
|
|
35
|
+
document.getElementsByTagName('head')[0].appendChild(script);
|
|
36
|
+
}
|
|
37
|
+
function get(name, ${REMOTE_FROM_PARAMETER}){
|
|
38
|
+
return import(/* @vite-ignore */ name).then(module => ()=> {
|
|
39
|
+
if (${REMOTE_FROM_PARAMETER} === 'webpack') {
|
|
40
|
+
return Object.prototype.toString.call(module).indexOf('Module') > -1 && module.default ? module.default : module
|
|
41
|
+
}
|
|
42
|
+
return module
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
const wrapShareModule = ${REMOTE_FROM_PARAMETER} => {
|
|
46
|
+
return {
|
|
47
|
+
${getModuleMarker('shareScope')}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const initMap = Object.create(null);
|
|
51
|
+
async function __federation_method_ensure(remoteId) {
|
|
52
|
+
const remote = remotesMap[remoteId];
|
|
53
|
+
if (!remote.inited) {
|
|
54
|
+
if ('var' === remote.format) {
|
|
55
|
+
return new Promise(resolve => {
|
|
56
|
+
const callback = () => {
|
|
57
|
+
if (!remote.inited) {
|
|
58
|
+
remote.lib = window[remoteId];
|
|
59
|
+
remote.lib.init(wrapShareModule(remote.from))
|
|
60
|
+
remote.inited = true;
|
|
61
|
+
}
|
|
62
|
+
resolve(remote.lib);
|
|
63
|
+
}
|
|
64
|
+
return loadJS(remote.url, callback);
|
|
65
|
+
});
|
|
66
|
+
} else if (['esm', 'systemjs'].includes(remote.format)) {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const getUrl = typeof remote.url === 'function' ? remote.url : () => Promise.resolve(remote.url);
|
|
69
|
+
getUrl().then(url => {
|
|
70
|
+
import(/* @vite-ignore */ url).then(lib => {
|
|
71
|
+
if (!remote.inited) {
|
|
72
|
+
const shareScope = wrapShareModule(remote.from)
|
|
73
|
+
lib.init(shareScope);
|
|
74
|
+
remote.lib = lib;
|
|
75
|
+
remote.lib.init(shareScope);
|
|
76
|
+
remote.inited = true;
|
|
77
|
+
}
|
|
78
|
+
resolve(remote.lib);
|
|
79
|
+
}).catch(reject)
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
return remote.lib;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function __federation_method_unwrapDefault(module) {
|
|
89
|
+
return (module?.__esModule || module?.[Symbol.toStringTag] === 'Module')?module.default:module
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function __federation_method_wrapDefault(module ,need){
|
|
93
|
+
if (!module?.default && need) {
|
|
94
|
+
let obj = Object.create(null);
|
|
95
|
+
obj.default = module;
|
|
96
|
+
obj.__esModule = true;
|
|
97
|
+
return obj;
|
|
98
|
+
}
|
|
99
|
+
return module;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function __federation_method_getRemote(remoteName, componentName){
|
|
103
|
+
return __federation_method_ensure(remoteName).then((remote) => remote.get(componentName).then(factory => factory()));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function __federation_method_setRemote(remoteName, remoteConfig) {
|
|
107
|
+
remotesMap[remoteName] = remoteConfig;
|
|
108
|
+
}
|
|
109
|
+
export {__federation_method_ensure, __federation_method_getRemote , __federation_method_setRemote , __federation_method_unwrapDefault , __federation_method_wrapDefault}
|
|
110
|
+
;`
|
|
111
|
+
} : { __federation__: '' },
|
|
112
|
+
// 配置 optimizeDeps.exclude
|
|
113
|
+
config(config) {
|
|
114
|
+
if (parsedOptions.devRemote.length) {
|
|
115
|
+
const excludeRemotes = [];
|
|
116
|
+
parsedOptions.devRemote.forEach((item) => excludeRemotes.push(item[0]));
|
|
117
|
+
let optimizeDeps = config.optimizeDeps;
|
|
118
|
+
if (!optimizeDeps) {
|
|
119
|
+
optimizeDeps = config.optimizeDeps = {};
|
|
120
|
+
}
|
|
121
|
+
if (!optimizeDeps.exclude) {
|
|
122
|
+
optimizeDeps.exclude = [];
|
|
123
|
+
}
|
|
124
|
+
optimizeDeps.exclude = optimizeDeps.exclude.concat(excludeRemotes);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
configureServer(server) {
|
|
128
|
+
viteDevServer = server;
|
|
129
|
+
},
|
|
130
|
+
async transform(code, id) {
|
|
131
|
+
// 处理 __federation__ 虚拟模块的 shareScope 替换
|
|
132
|
+
if (id === '\0virtual:__federation__') {
|
|
133
|
+
const scopeCode = await devSharedScopeCode.call(this, viteDevServer, parsedOptions.devShared);
|
|
134
|
+
return code.replace(getModuleMarker('shareScope'), scopeCode.join(','));
|
|
135
|
+
}
|
|
136
|
+
// 检查文件类型是否需要转换
|
|
137
|
+
const fileExtname = getFileExtname(id);
|
|
138
|
+
if (!transformFileTypeSet.has((fileExtname ?? '').toLowerCase())) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
let ast = null;
|
|
142
|
+
try {
|
|
143
|
+
ast = this.parse(code);
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
console.error(err);
|
|
147
|
+
}
|
|
148
|
+
if (!ast) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const magicString = new MagicString(code);
|
|
152
|
+
const hasStaticImported = new Map();
|
|
153
|
+
let requiresRuntime = false;
|
|
154
|
+
let manualRequired = null;
|
|
155
|
+
walk(ast, {
|
|
156
|
+
enter(node) {
|
|
157
|
+
// 检测手动导入 virtual:__federation__
|
|
158
|
+
if (node.type === 'ImportDeclaration' && node.source?.value === 'virtual:__federation__') {
|
|
159
|
+
manualRequired = node;
|
|
160
|
+
}
|
|
161
|
+
// 处理远程模块导入
|
|
162
|
+
if ((node.type === 'ImportExpression' || node.type === 'ImportDeclaration' || node.type === 'ExportNamedDeclaration') &&
|
|
163
|
+
node.source?.value?.indexOf('/') > -1) {
|
|
164
|
+
const moduleId = node.source.value;
|
|
165
|
+
const remote = devRemotes.find((r) => r.regexp.test(moduleId));
|
|
166
|
+
const needWrap = remote?.config.from === 'vite';
|
|
167
|
+
if (remote) {
|
|
168
|
+
requiresRuntime = true;
|
|
169
|
+
const modName = `.${moduleId.slice(remote.id.length)}`;
|
|
170
|
+
switch (node.type) {
|
|
171
|
+
case 'ImportExpression': {
|
|
172
|
+
magicString.overwrite(node.start, node.end, `__federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)}).then(module=>__federation_method_wrapDefault(module, ${needWrap}))`);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case 'ImportDeclaration': {
|
|
176
|
+
if (node.specifiers?.length) {
|
|
177
|
+
const afterImportName = `__federation_var_${moduleId.replace(/[@/\\.-]/g, '')}`;
|
|
178
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
179
|
+
magicString.overwrite(node.start, node.end, `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)});`);
|
|
180
|
+
hasStaticImported.set(moduleId, afterImportName);
|
|
181
|
+
}
|
|
182
|
+
let deconstructStr = '';
|
|
183
|
+
node.specifiers.forEach((spec) => {
|
|
184
|
+
if (spec.type === 'ImportDefaultSpecifier') {
|
|
185
|
+
magicString.appendRight(node.end, `\n let ${spec.local.name} = __federation_method_unwrapDefault(${afterImportName}) `);
|
|
186
|
+
}
|
|
187
|
+
else if (spec.type === 'ImportSpecifier') {
|
|
188
|
+
const importedName = spec.imported.name;
|
|
189
|
+
const localName = spec.local.name;
|
|
190
|
+
deconstructStr += `${importedName === localName ? localName : `${importedName} : ${localName}`},`;
|
|
191
|
+
}
|
|
192
|
+
else if (spec.type === 'ImportNamespaceSpecifier') {
|
|
193
|
+
magicString.appendRight(node.end, `let {${spec.local.name}} = ${afterImportName}`);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
if (deconstructStr.length > 0) {
|
|
197
|
+
magicString.appendRight(node.end, `\n let {${deconstructStr.slice(0, -1)}} = ${afterImportName}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case 'ExportNamedDeclaration': {
|
|
203
|
+
const afterImportName = `__federation_var_${moduleId.replace(/[@/\\.-]/g, '')}`;
|
|
204
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
205
|
+
hasStaticImported.set(moduleId, afterImportName);
|
|
206
|
+
magicString.overwrite(node.start, node.end, `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)});`);
|
|
207
|
+
}
|
|
208
|
+
if (node.specifiers.length > 0) {
|
|
209
|
+
const specifiers = node.specifiers;
|
|
210
|
+
let exportContent = '';
|
|
211
|
+
let deconstructContent = '';
|
|
212
|
+
specifiers.forEach((spec) => {
|
|
213
|
+
const localName = spec.local.name;
|
|
214
|
+
const exportName = spec.exported.name;
|
|
215
|
+
const variableName = `${afterImportName}_${localName}`;
|
|
216
|
+
deconstructContent = deconstructContent.concat(`${localName}:${variableName},`);
|
|
217
|
+
exportContent = exportContent.concat(`${variableName} as ${exportName},`);
|
|
218
|
+
});
|
|
219
|
+
magicString.append(`\n const {${deconstructContent.slice(0, deconstructContent.length - 1)}} = ${afterImportName}; \n`);
|
|
220
|
+
magicString.append(`\n export {${exportContent.slice(0, exportContent.length - 1)}}; `);
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
if (requiresRuntime) {
|
|
230
|
+
let requiresCode = `import {__federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault} from '__federation__';\n\n`;
|
|
231
|
+
if (manualRequired) {
|
|
232
|
+
requiresCode = `import {__federation_method_setRemote, __federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault} from '__federation__';\n\n`;
|
|
233
|
+
magicString.overwrite(manualRequired.start, manualRequired.end, ``);
|
|
234
|
+
}
|
|
235
|
+
magicString.prepend(requiresCode);
|
|
236
|
+
}
|
|
237
|
+
if (requiresRuntime) {
|
|
238
|
+
return magicString.toString();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* 生成开发环境共享模块代码
|
|
245
|
+
*/
|
|
246
|
+
async function devSharedScopeCode(viteDevServer, shared) {
|
|
247
|
+
const res = [];
|
|
248
|
+
if (shared.length && viteDevServer) {
|
|
249
|
+
const serverConfiguration = viteDevServer.config.server;
|
|
250
|
+
const base = viteDevServer.config.base;
|
|
251
|
+
const cwdPath = normalizePath(process.cwd());
|
|
252
|
+
for (const item of shared) {
|
|
253
|
+
const moduleInfo = await this.resolve(item[1].packagePath, undefined, { skipSelf: true });
|
|
254
|
+
if (!moduleInfo)
|
|
255
|
+
continue;
|
|
256
|
+
const moduleFilePath = normalizePath(moduleInfo.id);
|
|
257
|
+
const idx = moduleFilePath.indexOf(cwdPath);
|
|
258
|
+
const relativePath = idx === 0
|
|
259
|
+
? require('path').posix.join(base, moduleFilePath.slice(cwdPath.length))
|
|
260
|
+
: null;
|
|
261
|
+
const sharedName = item[0];
|
|
262
|
+
const obj = item[1];
|
|
263
|
+
let str = '';
|
|
264
|
+
if (typeof obj === 'object') {
|
|
265
|
+
const origin = serverConfiguration.origin;
|
|
266
|
+
const pathname = relativePath ?? `/@fs/${moduleInfo.id}`;
|
|
267
|
+
const url = origin ? `'${origin}${pathname}'` : `window.location.origin+'${pathname}'`;
|
|
268
|
+
str += `get:()=> get(${url}, ${REMOTE_FROM_PARAMETER})`;
|
|
269
|
+
res.push(`'${sharedName}':{'${obj.version}':{${str}}}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return res;
|
|
274
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/dev/shared.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAGnF,wBAAgB,eAAe,CAAC,OAAO,EAAE,2BAA2B,GAAG,mBAAmB,CAsBzF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 开发环境 - 共享依赖插件
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync } from 'fs';
|
|
5
|
+
import { parsedOptions, parseSharedOptions } from '../utils.js';
|
|
6
|
+
export function devSharedPlugin(options) {
|
|
7
|
+
parsedOptions.devShared = parseSharedOptions(options);
|
|
8
|
+
return {
|
|
9
|
+
name: 'federation:shared-development',
|
|
10
|
+
async configureServer(server) {
|
|
11
|
+
for (const arr of parsedOptions.devShared) {
|
|
12
|
+
if (!arr[1].version && !arr[1].manuallyPackagePathSetting) {
|
|
13
|
+
const packageJsonPath = (await server.pluginContainer.resolveId(`${arr[1].packagePath}/package.json`))?.id;
|
|
14
|
+
if (packageJsonPath) {
|
|
15
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, { encoding: 'utf-8' }));
|
|
16
|
+
arr[1].version = packageJson.version;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模块联邦插件入口
|
|
3
|
+
*/
|
|
4
|
+
import type { Plugin } from 'vite';
|
|
5
|
+
import type { VitePluginFederationOptions } from './types.js';
|
|
6
|
+
export type { VitePluginFederationOptions } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Vite模块联邦插件
|
|
9
|
+
*/
|
|
10
|
+
export default function federation(options: VitePluginFederationOptions): Plugin[];
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,MAAM,CAAA;AACjE,OAAO,KAAK,EAAE,2BAA2B,EAAuB,MAAM,YAAY,CAAA;AAUlF,YAAY,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AA8B7D;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,OAAO,EAAE,2BAA2B,GAAG,MAAM,EAAE,CAiKjF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { virtual } from './virtual.js';
|
|
2
|
+
import { builderInfo, parsedOptions, viteConfigResolved } from './utils.js';
|
|
3
|
+
import { prodSharedPlugin } from './prod/shared.js';
|
|
4
|
+
import { prodRemotePlugin } from './prod/remote.js';
|
|
5
|
+
import { prodExposePlugin } from './prod/expose.js';
|
|
6
|
+
import { devSharedPlugin } from './dev/shared.js';
|
|
7
|
+
import { devRemotePlugin } from './dev/remote.js';
|
|
8
|
+
import { devExposePlugin } from './dev/expose.js';
|
|
9
|
+
// semver satisfy 函数
|
|
10
|
+
const federation_fn_satisfy = `
|
|
11
|
+
const satisfy = (version, range) => {
|
|
12
|
+
if (range.startsWith('^') || range.startsWith('~')) range = '>=' + range.slice(1)
|
|
13
|
+
if (!range || range === '*') return true
|
|
14
|
+
const op = range.match(/^([<>=~^]+)/)?.[1] || '='
|
|
15
|
+
const target = range.replace(/^[<>=~^]+/, '').split('.').map(Number)
|
|
16
|
+
const current = version.split('.').map(Number)
|
|
17
|
+
for (let i = 0; i < 3; i++) {
|
|
18
|
+
target[i] = target[i] || 0
|
|
19
|
+
current[i] = current[i] || 0
|
|
20
|
+
}
|
|
21
|
+
if (op === '~') return current[0] === target[0] && current[1] === target[1] && current[2] >= target[2]
|
|
22
|
+
if (op === '^') {
|
|
23
|
+
if (target[0] !== 0) return current[0] === target[0] && (current[1] > target[1] || (current[1] === target[1] && current[2] >= target[2]))
|
|
24
|
+
if (target[1] !== 0) return current[0] === target[0] && current[1] === target[1] && current[2] >= target[2]
|
|
25
|
+
return current[0] === target[0] && current[1] === target[1] && current[2] === target[2]
|
|
26
|
+
}
|
|
27
|
+
if (op === '=') return current.join('.') === target.join('.')
|
|
28
|
+
if (op === '>=') return current[0] > target[0] || (current[0] === target[0] && (current[1] > target[1] || (current[1] === target[1] && current[2] >= target[2])))
|
|
29
|
+
if (op === '<=') return current[0] < target[0] || (current[0] === target[0] && (current[1] < target[1] || (current[1] === target[1] && current[2] <= target[2])))
|
|
30
|
+
if (op === '>') return current[0] > target[0] || (current[0] === target[0] && (current[1] > target[1] || (current[1] === target[1] && current[2] > target[2])))
|
|
31
|
+
if (op === '<') return current[0] < target[0] || (current[0] === target[0] && (current[1] < target[1] || (current[1] === target[1] && current[2] < target[2])))
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
export { satisfy }
|
|
35
|
+
`;
|
|
36
|
+
/**
|
|
37
|
+
* Vite模块联邦插件
|
|
38
|
+
*/
|
|
39
|
+
export default function federation(options) {
|
|
40
|
+
const isBuild = process.env.NODE_ENV === 'production' || process.argv.includes('build');
|
|
41
|
+
// 根据环境选择插件
|
|
42
|
+
const subPlugins = isBuild
|
|
43
|
+
? [
|
|
44
|
+
prodSharedPlugin(options),
|
|
45
|
+
prodRemotePlugin(options),
|
|
46
|
+
prodExposePlugin(options)
|
|
47
|
+
]
|
|
48
|
+
: [
|
|
49
|
+
devSharedPlugin(options),
|
|
50
|
+
devRemotePlugin(options),
|
|
51
|
+
devExposePlugin(options)
|
|
52
|
+
];
|
|
53
|
+
// 收集所有虚拟文件
|
|
54
|
+
const virtualFiles = {
|
|
55
|
+
__federation_fn_satisfy: federation_fn_satisfy
|
|
56
|
+
};
|
|
57
|
+
for (const plugin of subPlugins) {
|
|
58
|
+
if (plugin.virtualFile) {
|
|
59
|
+
Object.assign(virtualFiles, plugin.virtualFile);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 创建虚拟模块插件
|
|
63
|
+
const virtualPlugin = virtual(virtualFiles);
|
|
64
|
+
// 主插件
|
|
65
|
+
const mainPlugin = {
|
|
66
|
+
name: 'vite-module-federation',
|
|
67
|
+
enforce: 'post',
|
|
68
|
+
config(config, { command }) {
|
|
69
|
+
// 设置构建信息
|
|
70
|
+
builderInfo.builder = 'vite';
|
|
71
|
+
builderInfo.assetsDir = config.build?.assetsDir || 'assets';
|
|
72
|
+
// 调用子插件的 config
|
|
73
|
+
for (const plugin of subPlugins) {
|
|
74
|
+
if (plugin.config) {
|
|
75
|
+
plugin.config.call(this, config, { command });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
configResolved(config) {
|
|
80
|
+
viteConfigResolved.config = config;
|
|
81
|
+
builderInfo.isHost = !!parsedOptions.prodRemote.length || !!parsedOptions.devRemote.length;
|
|
82
|
+
builderInfo.isRemote = !!parsedOptions.prodExpose.length || !!parsedOptions.devExpose.length;
|
|
83
|
+
builderInfo.isShared = !!parsedOptions.prodShared.length || !!parsedOptions.devShared.length;
|
|
84
|
+
for (const plugin of subPlugins) {
|
|
85
|
+
if (plugin.configResolved) {
|
|
86
|
+
plugin.configResolved.call(this, config);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
configureServer(server) {
|
|
91
|
+
for (const plugin of subPlugins) {
|
|
92
|
+
if (plugin.configureServer) {
|
|
93
|
+
plugin.configureServer.call(this, server);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
async resolveId(id, importer) {
|
|
98
|
+
// 先检查虚拟模块
|
|
99
|
+
const v = virtualPlugin.resolveId(id, importer);
|
|
100
|
+
if (v)
|
|
101
|
+
return v;
|
|
102
|
+
// 处理 __federation_fn_import 虚拟模块
|
|
103
|
+
if (id === '\0virtual:__federation_fn_import') {
|
|
104
|
+
return { id: '\0virtual:__federation_fn_import', moduleSideEffects: true };
|
|
105
|
+
}
|
|
106
|
+
// 处理 __federation_fn_satisfy 模块解析
|
|
107
|
+
if (id === '__federation_fn_satisfy') {
|
|
108
|
+
return { id: '\0virtual:__federation_fn_satisfy', moduleSideEffects: true };
|
|
109
|
+
}
|
|
110
|
+
// 处理 virtual:__federation__ 模块
|
|
111
|
+
if (id === 'virtual:__federation__') {
|
|
112
|
+
return { id: '\0virtual:__federation__', moduleSideEffects: true };
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
},
|
|
116
|
+
load(id) {
|
|
117
|
+
return virtualPlugin.load(id);
|
|
118
|
+
},
|
|
119
|
+
options(inputOptions) {
|
|
120
|
+
for (const plugin of subPlugins) {
|
|
121
|
+
if (plugin.options) {
|
|
122
|
+
inputOptions = plugin.options.call(this, inputOptions) || inputOptions;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return inputOptions;
|
|
126
|
+
},
|
|
127
|
+
async buildStart(inputOptions) {
|
|
128
|
+
for (const plugin of subPlugins) {
|
|
129
|
+
if (plugin.buildStart) {
|
|
130
|
+
await plugin.buildStart.call(this, inputOptions);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
async transform(code, id) {
|
|
135
|
+
for (const plugin of subPlugins) {
|
|
136
|
+
if (plugin.transform) {
|
|
137
|
+
const result = await plugin.transform.call(this, code, id);
|
|
138
|
+
if (result) {
|
|
139
|
+
if (typeof result === 'string') {
|
|
140
|
+
code = result;
|
|
141
|
+
}
|
|
142
|
+
else if (result.code) {
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
outputOptions(outputOptions) {
|
|
150
|
+
for (const plugin of subPlugins) {
|
|
151
|
+
if (plugin.outputOptions) {
|
|
152
|
+
outputOptions = plugin.outputOptions.call(this, outputOptions) || outputOptions;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return outputOptions;
|
|
156
|
+
},
|
|
157
|
+
renderChunk(code, chunkInfo, options) {
|
|
158
|
+
for (const plugin of subPlugins) {
|
|
159
|
+
if (plugin.renderChunk) {
|
|
160
|
+
const result = plugin.renderChunk.call(this, code, chunkInfo, options);
|
|
161
|
+
if (result) {
|
|
162
|
+
if (typeof result === 'string') {
|
|
163
|
+
code = result;
|
|
164
|
+
}
|
|
165
|
+
else if (result.code) {
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
generateBundle(options, bundle, isWrite) {
|
|
173
|
+
for (const plugin of subPlugins) {
|
|
174
|
+
if (plugin.generateBundle) {
|
|
175
|
+
plugin.generateBundle.call(this, options, bundle, isWrite);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
return [mainPlugin];
|
|
181
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expose.d.ts","sourceRoot":"","sources":["../../src/prod/expose.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAiBnF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,2BAA2B,GAAG,mBAAmB,CAqQ1F"}
|