@sbee/vite-federation 0.0.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 +168 -0
- package/dist/index.js +1284 -0
- package/dist/index.mjs +1261 -0
- package/dist/runtime/index.d.ts +80 -0
- package/dist/runtime.js +176 -0
- package/dist/runtime.mjs +170 -0
- package/dist/satisfy.js +223 -0
- package/dist/satisfy.mjs +222 -0
- package/package.json +58 -0
- package/types/index.d.ts +334 -0
- package/types/pluginHooks.d.ts +4 -0
- package/types/viteDevServer.d.ts +22 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1261 @@
|
|
|
1
|
+
import path, { basename, dirname, extname, join, parse, posix, relative, resolve } from "path";
|
|
2
|
+
import { RolldownMagicString } from "rolldown";
|
|
3
|
+
//#region src/public.ts
|
|
4
|
+
var EXPOSES_MAP = /* @__PURE__ */ new Map();
|
|
5
|
+
var EXPOSES_KEY_MAP = /* @__PURE__ */ new Map();
|
|
6
|
+
var SHARED = "shared";
|
|
7
|
+
var DYNAMIC_LOADING_CSS = "dynamicLoadingCss";
|
|
8
|
+
var DYNAMIC_LOADING_CSS_PREFIX = "__v__css__";
|
|
9
|
+
var DEFAULT_ENTRY_FILENAME = "remoteEntry.js";
|
|
10
|
+
var EXTERNALS = [];
|
|
11
|
+
var builderInfo = {
|
|
12
|
+
builder: "rolldown",
|
|
13
|
+
version: "",
|
|
14
|
+
assetsDir: "",
|
|
15
|
+
isHost: false,
|
|
16
|
+
isRemote: false,
|
|
17
|
+
isShared: false
|
|
18
|
+
};
|
|
19
|
+
var parsedOptions = {
|
|
20
|
+
prodExpose: [],
|
|
21
|
+
prodRemote: [],
|
|
22
|
+
prodShared: [],
|
|
23
|
+
devShared: [],
|
|
24
|
+
devExpose: [],
|
|
25
|
+
devRemote: []
|
|
26
|
+
};
|
|
27
|
+
var devRemotes = [];
|
|
28
|
+
var prodRemotes = [];
|
|
29
|
+
var viteConfigResolved = { config: void 0 };
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/utils/html.ts
|
|
32
|
+
var unaryTags = /* @__PURE__ */ new Set([
|
|
33
|
+
"link",
|
|
34
|
+
"meta",
|
|
35
|
+
"base"
|
|
36
|
+
]);
|
|
37
|
+
function serializeTag({ tag, attrs, children }, indent = "") {
|
|
38
|
+
if (unaryTags.has(tag)) return `<${tag}${serializeAttrs(attrs)}>`;
|
|
39
|
+
else return `<${tag}${serializeAttrs(attrs)}>${serializeTags(children, incrementIndent(indent))}</${tag}>`;
|
|
40
|
+
}
|
|
41
|
+
function serializeTags(tags, indent = "") {
|
|
42
|
+
if (typeof tags === "string") return tags;
|
|
43
|
+
else if (tags && tags.length) return tags.map((tag) => `${indent}${serializeTag(tag, indent)}\n`).join("");
|
|
44
|
+
return "";
|
|
45
|
+
}
|
|
46
|
+
function serializeAttrs(attrs) {
|
|
47
|
+
let res = "";
|
|
48
|
+
for (const key in attrs) if (typeof attrs[key] === "boolean") res += attrs[key] ? ` ${key}` : ``;
|
|
49
|
+
else res += ` ${key}="${escapeHtml(attrs[key])}"`;
|
|
50
|
+
return res;
|
|
51
|
+
}
|
|
52
|
+
function incrementIndent(indent = "") {
|
|
53
|
+
return `${indent}${indent[0] === " " ? " " : " "}`;
|
|
54
|
+
}
|
|
55
|
+
var matchHtmlRegExp = /["'&<>]/;
|
|
56
|
+
function escapeHtml(string) {
|
|
57
|
+
const str = "" + string;
|
|
58
|
+
const match = matchHtmlRegExp.exec(str);
|
|
59
|
+
if (!match) return str;
|
|
60
|
+
let escape;
|
|
61
|
+
let html = "";
|
|
62
|
+
let index = 0;
|
|
63
|
+
let lastIndex = 0;
|
|
64
|
+
for (index = match.index; index < str.length; index++) {
|
|
65
|
+
switch (str.charCodeAt(index)) {
|
|
66
|
+
case 34:
|
|
67
|
+
escape = """;
|
|
68
|
+
break;
|
|
69
|
+
case 38:
|
|
70
|
+
escape = "&";
|
|
71
|
+
break;
|
|
72
|
+
case 39:
|
|
73
|
+
escape = "'";
|
|
74
|
+
break;
|
|
75
|
+
case 60:
|
|
76
|
+
escape = "<";
|
|
77
|
+
break;
|
|
78
|
+
case 62:
|
|
79
|
+
escape = ">";
|
|
80
|
+
break;
|
|
81
|
+
default: continue;
|
|
82
|
+
}
|
|
83
|
+
if (lastIndex !== index) html += str.substring(lastIndex, index);
|
|
84
|
+
lastIndex = index + 1;
|
|
85
|
+
html += escape;
|
|
86
|
+
}
|
|
87
|
+
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
|
|
88
|
+
}
|
|
89
|
+
var headInjectRE = /([ \t]*)<\/head>/i;
|
|
90
|
+
var headPrependInjectRE = /([ \t]*)<head[^>]*>/i;
|
|
91
|
+
var htmlPrependInjectRE = /([ \t]*)<html[^>]*>/i;
|
|
92
|
+
var bodyPrependInjectRE = /([ \t]*)<body[^>]*>/i;
|
|
93
|
+
var doctypePrependInjectRE = /<!doctype html>/i;
|
|
94
|
+
var toPreloadTag = (href) => ({
|
|
95
|
+
tag: "link",
|
|
96
|
+
attrs: {
|
|
97
|
+
rel: "modulepreload",
|
|
98
|
+
crossorigin: true,
|
|
99
|
+
href
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
function injectToHead(html, tags, prepend = false) {
|
|
103
|
+
if (tags.length === 0) return html;
|
|
104
|
+
if (prepend) {
|
|
105
|
+
if (headPrependInjectRE.test(html)) return html.replace(headPrependInjectRE, (match, p1) => `${match}\n${serializeTags(tags, incrementIndent(p1))}`);
|
|
106
|
+
} else {
|
|
107
|
+
if (headInjectRE.test(html)) return html.replace(headInjectRE, (match, p1) => `${serializeTags(tags, incrementIndent(p1))}${match}`);
|
|
108
|
+
if (bodyPrependInjectRE.test(html)) return html.replace(bodyPrependInjectRE, (match, p1) => `${serializeTags(tags, p1)}\n${match}`);
|
|
109
|
+
}
|
|
110
|
+
return prependInjectFallback(html, tags);
|
|
111
|
+
}
|
|
112
|
+
function prependInjectFallback(html, tags) {
|
|
113
|
+
if (htmlPrependInjectRE.test(html)) return html.replace(htmlPrependInjectRE, `$&\n${serializeTags(tags)}`);
|
|
114
|
+
if (doctypePrependInjectRE.test(html)) return html.replace(doctypePrependInjectRE, `$&\n${serializeTags(tags)}`);
|
|
115
|
+
return serializeTags(tags) + html;
|
|
116
|
+
}
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/utils/index.ts
|
|
119
|
+
var MagicString = RolldownMagicString;
|
|
120
|
+
var SKIP_KEYS = /* @__PURE__ */ new Set([
|
|
121
|
+
"type",
|
|
122
|
+
"start",
|
|
123
|
+
"end",
|
|
124
|
+
"loc",
|
|
125
|
+
"span"
|
|
126
|
+
]);
|
|
127
|
+
function walk(node, visitor) {
|
|
128
|
+
if (!node) return;
|
|
129
|
+
const enter = typeof visitor === "function" ? visitor : visitor.enter;
|
|
130
|
+
const leave = typeof visitor === "function" ? void 0 : visitor.leave;
|
|
131
|
+
enter?.(node);
|
|
132
|
+
for (const key of Object.keys(node)) {
|
|
133
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
134
|
+
const child = node[key];
|
|
135
|
+
if (!child || typeof child !== "object") continue;
|
|
136
|
+
if (Array.isArray(child)) {
|
|
137
|
+
for (const item of child) if (item && typeof item === "object" && "type" in item) walk(item, visitor);
|
|
138
|
+
} else if ("type" in child) walk(child, visitor);
|
|
139
|
+
}
|
|
140
|
+
leave?.(node);
|
|
141
|
+
}
|
|
142
|
+
function parseSharedOptions(options) {
|
|
143
|
+
return parseOptions(options.shared || {}, (value, key) => ({
|
|
144
|
+
import: true,
|
|
145
|
+
shareScope: "default",
|
|
146
|
+
packagePath: key,
|
|
147
|
+
manuallyPackagePathSetting: false,
|
|
148
|
+
generate: true,
|
|
149
|
+
modulePreload: false
|
|
150
|
+
}), (value, key) => {
|
|
151
|
+
value.import = value.import ?? true;
|
|
152
|
+
value.shareScope = value.shareScope || "default";
|
|
153
|
+
value.packagePath = value.packagePath || key;
|
|
154
|
+
value.manuallyPackagePathSetting = value.packagePath !== key;
|
|
155
|
+
value.generate = value.generate ?? true;
|
|
156
|
+
value.modulePreload = value.modulePreload ?? false;
|
|
157
|
+
return value;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function parseExposeOptions(options) {
|
|
161
|
+
return parseOptions(options.exposes, (item) => {
|
|
162
|
+
return {
|
|
163
|
+
import: item,
|
|
164
|
+
name: void 0,
|
|
165
|
+
dontAppendStylesToHead: false
|
|
166
|
+
};
|
|
167
|
+
}, (item) => ({
|
|
168
|
+
import: item.import,
|
|
169
|
+
name: item.name || void 0,
|
|
170
|
+
dontAppendStylesToHead: item.dontAppendStylesToHead || false
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
function parseRemoteOptions(options) {
|
|
174
|
+
return parseOptions(options.remotes ? options.remotes : {}, (item) => ({
|
|
175
|
+
external: Array.isArray(item) ? item : [item],
|
|
176
|
+
shareScope: options.shareScope || "default",
|
|
177
|
+
format: "esm",
|
|
178
|
+
from: "vite",
|
|
179
|
+
externalType: "url"
|
|
180
|
+
}), (item) => ({
|
|
181
|
+
external: Array.isArray(item.external) ? item.external : [item.external],
|
|
182
|
+
shareScope: item.shareScope || options.shareScope || "default",
|
|
183
|
+
format: item.format || "esm",
|
|
184
|
+
from: item.from ?? "vite",
|
|
185
|
+
externalType: item.externalType || "url"
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
function parseOptions(options, normalizeSimple, normalizeOptions) {
|
|
189
|
+
if (!options) return [];
|
|
190
|
+
const list = [];
|
|
191
|
+
const array = (items) => {
|
|
192
|
+
for (const item of items) if (typeof item === "string") list.push([item, normalizeSimple(item, item)]);
|
|
193
|
+
else if (item && typeof item === "object") object(item);
|
|
194
|
+
else throw new Error("Unexpected options format");
|
|
195
|
+
};
|
|
196
|
+
const object = (obj) => {
|
|
197
|
+
for (const [key, value] of Object.entries(obj)) if (typeof value === "string" || Array.isArray(value)) list.push([key, normalizeSimple(value, key)]);
|
|
198
|
+
else list.push([key, normalizeOptions(value, key)]);
|
|
199
|
+
};
|
|
200
|
+
if (Array.isArray(options)) array(options);
|
|
201
|
+
else if (typeof options === "object") object(options);
|
|
202
|
+
else throw new Error("Unexpected options format");
|
|
203
|
+
return list;
|
|
204
|
+
}
|
|
205
|
+
var letterReg = /* @__PURE__ */ new RegExp("[0-9a-zA-Z]+");
|
|
206
|
+
function removeNonRegLetter(str, reg = letterReg) {
|
|
207
|
+
let needUpperCase = false;
|
|
208
|
+
const chars = [];
|
|
209
|
+
for (const c of str) if (reg.test(c)) {
|
|
210
|
+
chars.push(needUpperCase ? c.toUpperCase() : c);
|
|
211
|
+
needUpperCase = false;
|
|
212
|
+
} else needUpperCase = true;
|
|
213
|
+
return chars.join("");
|
|
214
|
+
}
|
|
215
|
+
function getModuleMarker(value, type) {
|
|
216
|
+
return type ? `__rf_${type}__${value}` : `__rf_placeholder__${value}`;
|
|
217
|
+
}
|
|
218
|
+
function normalizePath(id) {
|
|
219
|
+
return posix.normalize(id.replace(/\\/g, "/"));
|
|
220
|
+
}
|
|
221
|
+
function createRemotesMap(remotes) {
|
|
222
|
+
const createUrl = (remote) => {
|
|
223
|
+
const external = remote.config.external[0];
|
|
224
|
+
if (remote.config.externalType === "promise") return `()=>${external}`;
|
|
225
|
+
else return `'${external}'`;
|
|
226
|
+
};
|
|
227
|
+
return `const remotesMap = {
|
|
228
|
+
${remotes.map((remote) => `'${remote.id}':{url:${createUrl(remote)},format:'${remote.config.format}',from:'${remote.config.from}'}`).join(",\n ")}
|
|
229
|
+
};`;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* get file extname from url
|
|
233
|
+
* @param url
|
|
234
|
+
*/
|
|
235
|
+
function getFileExtname(url) {
|
|
236
|
+
const fileNameAndParamArr = normalizePath(url).split("/");
|
|
237
|
+
const fileName = fileNameAndParamArr[fileNameAndParamArr.length - 1].split("?")[0];
|
|
238
|
+
return path.extname(fileName);
|
|
239
|
+
}
|
|
240
|
+
var REMOTE_FROM_PARAMETER = "remoteFrom";
|
|
241
|
+
var NAME_CHAR_REG = /* @__PURE__ */ new RegExp("[0-9a-zA-Z@_-]+");
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/dev/expose-development.ts
|
|
244
|
+
function devExposePlugin(options) {
|
|
245
|
+
parsedOptions.devExpose = parseExposeOptions(options);
|
|
246
|
+
return { name: "sbee:expose-development" };
|
|
247
|
+
}
|
|
248
|
+
//#endregion
|
|
249
|
+
//#region src/dev/remote-development.ts
|
|
250
|
+
function devRemotePlugin(options) {
|
|
251
|
+
parsedOptions.devRemote = parseRemoteOptions(options);
|
|
252
|
+
for (const item of parsedOptions.devRemote) devRemotes.push({
|
|
253
|
+
id: item[0],
|
|
254
|
+
regexp: new RegExp(`^${item[0]}/.+?`),
|
|
255
|
+
config: item[1]
|
|
256
|
+
});
|
|
257
|
+
options.transformFileTypes = (options.transformFileTypes ?? []).concat([
|
|
258
|
+
".js",
|
|
259
|
+
".ts",
|
|
260
|
+
".jsx",
|
|
261
|
+
".tsx",
|
|
262
|
+
".mjs",
|
|
263
|
+
".cjs",
|
|
264
|
+
".vue",
|
|
265
|
+
".svelte"
|
|
266
|
+
]).map((item) => item.toLowerCase());
|
|
267
|
+
const transformFileTypeSet = new Set(options.transformFileTypes);
|
|
268
|
+
let viteDevServer;
|
|
269
|
+
return {
|
|
270
|
+
name: "sbee:remote-development",
|
|
271
|
+
virtualFile: options.remotes ? { __federation__: `
|
|
272
|
+
${createRemotesMap(devRemotes)}
|
|
273
|
+
const loadJS = async (url, fn) => {
|
|
274
|
+
const resolvedUrl = typeof url === 'function' ? await url() : url;
|
|
275
|
+
const script = document.createElement('script')
|
|
276
|
+
script.type = 'text/javascript';
|
|
277
|
+
script.onload = fn;
|
|
278
|
+
script.src = resolvedUrl;
|
|
279
|
+
document.getElementsByTagName('head')[0].appendChild(script);
|
|
280
|
+
}
|
|
281
|
+
function get(name, ${REMOTE_FROM_PARAMETER}){
|
|
282
|
+
return import(/* @vite-ignore */ name).then(module => ()=> {
|
|
283
|
+
if (${REMOTE_FROM_PARAMETER} === 'webpack') {
|
|
284
|
+
return Object.prototype.toString.call(module).indexOf('Module') > -1 && module.default ? module.default : module
|
|
285
|
+
}
|
|
286
|
+
return module
|
|
287
|
+
})
|
|
288
|
+
}
|
|
289
|
+
const wrapShareScope = ${REMOTE_FROM_PARAMETER} => {
|
|
290
|
+
return {
|
|
291
|
+
${getModuleMarker("shareScope")}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async function __federation_method_ensure(remoteId) {
|
|
295
|
+
const remote = remotesMap[remoteId];
|
|
296
|
+
if (!remote.inited) {
|
|
297
|
+
if ('var' === remote.format) {
|
|
298
|
+
// loading js with script tag
|
|
299
|
+
return new Promise(resolve => {
|
|
300
|
+
const callback = () => {
|
|
301
|
+
if (!remote.inited) {
|
|
302
|
+
remote.lib = window[remoteId];
|
|
303
|
+
remote.lib.init(wrapShareScope(remote.from))
|
|
304
|
+
remote.inited = true;
|
|
305
|
+
}
|
|
306
|
+
resolve(remote.lib);
|
|
307
|
+
}
|
|
308
|
+
return loadJS(remote.url, callback);
|
|
309
|
+
});
|
|
310
|
+
} else if (['esm', 'systemjs'].includes(remote.format)) {
|
|
311
|
+
// loading js with import(...)
|
|
312
|
+
return new Promise((resolve, reject) => {
|
|
313
|
+
const getUrl = typeof remote.url === 'function' ? remote.url : () => Promise.resolve(remote.url);
|
|
314
|
+
getUrl().then(url => {
|
|
315
|
+
import(/* @vite-ignore */ url).then(lib => {
|
|
316
|
+
if (!remote.inited) {
|
|
317
|
+
const shareScope = wrapShareScope(remote.from)
|
|
318
|
+
remote.lib = lib;
|
|
319
|
+
remote.lib.init(shareScope);
|
|
320
|
+
remote.inited = true;
|
|
321
|
+
}
|
|
322
|
+
resolve(remote.lib);
|
|
323
|
+
}).catch(reject)
|
|
324
|
+
})
|
|
325
|
+
})
|
|
326
|
+
}
|
|
327
|
+
} else {
|
|
328
|
+
return remote.lib;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function __federation_method_unwrapDefault(module) {
|
|
333
|
+
return (module?.__esModule || module?.[Symbol.toStringTag] === 'Module')?module.default:module
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function __federation_method_wrapDefault(module ,need){
|
|
337
|
+
if (!module?.default && need) {
|
|
338
|
+
let obj = Object.create(null);
|
|
339
|
+
obj.default = module;
|
|
340
|
+
obj.__esModule = true;
|
|
341
|
+
return obj;
|
|
342
|
+
}
|
|
343
|
+
return module;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function __federation_method_getRemote(remoteName, componentName){
|
|
347
|
+
return __federation_method_ensure(remoteName).then((remote) => remote.get(componentName).then(factory => factory()));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function __federation_method_setRemote(remoteName, remoteConfig) {
|
|
351
|
+
remotesMap[remoteName] = remoteConfig;
|
|
352
|
+
}
|
|
353
|
+
export {__federation_method_ensure, __federation_method_getRemote , __federation_method_setRemote , __federation_method_unwrapDefault , __federation_method_wrapDefault}
|
|
354
|
+
;` } : { __federation__: "" },
|
|
355
|
+
config(config) {
|
|
356
|
+
if (parsedOptions.devRemote.length) {
|
|
357
|
+
const excludeRemotes = [];
|
|
358
|
+
parsedOptions.devRemote.forEach((item) => excludeRemotes.push(item[0]));
|
|
359
|
+
let optimizeDeps = config.optimizeDeps;
|
|
360
|
+
if (!optimizeDeps) optimizeDeps = config.optimizeDeps = {};
|
|
361
|
+
if (!optimizeDeps.exclude) optimizeDeps.exclude = [];
|
|
362
|
+
optimizeDeps.exclude = optimizeDeps.exclude.concat(excludeRemotes);
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
configureServer(server) {
|
|
366
|
+
viteDevServer = server;
|
|
367
|
+
},
|
|
368
|
+
async transform(code, id) {
|
|
369
|
+
if (builderInfo.isHost && !builderInfo.isRemote) {
|
|
370
|
+
for (const arr of parsedOptions.devShared) if (!arr[1].version && !arr[1].manuallyPackagePathSetting) {
|
|
371
|
+
const packageJsonPath = (await this.resolve(`${arr[0]}/package.json`))?.id;
|
|
372
|
+
if (!packageJsonPath) this.error(`No description file or no version in description file (usually package.json) of ${arr[0]}(${packageJsonPath}). Add version to description file, or manually specify version in shared config.`);
|
|
373
|
+
else {
|
|
374
|
+
const json = await this.fs.readFile(packageJsonPath, { encoding: "utf8" }).then((jsonStr) => JSON.parse(jsonStr));
|
|
375
|
+
arr[1].version = json.version;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (id === "\0virtual:__federation__") {
|
|
380
|
+
const scopeCode = await devSharedScopeCode.call(this, parsedOptions.devShared);
|
|
381
|
+
return code.replace(getModuleMarker("shareScope"), scopeCode.join(","));
|
|
382
|
+
}
|
|
383
|
+
const fileExtname = getFileExtname(id);
|
|
384
|
+
if (!transformFileTypeSet.has((fileExtname ?? "").toLowerCase())) return;
|
|
385
|
+
let ast = null;
|
|
386
|
+
try {
|
|
387
|
+
ast = this.parse(code);
|
|
388
|
+
} catch (err) {
|
|
389
|
+
console.error(err);
|
|
390
|
+
}
|
|
391
|
+
if (!ast) return null;
|
|
392
|
+
const magicString = new MagicString(code);
|
|
393
|
+
const hasStaticImported = /* @__PURE__ */ new Map();
|
|
394
|
+
let requiresRuntime = false;
|
|
395
|
+
let manualRequired = null;
|
|
396
|
+
walk(ast, { enter(node) {
|
|
397
|
+
if (node.type === "ImportDeclaration" && node.source?.value === "virtual:__federation__") manualRequired = node;
|
|
398
|
+
if ((node.type === "ImportExpression" || node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration") && node.source?.value?.indexOf("/") > -1) {
|
|
399
|
+
const moduleId = node.source.value;
|
|
400
|
+
const remote = devRemotes.find((r) => r.regexp.test(moduleId));
|
|
401
|
+
const needWrap = remote?.config.from === "vite";
|
|
402
|
+
if (remote) {
|
|
403
|
+
requiresRuntime = true;
|
|
404
|
+
const modName = `.${moduleId.slice(remote.id.length)}`;
|
|
405
|
+
switch (node.type) {
|
|
406
|
+
case "ImportExpression":
|
|
407
|
+
magicString.overwrite(node.start, node.end, `__federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)}).then(module=>__federation_method_wrapDefault(module, ${needWrap}))`);
|
|
408
|
+
break;
|
|
409
|
+
case "ImportDeclaration":
|
|
410
|
+
if (node.specifiers?.length) {
|
|
411
|
+
const afterImportName = `__federation_var_${moduleId.replace(/[@/\\.-]/g, "")}`;
|
|
412
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
413
|
+
magicString.overwrite(node.start, node.end, `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)});`);
|
|
414
|
+
hasStaticImported.set(moduleId, afterImportName);
|
|
415
|
+
}
|
|
416
|
+
let deconstructStr = "";
|
|
417
|
+
node.specifiers.forEach((spec) => {
|
|
418
|
+
if (spec.type === "ImportDefaultSpecifier") magicString.appendRight(node.end, `\n let ${spec.local.name} = __federation_method_unwrapDefault(${afterImportName}) `);
|
|
419
|
+
else if (spec.type === "ImportSpecifier") {
|
|
420
|
+
const importedName = spec.imported.name;
|
|
421
|
+
const localName = spec.local.name;
|
|
422
|
+
deconstructStr += `${importedName === localName ? localName : `${importedName} : ${localName}`},`;
|
|
423
|
+
} else if (spec.type === "ImportNamespaceSpecifier") magicString.appendRight(node.end, `let {${spec.local.name}} = ${afterImportName}`);
|
|
424
|
+
});
|
|
425
|
+
if (deconstructStr.length > 0) magicString.appendRight(node.end, `\n let {${deconstructStr.slice(0, -1)}} = ${afterImportName}`);
|
|
426
|
+
}
|
|
427
|
+
break;
|
|
428
|
+
case "ExportNamedDeclaration": {
|
|
429
|
+
const afterImportName = `__federation_var_${moduleId.replace(/[@/\\.-]/g, "")}`;
|
|
430
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
431
|
+
hasStaticImported.set(moduleId, afterImportName);
|
|
432
|
+
magicString.overwrite(node.start, node.end, `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)});`);
|
|
433
|
+
}
|
|
434
|
+
if (node.specifiers.length > 0) {
|
|
435
|
+
const specifiers = node.specifiers;
|
|
436
|
+
let exportContent = "";
|
|
437
|
+
let deconstructContent = "";
|
|
438
|
+
specifiers.forEach((spec) => {
|
|
439
|
+
const localName = spec.local.name;
|
|
440
|
+
const exportName = spec.exported.name;
|
|
441
|
+
const variableName = `${afterImportName}_${localName}`;
|
|
442
|
+
deconstructContent = deconstructContent.concat(`${localName}:${variableName},`);
|
|
443
|
+
exportContent = exportContent.concat(`${variableName} as ${exportName},`);
|
|
444
|
+
});
|
|
445
|
+
magicString.append(`\n const {${deconstructContent.slice(0, deconstructContent.length - 1)}} = ${afterImportName}; \n`);
|
|
446
|
+
magicString.append(`\n export {${exportContent.slice(0, exportContent.length - 1)}}; `);
|
|
447
|
+
}
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
} });
|
|
454
|
+
if (requiresRuntime) {
|
|
455
|
+
let requiresCode = `import {__federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault} from '__federation__';\n\n`;
|
|
456
|
+
if (manualRequired) {
|
|
457
|
+
requiresCode = `import {__federation_method_setRemote, __federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault} from '__federation__';\n\n`;
|
|
458
|
+
magicString.overwrite(manualRequired.start, manualRequired.end, ``);
|
|
459
|
+
}
|
|
460
|
+
magicString.prepend(requiresCode);
|
|
461
|
+
}
|
|
462
|
+
return magicString.toString();
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
async function devSharedScopeCode(shared) {
|
|
466
|
+
const res = [];
|
|
467
|
+
if (shared.length) {
|
|
468
|
+
const serverConfiguration = viteDevServer.config.server;
|
|
469
|
+
const base = viteDevServer.config.base;
|
|
470
|
+
const cwdPath = normalizePath(process.cwd());
|
|
471
|
+
for (const item of shared) {
|
|
472
|
+
const moduleInfo = await this.resolve(item[1].packagePath, void 0, { skipSelf: true });
|
|
473
|
+
if (!moduleInfo) continue;
|
|
474
|
+
const moduleFilePath = normalizePath(moduleInfo.id);
|
|
475
|
+
const relativePath = moduleFilePath.indexOf(cwdPath) === 0 ? posix.join(base, moduleFilePath.slice(cwdPath.length)) : null;
|
|
476
|
+
const sharedName = item[0];
|
|
477
|
+
const obj = item[1];
|
|
478
|
+
let str = "";
|
|
479
|
+
if (typeof obj === "object") {
|
|
480
|
+
const origin = serverConfiguration.origin;
|
|
481
|
+
const pathname = relativePath ?? `/@fs/${moduleInfo.id}`;
|
|
482
|
+
const url = origin ? `'${origin}${pathname}'` : `window.location.origin+'${pathname}'`;
|
|
483
|
+
str += `get:()=> get(${url}, ${REMOTE_FROM_PARAMETER})`;
|
|
484
|
+
res.push(`'${sharedName}':{'${obj.version}':{${str}}}`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return res;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region src/dev/shared-development.ts
|
|
493
|
+
function devSharedPlugin(options) {
|
|
494
|
+
parsedOptions.devShared = parseSharedOptions(options);
|
|
495
|
+
return { name: "sbee:shared-development" };
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/prod/expose-production.ts
|
|
499
|
+
function prodExposePlugin(options) {
|
|
500
|
+
const exposeOptions = parseExposeOptions(options);
|
|
501
|
+
let moduleMap = "";
|
|
502
|
+
if (!parsedOptions.prodExpose.some((expose) => {
|
|
503
|
+
return expose[0] === exposeOptions[0]?.[0];
|
|
504
|
+
})) parsedOptions.prodExpose = Array.prototype.concat(parsedOptions.prodExpose, exposeOptions);
|
|
505
|
+
for (const item of exposeOptions) {
|
|
506
|
+
const moduleName = getModuleMarker(`\${${item[0]}}`, SHARED);
|
|
507
|
+
EXTERNALS.push(moduleName);
|
|
508
|
+
const exposeFilepath = normalizePath(resolve(item[1].import));
|
|
509
|
+
EXPOSES_MAP.set(item[0], exposeFilepath);
|
|
510
|
+
EXPOSES_KEY_MAP.set(item[0], `__federation_expose_${removeNonRegLetter(item[0], NAME_CHAR_REG)}`);
|
|
511
|
+
moduleMap += `\n"${item[0]}":()=>{
|
|
512
|
+
${DYNAMIC_LOADING_CSS}('${DYNAMIC_LOADING_CSS_PREFIX}${exposeFilepath}', ${item[1].dontAppendStylesToHead}, '${item[0]}')
|
|
513
|
+
return __federation_import('\${__federation_expose_${item[0]}}').then(module =>Object.keys(module).every(item => exportSet.has(item)) ? () => module.default : () => module)},`;
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
name: "sbee:expose-production",
|
|
517
|
+
virtualFile: { [`__remoteEntryHelper__${options.filename}`]: `
|
|
518
|
+
const currentImports = {}
|
|
519
|
+
const exportSet = new Set(['Module', '__esModule', 'default', '_export_sfc']);
|
|
520
|
+
let moduleMap = {${moduleMap}}
|
|
521
|
+
const seen = {}
|
|
522
|
+
export const ${DYNAMIC_LOADING_CSS} = (cssFilePaths, dontAppendStylesToHead, exposeItemName) => {
|
|
523
|
+
const metaUrl = import.meta.url;
|
|
524
|
+
if (typeof metaUrl === 'undefined') {
|
|
525
|
+
console.warn('The remote style takes effect only when the build.target option in the vite.config.ts file is higher than that of "es2020".');
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
const curUrl = metaUrl.substring(0, metaUrl.lastIndexOf('${options.filename}'));
|
|
530
|
+
const base = __VITE_BASE_PLACEHOLDER__;
|
|
531
|
+
const assetsDir = __VITE_ASSETS_DIR_PLACEHOLDER__;
|
|
532
|
+
|
|
533
|
+
cssFilePaths.forEach(cssPath => {
|
|
534
|
+
let href = '';
|
|
535
|
+
const baseUrl = base || curUrl;
|
|
536
|
+
if (baseUrl) {
|
|
537
|
+
const trimmer = {
|
|
538
|
+
trailing: (path) => (path.endsWith('/') ? path.slice(0, -1) : path),
|
|
539
|
+
leading: (path) => (path.startsWith('/') ? path.slice(1) : path)
|
|
540
|
+
}
|
|
541
|
+
const isAbsoluteUrl = (url) => url.startsWith('http') || url.startsWith('//');
|
|
542
|
+
|
|
543
|
+
const cleanBaseUrl = trimmer.trailing(baseUrl);
|
|
544
|
+
const cleanCssPath = trimmer.leading(cssPath);
|
|
545
|
+
const cleanCurUrl = trimmer.trailing(curUrl);
|
|
546
|
+
|
|
547
|
+
if (isAbsoluteUrl(baseUrl)) {
|
|
548
|
+
href = [cleanBaseUrl, cleanCssPath].filter(Boolean).join('/');
|
|
549
|
+
} else {
|
|
550
|
+
if (cleanCurUrl.includes(cleanBaseUrl)) {
|
|
551
|
+
href = [cleanCurUrl, cleanCssPath].filter(Boolean).join('/');
|
|
552
|
+
} else {
|
|
553
|
+
href = [cleanCurUrl + cleanBaseUrl, cleanCssPath].filter(Boolean).join('/');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
} else {
|
|
557
|
+
href = cssPath;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (dontAppendStylesToHead) {
|
|
561
|
+
const key = 'css__${options.name}__' + exposeItemName;
|
|
562
|
+
window[key] = window[key] || [];
|
|
563
|
+
window[key].push(href);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (href in seen) return;
|
|
568
|
+
seen[href] = true;
|
|
569
|
+
|
|
570
|
+
const element = document.createElement('link');
|
|
571
|
+
element.rel = 'stylesheet';
|
|
572
|
+
element.href = href;
|
|
573
|
+
document.head.appendChild(element);
|
|
574
|
+
});
|
|
575
|
+
};
|
|
576
|
+
async function __federation_import(name) {
|
|
577
|
+
currentImports[name] ??= import(name)
|
|
578
|
+
return currentImports[name]
|
|
579
|
+
};
|
|
580
|
+
export const get =(module) => {
|
|
581
|
+
if(!moduleMap[module]) throw new Error('Can not find remote module ' + module)
|
|
582
|
+
return moduleMap[module]();
|
|
583
|
+
};
|
|
584
|
+
export const init =(shareScope) => {
|
|
585
|
+
globalThis.__federation_shared__= globalThis.__federation_shared__|| {};
|
|
586
|
+
Object.entries(shareScope).forEach(([key, value]) => {
|
|
587
|
+
for (const [versionKey, versionValue] of Object.entries(value)) {
|
|
588
|
+
const scope = versionValue.scope || 'default'
|
|
589
|
+
globalThis.__federation_shared__[scope] = globalThis.__federation_shared__[scope] || {};
|
|
590
|
+
const shared= globalThis.__federation_shared__[scope];
|
|
591
|
+
(shared[key] = shared[key]||{})[versionKey] = versionValue;
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
}` },
|
|
595
|
+
configResolved(config) {
|
|
596
|
+
if (config) viteConfigResolved.config = config;
|
|
597
|
+
},
|
|
598
|
+
buildStart() {
|
|
599
|
+
if (parsedOptions.prodExpose.length > 0) this.emitFile({
|
|
600
|
+
fileName: `${builderInfo.assetsDir ? builderInfo.assetsDir + "/" : ""}${options.filename}`,
|
|
601
|
+
type: "chunk",
|
|
602
|
+
id: `__remoteEntryHelper__${options.filename}`,
|
|
603
|
+
preserveSignature: "strict"
|
|
604
|
+
});
|
|
605
|
+
},
|
|
606
|
+
generateBundle(_options, bundle) {
|
|
607
|
+
let remoteEntryChunk;
|
|
608
|
+
for (const file in bundle) {
|
|
609
|
+
const chunk = bundle[file];
|
|
610
|
+
if (chunk?.facadeModuleId === `\0virtual:__remoteEntryHelper__${options.filename}`) {
|
|
611
|
+
remoteEntryChunk = chunk;
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
if (remoteEntryChunk) {
|
|
616
|
+
remoteEntryChunk.code = remoteEntryChunk.code.replace("__VITE_BASE_PLACEHOLDER__", `'${viteConfigResolved.config?.base || ""}'`).replace("__VITE_ASSETS_DIR_PLACEHOLDER__", `'${viteConfigResolved.config?.build?.assetsDir || ""}'`);
|
|
617
|
+
const filepathMap = /* @__PURE__ */ new Map();
|
|
618
|
+
const facadeIndex = /* @__PURE__ */ new Map();
|
|
619
|
+
for (const b of Object.values(bundle)) if ("facadeModuleId" in b && b.facadeModuleId) facadeIndex.set(b.facadeModuleId, b);
|
|
620
|
+
const getFilename = (name) => parse(parse(name).name).name;
|
|
621
|
+
const cssBundlesMap = Object.keys(bundle).filter((name) => extname(name) === ".css").reduce((res, name) => {
|
|
622
|
+
const filename = getFilename(name);
|
|
623
|
+
res.set(filename, bundle[name]);
|
|
624
|
+
return res;
|
|
625
|
+
}, /* @__PURE__ */ new Map());
|
|
626
|
+
remoteEntryChunk.code = remoteEntryChunk.code.replace(new RegExp(`(["'])${DYNAMIC_LOADING_CSS_PREFIX}.*?\\1`, "g"), (str) => {
|
|
627
|
+
if (viteConfigResolved.config && !viteConfigResolved.config.build.cssCodeSplit) if (cssBundlesMap.size) return `[${[...cssBundlesMap.values()].map((cssBundle) => JSON.stringify(basename(cssBundle.fileName))).join(",")}]`;
|
|
628
|
+
else return "[]";
|
|
629
|
+
const filepath = str.slice((`'` + DYNAMIC_LOADING_CSS_PREFIX).length, -1);
|
|
630
|
+
if (!filepath || !filepath.length) return str;
|
|
631
|
+
let fileBundle = filepathMap.get(filepath);
|
|
632
|
+
if (!fileBundle) {
|
|
633
|
+
fileBundle = facadeIndex.get(filepath);
|
|
634
|
+
if (fileBundle) filepathMap.set(filepath, fileBundle);
|
|
635
|
+
else return str;
|
|
636
|
+
}
|
|
637
|
+
const depCssFiles = /* @__PURE__ */ new Set();
|
|
638
|
+
const addDepCss = (bundleName) => {
|
|
639
|
+
const theBundle = bundle[bundleName];
|
|
640
|
+
if (theBundle && theBundle.viteMetadata) for (const cssFileName of theBundle.viteMetadata.importedCss.values()) {
|
|
641
|
+
const cssBundle = cssBundlesMap.get(getFilename(cssFileName));
|
|
642
|
+
if (cssBundle) depCssFiles.add(cssBundle.fileName);
|
|
643
|
+
}
|
|
644
|
+
if (theBundle && theBundle.imports && theBundle.imports.length) theBundle.imports.forEach((name) => addDepCss(name));
|
|
645
|
+
};
|
|
646
|
+
[fileBundle.fileName, ...fileBundle.imports].forEach(addDepCss);
|
|
647
|
+
return `[${[...depCssFiles].map((d) => JSON.stringify(basename(d))).join(",")}]`;
|
|
648
|
+
});
|
|
649
|
+
const nameToKey = /* @__PURE__ */ new Map();
|
|
650
|
+
for (const key of Object.keys(bundle)) {
|
|
651
|
+
const name = bundle[key].name;
|
|
652
|
+
if (name) nameToKey.set(name, key);
|
|
653
|
+
}
|
|
654
|
+
for (const expose of exposeOptions) {
|
|
655
|
+
const exposeKey = EXPOSES_KEY_MAP.get(expose[0]);
|
|
656
|
+
const module = exposeKey ? nameToKey.get(exposeKey) : void 0;
|
|
657
|
+
if (module) {
|
|
658
|
+
const chunk = bundle[module];
|
|
659
|
+
const slashPath = relative(dirname(remoteEntryChunk.fileName), chunk.fileName).replace(/\\/g, "/");
|
|
660
|
+
remoteEntryChunk.code = remoteEntryChunk.code.replace(`\${__federation_expose_${expose[0]}}`, viteConfigResolved.config?.base?.replace(/\/+$/, "") ? [
|
|
661
|
+
viteConfigResolved.config.base.replace(/\/+$/, ""),
|
|
662
|
+
viteConfigResolved.config.build?.assetsDir?.replace(/\/+$/, ""),
|
|
663
|
+
slashPath
|
|
664
|
+
].filter(Boolean).join("/") : `./${slashPath}`);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
let ast = null;
|
|
668
|
+
try {
|
|
669
|
+
ast = this.parse(remoteEntryChunk.code);
|
|
670
|
+
} catch (err) {
|
|
671
|
+
console.error(err);
|
|
672
|
+
}
|
|
673
|
+
if (!ast) return;
|
|
674
|
+
const magicString = new MagicString(remoteEntryChunk.code);
|
|
675
|
+
walk(ast, { enter(node) {
|
|
676
|
+
if (node && node.type === "CallExpression" && typeof node.arguments[0]?.value === "string" && node.arguments[0]?.value.indexOf(`__v__css__`) > -1) magicString.remove(node.start, node.end + 1);
|
|
677
|
+
} });
|
|
678
|
+
remoteEntryChunk.code = magicString.toString();
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
//#endregion
|
|
684
|
+
//#region src/prod/remote-production.ts
|
|
685
|
+
function joinUrlSegments(a, b) {
|
|
686
|
+
if (!a || !b) return a || b || "";
|
|
687
|
+
if (a[a.length - 1] === "/") a = a.substring(0, a.length - 1);
|
|
688
|
+
if (b[0] !== "/") b = "/" + b;
|
|
689
|
+
return a + b;
|
|
690
|
+
}
|
|
691
|
+
function toOutputFilePathWithoutRuntime(filename, type, hostId, hostType, config, toRelative) {
|
|
692
|
+
const { renderBuiltUrl } = config.experimental;
|
|
693
|
+
let relative = config.base === "" || config.base === "./";
|
|
694
|
+
if (renderBuiltUrl) {
|
|
695
|
+
const result = renderBuiltUrl(filename, {
|
|
696
|
+
hostId,
|
|
697
|
+
hostType,
|
|
698
|
+
type,
|
|
699
|
+
ssr: !!config.build.ssr
|
|
700
|
+
});
|
|
701
|
+
if (typeof result === "object") {
|
|
702
|
+
if (result.runtime) throw new Error(`{ runtime: "${result.runtime}" } is not supported for assets in ${hostType} files: ${filename}`);
|
|
703
|
+
if (typeof result.relative === "boolean") relative = result.relative;
|
|
704
|
+
} else if (result) return result;
|
|
705
|
+
}
|
|
706
|
+
if (relative && !config.build.ssr) return toRelative(filename, hostId);
|
|
707
|
+
else return joinUrlSegments(config.base, filename);
|
|
708
|
+
}
|
|
709
|
+
function prodRemotePlugin(options) {
|
|
710
|
+
parsedOptions.prodRemote = parseRemoteOptions(options);
|
|
711
|
+
for (const item of parsedOptions.prodRemote) prodRemotes.push({
|
|
712
|
+
id: item[0],
|
|
713
|
+
regexp: new RegExp(`^${item[0]}/.+?`),
|
|
714
|
+
config: item[1]
|
|
715
|
+
});
|
|
716
|
+
const shareScope = options.shareScope || "default";
|
|
717
|
+
let resolvedConfig;
|
|
718
|
+
return {
|
|
719
|
+
name: "sbee:remote-production",
|
|
720
|
+
virtualFile: options.remotes ? { __federation__: `
|
|
721
|
+
${createRemotesMap(prodRemotes)}
|
|
722
|
+
const currentImports = {}
|
|
723
|
+
const loadJS = async (url, fn) => {
|
|
724
|
+
const resolvedUrl = typeof url === 'function' ? await url() : url;
|
|
725
|
+
const script = document.createElement('script')
|
|
726
|
+
script.type = 'text/javascript';
|
|
727
|
+
script.onload = fn;
|
|
728
|
+
script.src = resolvedUrl;
|
|
729
|
+
document.getElementsByTagName('head')[0].appendChild(script);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
function get(name, ${REMOTE_FROM_PARAMETER}) {
|
|
733
|
+
return __federation_import(name).then(module => () => {
|
|
734
|
+
if (${REMOTE_FROM_PARAMETER} === 'webpack') {
|
|
735
|
+
return Object.prototype.toString.call(module).indexOf('Module') > -1 && module.default ? module.default : module
|
|
736
|
+
}
|
|
737
|
+
return module
|
|
738
|
+
})
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
function merge(obj1, obj2) {
|
|
742
|
+
const mergedObj = Object.assign(obj1, obj2);
|
|
743
|
+
for (const key of Object.keys(mergedObj)) {
|
|
744
|
+
if (typeof mergedObj[key] === 'object' && typeof obj2[key] === 'object') {
|
|
745
|
+
mergedObj[key] = merge(mergedObj[key], obj2[key]);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return mergedObj;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
const wrapShareModule = ${REMOTE_FROM_PARAMETER} => {
|
|
752
|
+
return merge({
|
|
753
|
+
${getModuleMarker("shareScope")}
|
|
754
|
+
}, (globalThis.__federation_shared__ || {})['${shareScope}'] || {});
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
async function __federation_import(name) {
|
|
758
|
+
currentImports[name] ??= import(name)
|
|
759
|
+
return currentImports[name]
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
async function __federation_method_ensure(remoteId) {
|
|
763
|
+
const remote = remotesMap[remoteId];
|
|
764
|
+
if (!remote.inited) {
|
|
765
|
+
if ('var' === remote.format) {
|
|
766
|
+
// loading js with script tag
|
|
767
|
+
return new Promise(resolve => {
|
|
768
|
+
const callback = () => {
|
|
769
|
+
if (!remote.inited) {
|
|
770
|
+
remote.lib = window[remoteId];
|
|
771
|
+
remote.lib.init(wrapShareModule(remote.from))
|
|
772
|
+
remote.inited = true;
|
|
773
|
+
}
|
|
774
|
+
resolve(remote.lib);
|
|
775
|
+
}
|
|
776
|
+
return loadJS(remote.url, callback);
|
|
777
|
+
});
|
|
778
|
+
} else if (['esm', 'systemjs'].includes(remote.format)) {
|
|
779
|
+
// loading js with import(...)
|
|
780
|
+
return new Promise((resolve, reject) => {
|
|
781
|
+
const getUrl = typeof remote.url === 'function' ? remote.url : () => Promise.resolve(remote.url);
|
|
782
|
+
getUrl().then(url => {
|
|
783
|
+
import(/* @vite-ignore */ url).then(lib => {
|
|
784
|
+
if (!remote.inited) {
|
|
785
|
+
const shareScope = wrapShareModule(remote.from);
|
|
786
|
+
remote.lib = lib;
|
|
787
|
+
remote.lib.init(shareScope);
|
|
788
|
+
remote.inited = true;
|
|
789
|
+
}
|
|
790
|
+
resolve(remote.lib);
|
|
791
|
+
}).catch(reject)
|
|
792
|
+
})
|
|
793
|
+
})
|
|
794
|
+
}
|
|
795
|
+
} else {
|
|
796
|
+
return remote.lib;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function __federation_method_unwrapDefault(module) {
|
|
801
|
+
return (module?.__esModule || module?.[Symbol.toStringTag] === 'Module') ? module.default : module
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
function __federation_method_wrapDefault(module, need) {
|
|
805
|
+
if (!module?.default && need) {
|
|
806
|
+
let obj = Object.create(null);
|
|
807
|
+
obj.default = module;
|
|
808
|
+
obj.__esModule = true;
|
|
809
|
+
return obj;
|
|
810
|
+
}
|
|
811
|
+
return module;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
function __federation_method_getRemote(remoteName, componentName) {
|
|
815
|
+
return __federation_method_ensure(remoteName).then((remote) => remote.get(componentName).then(factory => factory()));
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
function __federation_method_setRemote(remoteName, remoteConfig) {
|
|
819
|
+
remotesMap[remoteName] = remoteConfig;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
export {
|
|
823
|
+
__federation_method_ensure,
|
|
824
|
+
__federation_method_getRemote,
|
|
825
|
+
__federation_method_setRemote,
|
|
826
|
+
__federation_method_unwrapDefault,
|
|
827
|
+
__federation_method_wrapDefault
|
|
828
|
+
}
|
|
829
|
+
` } : { __federation__: "" },
|
|
830
|
+
configResolved(config) {
|
|
831
|
+
resolvedConfig = config;
|
|
832
|
+
},
|
|
833
|
+
async transform(code, id) {
|
|
834
|
+
if (builderInfo.isShared) {
|
|
835
|
+
for (const sharedInfo of parsedOptions.prodShared) if (!sharedInfo[1].emitFile) sharedInfo[1].emitFile = this.emitFile({
|
|
836
|
+
type: "chunk",
|
|
837
|
+
id: sharedInfo[1].id ?? sharedInfo[1].packagePath,
|
|
838
|
+
preserveSignature: "strict",
|
|
839
|
+
name: `__federation_shared_${sharedInfo[0]}`
|
|
840
|
+
});
|
|
841
|
+
if (id === "\0virtual:__federation_fn_import") {
|
|
842
|
+
const moduleMapCode = parsedOptions.prodShared.filter((shareInfo) => shareInfo[1].generate).map((sharedInfo) => `'${sharedInfo[0]}':{get:()=>()=>__federation_import(import.meta.ROLLUP_FILE_URL_${sharedInfo[1].emitFile}),import:${sharedInfo[1].import}${sharedInfo[1].requiredVersion ? `,requiredVersion:'${sharedInfo[1].requiredVersion}'` : ""}}`).join(",");
|
|
843
|
+
return code.replace(getModuleMarker("moduleMap", "var"), `{${moduleMapCode}}`);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
if (builderInfo.isRemote) {
|
|
847
|
+
for (const expose of parsedOptions.prodExpose) if (!expose[1].emitFile) expose[1].emitFile = this.emitFile({
|
|
848
|
+
type: "chunk",
|
|
849
|
+
id: expose[1].id ?? expose[1].import,
|
|
850
|
+
name: EXPOSES_KEY_MAP.get(expose[0]),
|
|
851
|
+
preserveSignature: "allow-extension"
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
if (builderInfo.isHost) {
|
|
855
|
+
if (id === "\0virtual:__federation__") {
|
|
856
|
+
const res = [];
|
|
857
|
+
parsedOptions.prodShared.forEach((arr) => {
|
|
858
|
+
const obj = arr[1];
|
|
859
|
+
let str = "";
|
|
860
|
+
if (typeof obj === "object") {
|
|
861
|
+
const fileUrl = `import.meta.ROLLUP_FILE_URL_${obj.emitFile}`;
|
|
862
|
+
str += `get:()=>get(${fileUrl}, ${REMOTE_FROM_PARAMETER}), loaded:1`;
|
|
863
|
+
res.push(`'${arr[0]}':{'${obj.version}':{${str}}}`);
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
return code.replace(getModuleMarker("shareScope"), res.join(","));
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
if (builderInfo.isHost || builderInfo.isShared) {
|
|
870
|
+
let ast = null;
|
|
871
|
+
try {
|
|
872
|
+
ast = this.parse(code);
|
|
873
|
+
} catch (err) {
|
|
874
|
+
console.error(err);
|
|
875
|
+
}
|
|
876
|
+
if (!ast) return null;
|
|
877
|
+
const magicString = new MagicString(code);
|
|
878
|
+
const hasStaticImported = /* @__PURE__ */ new Map();
|
|
879
|
+
let requiresRuntime = false;
|
|
880
|
+
let hasImportShared = false;
|
|
881
|
+
let modify = false;
|
|
882
|
+
let manualRequired = null;
|
|
883
|
+
const sharedNameSet = new Set(parsedOptions.prodShared.map((sharedInfo) => sharedInfo[0]));
|
|
884
|
+
walk(ast, { enter(node) {
|
|
885
|
+
if (node.type === "ImportDeclaration") {
|
|
886
|
+
const moduleName = node.source.value;
|
|
887
|
+
if (sharedNameSet.has(moduleName)) {
|
|
888
|
+
const namedImportDeclaration = [];
|
|
889
|
+
let defaultImportDeclaration = null;
|
|
890
|
+
if (!node.specifiers?.length) {
|
|
891
|
+
magicString.remove(node.start, node.end);
|
|
892
|
+
modify = true;
|
|
893
|
+
} else {
|
|
894
|
+
node.specifiers.forEach((specify) => {
|
|
895
|
+
if (specify.imported?.name) namedImportDeclaration.push(`${specify.imported.name === specify.local.name ? specify.imported.name : `${specify.imported.name}:${specify.local.name}`}`);
|
|
896
|
+
else defaultImportDeclaration = specify.local.name;
|
|
897
|
+
});
|
|
898
|
+
hasImportShared = true;
|
|
899
|
+
if (defaultImportDeclaration && namedImportDeclaration.length) {
|
|
900
|
+
const imports = namedImportDeclaration.join(",");
|
|
901
|
+
const line = `const ${defaultImportDeclaration} = await importShared('${moduleName}');\nconst {${imports}} = ${defaultImportDeclaration};\n`;
|
|
902
|
+
magicString.overwrite(node.start, node.end, line);
|
|
903
|
+
} else if (defaultImportDeclaration) magicString.overwrite(node.start, node.end, `const ${defaultImportDeclaration} = await importShared('${moduleName}');\n`);
|
|
904
|
+
else if (namedImportDeclaration.length) magicString.overwrite(node.start, node.end, `const {${namedImportDeclaration.join(",")}} = await importShared('${moduleName}');\n`);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
if (node.type === "ImportDeclaration" && node.source?.value === "virtual:__federation__") manualRequired = node;
|
|
909
|
+
if ((node.type === "ImportExpression" || node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration") && node.source?.value?.indexOf("/") > -1) {
|
|
910
|
+
const moduleId = node.source.value;
|
|
911
|
+
const remote = prodRemotes.find((r) => r.regexp.test(moduleId));
|
|
912
|
+
const needWrap = remote?.config.from === "vite";
|
|
913
|
+
if (remote) {
|
|
914
|
+
requiresRuntime = true;
|
|
915
|
+
const modName = `.${moduleId.slice(remote.id.length)}`;
|
|
916
|
+
switch (node.type) {
|
|
917
|
+
case "ImportExpression":
|
|
918
|
+
magicString.overwrite(node.start, node.end, `__federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)}).then(module=>__federation_method_wrapDefault(module, ${needWrap}))`);
|
|
919
|
+
break;
|
|
920
|
+
case "ImportDeclaration":
|
|
921
|
+
if (node.specifiers?.length) {
|
|
922
|
+
const afterImportName = `__federation_var_${moduleId.replace(/[@/\\.-]/g, "")}`;
|
|
923
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
924
|
+
hasStaticImported.set(moduleId, afterImportName);
|
|
925
|
+
magicString.overwrite(node.start, node.end, `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)});`);
|
|
926
|
+
}
|
|
927
|
+
let deconstructStr = "";
|
|
928
|
+
node.specifiers.forEach((spec) => {
|
|
929
|
+
if (spec.type === "ImportDefaultSpecifier") magicString.appendRight(node.end, `\n let ${spec.local.name} = __federation_method_unwrapDefault(${afterImportName}) `);
|
|
930
|
+
else if (spec.type === "ImportSpecifier") {
|
|
931
|
+
const importedName = spec.imported.name;
|
|
932
|
+
const localName = spec.local.name;
|
|
933
|
+
deconstructStr += `${importedName === localName ? localName : `${importedName} : ${localName}`},`;
|
|
934
|
+
} else if (spec.type === "ImportNamespaceSpecifier") magicString.appendRight(node.end, `let {${spec.local.name}} = ${afterImportName}`);
|
|
935
|
+
});
|
|
936
|
+
if (deconstructStr.length > 0) magicString.appendRight(node.end, `\n let {${deconstructStr.slice(0, -1)}} = ${afterImportName}`);
|
|
937
|
+
}
|
|
938
|
+
break;
|
|
939
|
+
case "ExportNamedDeclaration": {
|
|
940
|
+
const afterImportName = `__federation_var_${moduleId.replace(/[@/\\.-]/g, "")}`;
|
|
941
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
942
|
+
hasStaticImported.set(moduleId, afterImportName);
|
|
943
|
+
magicString.overwrite(node.start, node.end, `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(remote.id)} , ${JSON.stringify(modName)});`);
|
|
944
|
+
}
|
|
945
|
+
if (node.specifiers.length > 0) {
|
|
946
|
+
const specifiers = node.specifiers;
|
|
947
|
+
let exportContent = "";
|
|
948
|
+
let deconstructContent = "";
|
|
949
|
+
specifiers.forEach((spec) => {
|
|
950
|
+
const localName = spec.local.name;
|
|
951
|
+
const exportName = spec.exported.name;
|
|
952
|
+
const variableName = `${afterImportName}_${localName}`;
|
|
953
|
+
deconstructContent = deconstructContent.concat(`${localName}:${variableName},`);
|
|
954
|
+
exportContent = exportContent.concat(`${variableName} as ${exportName},`);
|
|
955
|
+
});
|
|
956
|
+
magicString.append(`\n const {${deconstructContent.slice(0, deconstructContent.length - 1)}} = ${afterImportName}; \n`);
|
|
957
|
+
magicString.append(`\n export {${exportContent.slice(0, exportContent.length - 1)}}; `);
|
|
958
|
+
}
|
|
959
|
+
break;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
} });
|
|
965
|
+
if (requiresRuntime) {
|
|
966
|
+
let requiresCode = `import {__federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault} from '__federation__';\n\n`;
|
|
967
|
+
if (manualRequired) {
|
|
968
|
+
requiresCode = `import {__federation_method_setRemote, __federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault} from '__federation__';\n\n`;
|
|
969
|
+
magicString.overwrite(manualRequired.start, manualRequired.end, ``);
|
|
970
|
+
}
|
|
971
|
+
magicString.prepend(requiresCode);
|
|
972
|
+
}
|
|
973
|
+
if (hasImportShared) magicString.prepend(`import {importShared} from '\0virtual:__federation_fn_import';\n`);
|
|
974
|
+
if (requiresRuntime || hasImportShared || modify) return {
|
|
975
|
+
code: magicString.toString(),
|
|
976
|
+
map: magicString.generateMap({ hires: true })
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
generateBundle(options, bundle) {
|
|
981
|
+
const preloadSharedReg = parsedOptions.prodShared.filter((shareInfo) => shareInfo[1].modulePreload).map((item) => new RegExp(`__federation_shared_${item[0]}-.{8}\\.js`));
|
|
982
|
+
const getImportedChunks = (rootChunk, satisfy, seen = /* @__PURE__ */ new Set()) => {
|
|
983
|
+
const chunks = [];
|
|
984
|
+
const stack = [rootChunk];
|
|
985
|
+
while (stack.length > 0) {
|
|
986
|
+
const chunk = stack.pop();
|
|
987
|
+
for (const file of chunk.imports) {
|
|
988
|
+
const importee = bundle[file];
|
|
989
|
+
if (importee?.type === "chunk" && !seen.has(file)) {
|
|
990
|
+
if (satisfy(importee)) {
|
|
991
|
+
seen.add(file);
|
|
992
|
+
stack.push(importee);
|
|
993
|
+
chunks.push(importee);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
return chunks;
|
|
999
|
+
};
|
|
1000
|
+
const sharedFiles = [];
|
|
1001
|
+
const entryChunk = {};
|
|
1002
|
+
for (const fileName in bundle) {
|
|
1003
|
+
const file = bundle[fileName];
|
|
1004
|
+
if (file.type === "asset") {
|
|
1005
|
+
if (fileName.endsWith(".html")) entryChunk[fileName] = file;
|
|
1006
|
+
} else if (preloadSharedReg.some((item) => item.test(fileName))) sharedFiles.push(fileName);
|
|
1007
|
+
}
|
|
1008
|
+
if (!sharedFiles.length) return;
|
|
1009
|
+
Object.keys(entryChunk).forEach((fileName) => {
|
|
1010
|
+
let html = entryChunk[fileName].source;
|
|
1011
|
+
const htmlPath = entryChunk[fileName].fileName;
|
|
1012
|
+
const basePath = resolvedConfig.base === "./" || resolvedConfig.base === "" ? path.posix.join(path.posix.relative(entryChunk[fileName].fileName, "").slice(0, -2), "./") : resolvedConfig.base;
|
|
1013
|
+
const toOutputFilePath = (filename) => toOutputFilePathWithoutRuntime(filename, "asset", htmlPath, "html", resolvedConfig, (filename) => basePath + filename);
|
|
1014
|
+
const importFiles = sharedFiles.filter((item) => {
|
|
1015
|
+
return !html.includes(toOutputFilePath(item));
|
|
1016
|
+
}).flatMap((item) => {
|
|
1017
|
+
return [item, ...getImportedChunks(bundle[item], (chunk) => !html.includes(toOutputFilePath(chunk.fileName))).map((item) => item.fileName)].map((item) => toOutputFilePath(item));
|
|
1018
|
+
});
|
|
1019
|
+
html = injectToHead(html, [...new Set(importFiles)].map((item) => toPreloadTag(item)));
|
|
1020
|
+
entryChunk[fileName].source = html;
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
//#endregion
|
|
1026
|
+
//#region src/prod/federation_fn_import.js?raw
|
|
1027
|
+
var federation_fn_import_default = "import { satisfy } from '__federation_fn_satisfy'\n\nconst currentImports = {}\n\n// eslint-disable-next-line no-undef\nconst moduleMap = __rf_var__moduleMap\nconst moduleCache = Object.create(null)\nasync function importShared(name, shareScope = 'default') {\n return moduleCache[name]\n ? new Promise((r) => r(moduleCache[name]))\n : (await getSharedFromRuntime(name, shareScope)) || getSharedFromLocal(name)\n}\n// eslint-disable-next-line\nasync function __federation_import(name) {\n currentImports[name] ??= import(name)\n return currentImports[name]\n}\nasync function getSharedFromRuntime(name, shareScope) {\n let module = null\n if (globalThis?.__federation_shared__?.[shareScope]?.[name]) {\n const versionObj = globalThis.__federation_shared__[shareScope][name]\n const requiredVersion = moduleMap[name]?.requiredVersion\n const hasRequiredVersion = !!requiredVersion\n if (hasRequiredVersion) {\n const versionKey = Object.keys(versionObj).find((version) =>\n satisfy(version, requiredVersion)\n )\n if (versionKey) {\n const versionValue = versionObj[versionKey]\n module = await (await versionValue.get())()\n } else {\n console.log(\n `provider support ${name}(${versionKey}) is not satisfied requiredVersion(\\${moduleMap[name].requiredVersion})`\n )\n }\n } else {\n const versionKey = Object.keys(versionObj)[0]\n const versionValue = versionObj[versionKey]\n module = await (await versionValue.get())()\n }\n }\n if (module) {\n return flattenModule(module, name)\n }\n}\nasync function getSharedFromLocal(name) {\n if (moduleMap[name]?.import) {\n let module = await (await moduleMap[name].get())()\n return flattenModule(module, name)\n } else {\n console.error(\n `consumer config import=false,so cant use callback shared module`\n )\n }\n}\nfunction flattenModule(module, name) {\n // use a shared module which export default a function will getting error 'TypeError: xxx is not a function'\n if (typeof module.default === 'function') {\n Object.keys(module).forEach((key) => {\n if (key !== 'default') {\n module.default[key] = module[key]\n }\n })\n moduleCache[name] = module.default\n return module.default\n }\n if (module.default) module = Object.assign({}, module.default, module)\n moduleCache[name] = module\n return module\n}\nexport {\n importShared,\n getSharedFromRuntime as importSharedRuntime,\n getSharedFromLocal as importSharedLocal\n}\n";
|
|
1028
|
+
//#endregion
|
|
1029
|
+
//#region src/prod/shared-production.ts
|
|
1030
|
+
var sharedFilePathReg = /__federation_shared_(.+)-.{8}\.js$/;
|
|
1031
|
+
function prodSharedPlugin(options) {
|
|
1032
|
+
parsedOptions.prodShared = parseSharedOptions(options);
|
|
1033
|
+
const shareName2Prop = /* @__PURE__ */ new Map();
|
|
1034
|
+
parsedOptions.prodShared.forEach((value) => shareName2Prop.set(removeNonRegLetter(value[0], NAME_CHAR_REG), value[1]));
|
|
1035
|
+
let isHost = false;
|
|
1036
|
+
let isRemote = false;
|
|
1037
|
+
const id2Prop = /* @__PURE__ */ new Map();
|
|
1038
|
+
return {
|
|
1039
|
+
name: "sbee:shared-production",
|
|
1040
|
+
virtualFile: { __federation_fn_import: federation_fn_import_default },
|
|
1041
|
+
options(inputOptions) {
|
|
1042
|
+
isRemote = !!parsedOptions.prodExpose.length;
|
|
1043
|
+
isHost = !!parsedOptions.prodRemote.length && !parsedOptions.prodExpose.length;
|
|
1044
|
+
if (shareName2Prop.size) inputOptions.external = inputOptions.external?.filter((item) => {
|
|
1045
|
+
if (item instanceof RegExp) return ![...shareName2Prop.keys()].some((key) => item.test(key));
|
|
1046
|
+
return !shareName2Prop.has(removeNonRegLetter(item, NAME_CHAR_REG));
|
|
1047
|
+
});
|
|
1048
|
+
return inputOptions;
|
|
1049
|
+
},
|
|
1050
|
+
async buildStart() {
|
|
1051
|
+
if (parsedOptions.prodShared.length && isRemote) this.emitFile({
|
|
1052
|
+
name: "__federation_fn_import",
|
|
1053
|
+
type: "chunk",
|
|
1054
|
+
id: "__federation_fn_import",
|
|
1055
|
+
preserveSignature: "strict"
|
|
1056
|
+
});
|
|
1057
|
+
const collectDirFn = async (filePath, collect) => {
|
|
1058
|
+
try {
|
|
1059
|
+
const files = await this.fs.readdir(filePath);
|
|
1060
|
+
for (const name of files) {
|
|
1061
|
+
const tempPath = join(filePath, name);
|
|
1062
|
+
try {
|
|
1063
|
+
if ((await this.fs.stat(tempPath)).isDirectory()) {
|
|
1064
|
+
collect.push(tempPath);
|
|
1065
|
+
await collectDirFn(tempPath, collect);
|
|
1066
|
+
}
|
|
1067
|
+
} catch {}
|
|
1068
|
+
}
|
|
1069
|
+
} catch {}
|
|
1070
|
+
};
|
|
1071
|
+
const monoRepos = [];
|
|
1072
|
+
const currentDir = resolve();
|
|
1073
|
+
for (const arr of parsedOptions.prodShared) if (isHost && !arr[1].version && !arr[1].manuallyPackagePathSetting) {
|
|
1074
|
+
const packageJsonPath = (await this.resolve(`${arr[1].packagePath}/package.json`))?.id;
|
|
1075
|
+
if (packageJsonPath) {
|
|
1076
|
+
const packageJson = JSON.parse(await this.fs.readFile(packageJsonPath, { encoding: "utf8" }));
|
|
1077
|
+
arr[1].version = packageJson.version;
|
|
1078
|
+
} else {
|
|
1079
|
+
arr[1].removed = true;
|
|
1080
|
+
const dirPaths = [];
|
|
1081
|
+
const dir = join(currentDir, "node_modules", arr[0]);
|
|
1082
|
+
if ((await this.fs.stat(dir)).isDirectory()) await collectDirFn(dir, dirPaths);
|
|
1083
|
+
else this.error(`cant resolve "${arr[1].packagePath}"`);
|
|
1084
|
+
if (dirPaths.length > 0) monoRepos.push({
|
|
1085
|
+
arr: dirPaths,
|
|
1086
|
+
root: arr
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
if (!arr[1].removed && !arr[1].version) this.error(`No description file or no version in description file (usually package.json) of ${arr[0]}. Add version to description file, or manually specify version in shared config.`);
|
|
1090
|
+
}
|
|
1091
|
+
parsedOptions.prodShared = parsedOptions.prodShared.filter((item) => !item[1].removed);
|
|
1092
|
+
if (monoRepos.length > 0) for (const monoRepo of monoRepos) for (const id of monoRepo.arr) try {
|
|
1093
|
+
const idResolve = await this.resolve(id);
|
|
1094
|
+
if (idResolve?.id) parsedOptions.prodShared.push([`${monoRepo.root[0]}/${basename(id)}`, {
|
|
1095
|
+
id: idResolve?.id,
|
|
1096
|
+
import: monoRepo.root[1].import,
|
|
1097
|
+
shareScope: monoRepo.root[1].shareScope,
|
|
1098
|
+
root: monoRepo.root
|
|
1099
|
+
}]);
|
|
1100
|
+
} catch (e) {}
|
|
1101
|
+
if (parsedOptions.prodShared.length && isRemote) for (const prod of parsedOptions.prodShared) id2Prop.set(prod[1].id, prod[1]);
|
|
1102
|
+
},
|
|
1103
|
+
outputOptions: function(outputOption) {
|
|
1104
|
+
outputOption.hoistTransitiveImports = false;
|
|
1105
|
+
const depToChunk = /* @__PURE__ */ new Map();
|
|
1106
|
+
for (const arr of parsedOptions.prodShared) {
|
|
1107
|
+
const deps = arr[1].dependencies;
|
|
1108
|
+
if (deps) for (const depId of deps) depToChunk.set(depId, arr[0]);
|
|
1109
|
+
}
|
|
1110
|
+
const manualChunkFunc = (id) => {
|
|
1111
|
+
return depToChunk.get(id);
|
|
1112
|
+
};
|
|
1113
|
+
if (typeof outputOption.manualChunks === "function") {
|
|
1114
|
+
const originalManualChunks = outputOption.manualChunks;
|
|
1115
|
+
outputOption.manualChunks = (id, getModuleInfo) => {
|
|
1116
|
+
const result = manualChunkFunc(id);
|
|
1117
|
+
return result ? result : originalManualChunks(id, getModuleInfo);
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
if (outputOption.manualChunks === void 0) outputOption.manualChunks = manualChunkFunc;
|
|
1121
|
+
return outputOption;
|
|
1122
|
+
},
|
|
1123
|
+
generateBundle(options, bundle) {
|
|
1124
|
+
if (!isRemote) return;
|
|
1125
|
+
const needRemoveShared = /* @__PURE__ */ new Set();
|
|
1126
|
+
for (const key in bundle) {
|
|
1127
|
+
const chunk = bundle[key];
|
|
1128
|
+
if (chunk.type === "chunk") {
|
|
1129
|
+
if (!isHost) {
|
|
1130
|
+
const regRst = sharedFilePathReg.exec(chunk.fileName);
|
|
1131
|
+
if (regRst && shareName2Prop.get(removeNonRegLetter(regRst[1], NAME_CHAR_REG))?.generate === false) needRemoveShared.add(key);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
if (needRemoveShared.size !== 0) for (const key of needRemoveShared) delete bundle[key];
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
//#endregion
|
|
1140
|
+
//#region src/index.ts
|
|
1141
|
+
function resolveHook(hook) {
|
|
1142
|
+
if (!hook) return void 0;
|
|
1143
|
+
if (typeof hook === "function") return hook;
|
|
1144
|
+
return hook.handler;
|
|
1145
|
+
}
|
|
1146
|
+
function federation(options) {
|
|
1147
|
+
options.filename = options.filename ? options.filename : DEFAULT_ENTRY_FILENAME;
|
|
1148
|
+
let pluginList = [];
|
|
1149
|
+
let virtualFiles = {};
|
|
1150
|
+
let registerCount = 0;
|
|
1151
|
+
let _mode;
|
|
1152
|
+
function registerPlugins(mode, command) {
|
|
1153
|
+
if (mode === "production" || command === "build") pluginList = [
|
|
1154
|
+
prodSharedPlugin(options),
|
|
1155
|
+
prodExposePlugin(options),
|
|
1156
|
+
prodRemotePlugin(options)
|
|
1157
|
+
];
|
|
1158
|
+
else if (mode === "development" || command === "serve") pluginList = [
|
|
1159
|
+
devSharedPlugin(options),
|
|
1160
|
+
devExposePlugin(options),
|
|
1161
|
+
devRemotePlugin(options)
|
|
1162
|
+
];
|
|
1163
|
+
else pluginList = [];
|
|
1164
|
+
builderInfo.isHost = !!(parsedOptions.prodRemote.length || parsedOptions.devRemote.length);
|
|
1165
|
+
builderInfo.isRemote = !!(parsedOptions.prodExpose.length || parsedOptions.devExpose.length);
|
|
1166
|
+
builderInfo.isShared = !!(parsedOptions.prodShared.length || parsedOptions.devShared.length);
|
|
1167
|
+
virtualFiles = {};
|
|
1168
|
+
pluginList.forEach((plugin) => {
|
|
1169
|
+
if (plugin.virtualFile) Object.assign(virtualFiles, plugin.virtualFile);
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
return {
|
|
1173
|
+
name: "sbee:federation",
|
|
1174
|
+
enforce: "post",
|
|
1175
|
+
options(_options) {
|
|
1176
|
+
if (!registerCount++) {
|
|
1177
|
+
_mode = options.mode ?? "production";
|
|
1178
|
+
registerPlugins(_mode, "");
|
|
1179
|
+
}
|
|
1180
|
+
if (typeof _options.input === "string") _options.input = { index: _options.input };
|
|
1181
|
+
_options.external = _options.external || [];
|
|
1182
|
+
if (!Array.isArray(_options.external)) _options.external = [_options.external];
|
|
1183
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.options)?.call(this, _options);
|
|
1184
|
+
return _options;
|
|
1185
|
+
},
|
|
1186
|
+
config(config, env) {
|
|
1187
|
+
_mode = _mode ?? env.mode;
|
|
1188
|
+
registerPlugins(_mode, env.command);
|
|
1189
|
+
registerCount++;
|
|
1190
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.config)?.call(this, config, env);
|
|
1191
|
+
builderInfo.builder = "vite";
|
|
1192
|
+
builderInfo.assetsDir = config?.build?.assetsDir ?? "assets";
|
|
1193
|
+
},
|
|
1194
|
+
configureServer(server) {
|
|
1195
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.configureServer)?.call(this, server);
|
|
1196
|
+
},
|
|
1197
|
+
configResolved(config) {
|
|
1198
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.configResolved)?.call(this, config);
|
|
1199
|
+
},
|
|
1200
|
+
buildStart(inputOptions) {
|
|
1201
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.buildStart)?.call(this, inputOptions);
|
|
1202
|
+
},
|
|
1203
|
+
async resolveId(...args) {
|
|
1204
|
+
const id = args[0];
|
|
1205
|
+
const importer = args[1];
|
|
1206
|
+
if (id in virtualFiles) return "\0virtual:" + id;
|
|
1207
|
+
if (id.startsWith("\0virtual:")) return id;
|
|
1208
|
+
if (importer && importer.startsWith("\0virtual:")) {
|
|
1209
|
+
const resolved = id;
|
|
1210
|
+
if (resolved in virtualFiles) return "\0virtual:" + resolved;
|
|
1211
|
+
}
|
|
1212
|
+
if (args[0] === "\0virtual:__federation_fn_import") return {
|
|
1213
|
+
id: "\0virtual:__federation_fn_import",
|
|
1214
|
+
moduleSideEffects: true
|
|
1215
|
+
};
|
|
1216
|
+
if (args[0] === "__federation_fn_satisfy") {
|
|
1217
|
+
const federationId = (await this.resolve("@sbee/vite-federation"))?.id;
|
|
1218
|
+
return await this.resolve(`${dirname(federationId)}/satisfy.mjs`);
|
|
1219
|
+
}
|
|
1220
|
+
if (args[0] === "virtual:__federation__") return {
|
|
1221
|
+
id: "\0virtual:__federation__",
|
|
1222
|
+
moduleSideEffects: true
|
|
1223
|
+
};
|
|
1224
|
+
return null;
|
|
1225
|
+
},
|
|
1226
|
+
load(...args) {
|
|
1227
|
+
const id = args[0];
|
|
1228
|
+
if (id.startsWith("\0virtual:")) {
|
|
1229
|
+
const key = id.slice(9);
|
|
1230
|
+
if (key in virtualFiles) return virtualFiles[key];
|
|
1231
|
+
}
|
|
1232
|
+
return null;
|
|
1233
|
+
},
|
|
1234
|
+
transform(code, id) {
|
|
1235
|
+
for (const pluginHook of pluginList) {
|
|
1236
|
+
const result = resolveHook(pluginHook.transform)?.call(this, code, id);
|
|
1237
|
+
if (result) return result;
|
|
1238
|
+
}
|
|
1239
|
+
return code;
|
|
1240
|
+
},
|
|
1241
|
+
moduleParsed(moduleInfo) {
|
|
1242
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.moduleParsed)?.call(this, moduleInfo);
|
|
1243
|
+
},
|
|
1244
|
+
outputOptions(outputOptions) {
|
|
1245
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.outputOptions)?.call(this, outputOptions);
|
|
1246
|
+
return outputOptions;
|
|
1247
|
+
},
|
|
1248
|
+
renderChunk(code, chunkInfo, _options) {
|
|
1249
|
+
for (const pluginHook of pluginList) {
|
|
1250
|
+
const result = resolveHook(pluginHook.renderChunk)?.call(this, code, chunkInfo, _options);
|
|
1251
|
+
if (result) return result;
|
|
1252
|
+
}
|
|
1253
|
+
return null;
|
|
1254
|
+
},
|
|
1255
|
+
generateBundle: function(_options, bundle, isWrite) {
|
|
1256
|
+
for (const pluginHook of pluginList) resolveHook(pluginHook.generateBundle)?.call(this, _options, bundle, isWrite);
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
//#endregion
|
|
1261
|
+
export { federation as default };
|