"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const federation = require("@originjs/vite-plugin-federation"); const path = require("path"); const fs = require("fs-extra"); const MagicString = require("magic-string"); const os = require("os"); const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e }; const federation__default = /* @__PURE__ */ _interopDefaultLegacy(federation); const path__default = /* @__PURE__ */ _interopDefaultLegacy(path); const fs__default = /* @__PURE__ */ _interopDefaultLegacy(fs); const MagicString__default = /* @__PURE__ */ _interopDefaultLegacy(MagicString); const os__default = /* @__PURE__ */ _interopDefaultLegacy(os); const federationFnImportFunc = (moduleMapStr) => ` import { importSharedMicro } from 'vite-micro/client' export async function importShared(name, shareScope = 'default') { if (!window._federation_shared_moduleMap) { window._federation_shared_moduleMap = ${moduleMapStr} } return importSharedMicro(name, window._federation_shared_moduleMap, shareScope) } `; class WalkerBase { constructor() { this.should_skip = false; this.should_remove = false; this.replacement = null; this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (node) => this.replacement = node }; } replace(parent, prop, index, node) { if (parent && prop) { if (index != null) { parent[prop][index] = node; } else { parent[prop] = node; } } } remove(parent, prop, index) { if (parent && prop) { if (index !== null && index !== void 0) { parent[prop].splice(index, 1); } else { delete parent[prop]; } } } } class SyncWalker extends WalkerBase { constructor(enter, leave) { super(); this.should_skip = false; this.should_remove = false; this.replacement = null; this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (node) => this.replacement = node }; this.enter = enter; this.leave = leave; } visit(node, parent, prop, index) { if (node) { if (this.enter) { const _should_skip = this.should_skip; const _should_remove = this.should_remove; const _replacement = this.replacement; this.should_skip = false; this.should_remove = false; this.replacement = null; this.enter.call(this.context, node, parent, prop, index); if (this.replacement) { node = this.replacement; this.replace(parent, prop, index, node); } if (this.should_remove) { this.remove(parent, prop, index); } const skipped = this.should_skip; const removed = this.should_remove; this.should_skip = _should_skip; this.should_remove = _should_remove; this.replacement = _replacement; if (skipped) return node; if (removed) return null; } let key; for (key in node) { const value = node[key]; if (value && typeof value === "object") { if (Array.isArray(value)) { const nodes = value; for (let i = 0; i < nodes.length; i += 1) { const item = nodes[i]; if (isNode(item)) { if (!this.visit(item, node, key, i)) { i--; } } } } else if (isNode(value)) { this.visit(value, node, key, null); } } } if (this.leave) { const _replacement = this.replacement; const _should_remove = this.should_remove; this.replacement = null; this.should_remove = false; this.leave.call(this.context, node, parent, prop, index); if (this.replacement) { node = this.replacement; this.replace(parent, prop, index, node); } if (this.should_remove) { this.remove(parent, prop, index); } const removed = this.should_remove; this.replacement = _replacement; this.should_remove = _should_remove; if (removed) return null; } } return node; } } function isNode(value) { return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string"; } function walk(ast, { enter, leave }) { const instance = new SyncWalker(enter, leave); return instance.visit(ast, null); } function transform(self, code, id, config) { let ast = null; const shared = config.shared || []; try { ast = self.parse(code); } catch (err) { console.error(err); } if (!ast) { return null; } const magicString = new MagicString__default.default(code); let hasImportShared = false; let modify = false; walk(ast, { enter(node) { var _a; if (node.type === "ImportDeclaration") { const moduleName = node.source.value; if (shared.some((sharedInfo) => sharedInfo === moduleName)) { const namedImportDeclaration = []; let defaultImportDeclaration = null; if (!((_a = node.specifiers) == null ? void 0 : _a.length)) { magicString.remove(node.start, node.end); modify = true; } else { node.specifiers.forEach((specify) => { var _a2; if ((_a2 = specify.imported) == null ? void 0 : _a2.name) { namedImportDeclaration.push( `${specify.imported.name === specify.local.name ? specify.imported.name : `${specify.imported.name}:${specify.local.name}`}` ); } else { defaultImportDeclaration = specify.local.name; } }); hasImportShared = true; if (defaultImportDeclaration && namedImportDeclaration.length) { const imports = namedImportDeclaration.join(","); const line = `const ${defaultImportDeclaration} = await importShared('${moduleName}'); const {${imports}} = ${defaultImportDeclaration}; `; magicString.overwrite(node.start, node.end, line); } else if (defaultImportDeclaration) { magicString.overwrite(node.start, node.end, `const ${defaultImportDeclaration} = await importShared('${moduleName}'); `); } else if (namedImportDeclaration.length) { magicString.overwrite( node.start, node.end, `const {${namedImportDeclaration.join(",")}} = await importShared('${moduleName}'); ` ); } } } } } }); if (hasImportShared) { magicString.prepend(`import {importShared} from 'virtual:__federation_fn_import'; `); } if (hasImportShared || modify) { return { code: magicString.toString(), map: magicString.generateMap({ hires: true }) }; } } function parseSharedToShareMap(sharedOption) { let modulesMap = ` { `; sharedOption.forEach((shared) => { if (typeof shared === "string") { modulesMap += `${shared}: { get: () => import('${shared}'), },`; } else { modulesMap += `${shared.name}: { get: () => import('${shared.name}'), requiredVersion: ${shared.requiredVersion} },`; } }); modulesMap += "}"; return modulesMap; } function getIPAdress() { const interfaces = os__default.default.networkInterfaces(); for (const devName in interfaces) { const iface = interfaces[devName]; for (let i = 0; i < iface.length; i++) { const alias = iface[i]; if (alias.family === "IPv4" && alias.address !== "127.0.0.1" && !alias.internal) { return alias.address; } } } } const host = `http://${getIPAdress() || "localhost"}:8080`; const virtualModuleId = "__remoteEntryHelper__"; const resolvedVirtualModuleId = "\0" + virtualModuleId; const shareVirsualModuleId = "virtual:__federation_fn_import"; const resolveShareVirsualModuleId = "\0" + shareVirsualModuleId; const federationDefaultOption = { isRootService: true, filename: "remoteEntry.js", shared: [] }; function normalizePath(id) { return path__default.default.posix.normalize(id.replace(/\\/g, "/")); } function getRemoteEntryFile(options, viteConfig) { if (!options.exposes) return ""; if (!viteConfig.root) return ""; let moduleMap = ""; const exposes = options.exposes || {}; Object.keys(options.exposes).forEach((item) => { const exposeFilepath = normalizePath(path__default.default.resolve(viteConfig.root || "", exposes[item])); moduleMap += ` "${item}":()=> import('${exposeFilepath}').then(module => () => module),`; }); return ` const exportSet = new Set(['Module', '__esModule', 'default', '_export_sfc']); let moduleMap = {${moduleMap}} const seen = {} export const get =(module) => { return moduleMap[module](); }; export const init =(shareScope) => { globalThis.__federation_shared__= globalThis.__federation_shared__|| {}; Object.entries(shareScope).forEach(([key, value]) => { const versionKey = Object.keys(value)[0]; const versionValue = Object.values(value)[0]; const scope = versionValue.scope || 'default' globalThis.__federation_shared__[scope] = globalThis.__federation_shared__[scope] || {}; const shared= globalThis.__federation_shared__[scope]; (shared[key] = shared[key]||{})[versionKey] = versionValue; }); }`; } function generateCommonRemoteEntryFile(version) { return ` export * from './${version}/remoteEntry.js' `; } function getDevRemoteFileUrl(options, remoteName, base) { const devUrl = options.remotes[remoteName].devUrl; const remoteUrl = devUrl ? `${devUrl}/@id/__remoteEntryHelper__` : `${host}/${base}/@id/__remoteEntryHelper__`; return remoteUrl; } function parseRemotes(options) { const remotes = options.remotes || {}; Object.keys(remotes).forEach((remoteName) => { let base = remoteName.split("Remote")[0]; if (options.mode === "development") { remotes[remoteName].external = getDevRemoteFileUrl(options, remoteName, base); } else { remotes[remoteName].url = remotes[remoteName].url || `/assets/${base}`; remotes[remoteName].external = remotes[remoteName].url + `/remoteEntrys.js?version=v${Date.now()}`; } remotes[remoteName].from = "vite"; remotes[remoteName].format = "esm"; }); return remotes; } function parseExposes(options) { options.exposes = options.exposes || {}; let exposes = {}; Object.keys(options.exposes).forEach((exposesName) => { exposes["./" + exposesName] = options.exposes[exposesName]; }); return exposes; } function federationMicro(options) { let viteConfig = {}; options = Object.assign(federationDefaultOption, options); if (options.remotes) { options.remotes = parseRemotes(options); } if (options.exposes) { options.exposes = parseExposes(options); } const federationPlugin = federation__default.default(options); const federationConfigFunc = federationPlugin.config; federationPlugin.config = function config(config, env) { viteConfig = config; federationConfigFunc.call(this, config, env); }; if (options.mode !== "development") { federationPlugin.closeBundle = function(value) { var _a, _b; if (options.exposes) { if (!((_a = viteConfig == null ? void 0 : viteConfig.build) == null ? void 0 : _a.assetsDir)) throw new Error("\u9700\u8981\u914D\u7F6Ebuild/assetsDir"); if (!((_b = viteConfig == null ? void 0 : viteConfig.build) == null ? void 0 : _b.outDir)) throw new Error("\u9700\u8981\u914D\u7F6Ebuild/outDir"); const dirArrs = viteConfig.build.assetsDir.split("/"); const version = dirArrs[dirArrs.length - 1]; const commonRemotePath = path__default.default.resolve(viteConfig.build.outDir + "/" + viteConfig.build.assetsDir, "../remoteEntrys.js"); fs__default.default.ensureDir(path__default.default.resolve(viteConfig.build.outDir + "/" + viteConfig.build.assetsDir), () => { fs__default.default.writeFileSync(commonRemotePath, generateCommonRemoteEntryFile(version)); }); } }; } if (options.mode === "development") { const resolveIdFunc = federationPlugin.resolveId; federationPlugin.resolveId = (...args) => { if (args[0] === virtualModuleId) { return resolvedVirtualModuleId; } if (args[0] === shareVirsualModuleId) { return resolveShareVirsualModuleId; } return resolveIdFunc(...args); }; const sharedMap = parseSharedToShareMap(options.shared || []); const federationFnImport = federationFnImportFunc(sharedMap); const loadFunc = federationPlugin.load; federationPlugin.load = (...args) => { if (args[0] === resolvedVirtualModuleId) return getRemoteEntryFile(options, viteConfig); if (args[0] === resolveShareVirsualModuleId) return federationFnImport; return loadFunc(args[0]); }; const transformFunc = federationPlugin.transform; federationPlugin.transform = function(code, id) { const result = transform(this, code, id, options); if (result) { if (transformFunc) return transformFunc.call(this, result.code, id); return result; } if (transformFunc) return transformFunc.call(this, code, id); return code; }; } return federationPlugin; } exports.federation = federationMicro;