@module-federation/vite
Version: 
Vite plugin for Module Federation
1,251 lines (1,230 loc) • 62.7 kB
JavaScript
var defu = require('defu');
var fs = require('fs');
var path = require('pathe');
var pluginutils = require('@rollup/pluginutils');
var estreeWalker = require('estree-walker');
var MagicString = require('magic-string');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n["default"] = e;
  return n;
}
var defu__default = /*#__PURE__*/_interopDefaultLegacy(defu);
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
var path__namespace = /*#__PURE__*/_interopNamespace(path);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
function getFirstHtmlEntryFile(entryFiles) {
  return entryFiles.find(function (file) {
    return file.endsWith('.html');
  });
}
var addEntry = function addEntry(_ref) {
  var entryName = _ref.entryName,
    entryPath = _ref.entryPath,
    fileName = _ref.fileName,
    _ref$inject = _ref.inject,
    inject = _ref$inject === void 0 ? 'entry' : _ref$inject;
  var devEntryPath = entryPath.startsWith('virtual:mf') ? '@id/' + entryPath : entryPath;
  var entryFiles = [];
  var htmlFilePath;
  var _command;
  var emitFileId;
  var viteConfig;
  function injectHtml() {
    return inject === 'html' && htmlFilePath;
  }
  function injectEntry() {
    return inject === 'entry' || !htmlFilePath;
  }
  return [{
    name: 'add-entry',
    apply: 'serve',
    config: function config(_config, _ref2) {
      var command = _ref2.command;
      _command = command;
    },
    configResolved: function configResolved(config) {
      viteConfig = config;
      devEntryPath = config.base + devEntryPath.replace(/\\\\?/g, '/').replace(/.+?\:([/\\])[/\\]?/, '$1').replace(/^\//, '');
    },
    configureServer: function configureServer(server) {
      server.middlewares.use(function (req, res, next) {
        if (!fileName) {
          next();
          return;
        }
        if (req.url && req.url.startsWith((viteConfig.base + fileName).replace(/^\/?/, '/'))) {
          req.url = devEntryPath;
        }
        next();
      });
    },
    transformIndexHtml: function transformIndexHtml(c) {
      if (!injectHtml()) return;
      return c.replace('<head>', "<head><script type=\"module\" src=" + JSON.stringify(devEntryPath.replace(/.+?\:([/\\])[/\\]?/, '$1').replace(/\\\\?/g, '/')) + "></script>");
    },
    transform: function transform(code, id) {
      if (id.includes('node_modules') || inject !== 'html' || htmlFilePath) {
        return;
      }
      if (id.includes('.svelte-kit') && id.includes('internal.js')) {
        var src = devEntryPath.replace(/.+?\:([/\\])[/\\]?/, '$1').replace(/\\\\?/g, '/');
        return code.replace(/<head>/g, '<head><script type=\\"module\\" src=\\"' + src + '\\"></script>');
      }
    }
  }, {
    name: 'add-entry',
    enforce: 'post',
    configResolved: function configResolved(config) {
      viteConfig = config;
      var inputOptions = config.build.rollupOptions.input;
      if (!inputOptions) {
        htmlFilePath = path__namespace.resolve(config.root, 'index.html');
      } else if (typeof inputOptions === 'string') {
        entryFiles = [inputOptions];
      } else if (Array.isArray(inputOptions)) {
        entryFiles = inputOptions;
      } else if (typeof inputOptions === 'object') {
        entryFiles = Object.values(inputOptions);
      }
      if (entryFiles && entryFiles.length > 0) {
        htmlFilePath = getFirstHtmlEntryFile(entryFiles);
      }
    },
    buildStart: function buildStart() {
      if (_command === 'serve') return;
      var hasHash = fileName == null || fileName.includes == null ? void 0 : fileName.includes('[hash');
      var emitFileOptions = {
        name: entryName,
        type: 'chunk',
        id: entryPath,
        preserveSignature: 'strict'
      };
      if (!hasHash) {
        emitFileOptions.fileName = fileName;
      }
      emitFileId = this.emitFile(emitFileOptions);
      if (htmlFilePath && fs__namespace.existsSync(htmlFilePath)) {
        var htmlContent = fs__namespace.readFileSync(htmlFilePath, 'utf-8');
        var scriptRegex = /<script\s+[^>]*src=["']([^"']+)["'][^>]*>/gi;
        var match;
        while ((match = scriptRegex.exec(htmlContent)) !== null) {
          entryFiles.push(match[1]);
        }
      }
    },
    generateBundle: function generateBundle(options, bundle) {
      if (!injectHtml()) return;
      var file = this.getFileName(emitFileId);
      var scriptContent = "\n          <script type=\"module\" src=\"" + (viteConfig.base + file) + "\"></script>\n        ";
      for (var _fileName in bundle) {
        if (_fileName.endsWith('.html')) {
          var htmlAsset = bundle[_fileName];
          if (htmlAsset.type === 'chunk') return;
          var htmlContent = htmlAsset.source.toString() || '';
          htmlContent = htmlContent.replace('<head>', "<head>" + scriptContent);
          htmlAsset.source = htmlContent;
        }
      }
    },
    transform: function transform(code, id) {
      if (injectEntry() && entryFiles.some(function (file) {
        return id.endsWith(file);
      })) {
        var injection = "\n          import " + JSON.stringify(entryPath) + ";\n          ";
        return injection + code;
      }
    }
  }];
};
/**
 * Solve the problem that dev mode dependency prebunding does not support top-level await syntax
 */
function PluginDevProxyModuleTopLevelAwait() {
  var filterFunction = pluginutils.createFilter();
  var processedFlag = '/* already-processed-by-dev-proxy-module-top-level-await */';
  return {
    name: 'dev-proxy-module-top-level-await',
    apply: 'serve',
    transform: function transform(code, id) {
      if (code.includes(processedFlag)) {
        return null;
      }
      if (!code.includes('/*mf top-level-await placeholder replacement mf*/')) {
        return null;
      }
      if (!filterFunction(id)) return null;
      var ast;
      try {
        ast = this.parse(code, {
          allowReturnOutsideFunction: true
        });
      } catch (e) {
        throw new Error(id + ": " + e);
      }
      var magicString = new MagicString__default["default"](code);
      estreeWalker.walk(ast, {
        enter: function enter(node) {
          if (node.type === 'ExportNamedDeclaration' && node.specifiers) {
            var exportSpecifiers = node.specifiers.map(function (specifier) {
              return specifier.exported.name;
            });
            var proxyStatements = exportSpecifiers.map(function (name) {
              return "\n              const __mfproxy__await" + name + " = await " + name + "();\n              const __mfproxy__" + name + " = () => __mfproxy__await" + name + ";\n            ";
            }).join('\n');
            var exportStatements = exportSpecifiers.map(function (name) {
              return "__mfproxy__" + name + " as " + name;
            }).join(', ');
            var start = node.start;
            var end = node.end;
            var replacement = proxyStatements + "\nexport { " + exportStatements + " };";
            magicString.overwrite(start, end, replacement);
          }
          if (node.type === 'ExportDefaultDeclaration') {
            var declaration = node.declaration;
            var _start = node.start;
            var _end = node.end;
            var proxyStatement;
            var exportStatement = 'default';
            if (declaration.type === 'Identifier') {
              // example: export default foo;
              proxyStatement = "\n                const __mfproxy__awaitdefault = await " + declaration.name + "();\n                const __mfproxy__default = __mfproxy__awaitdefault;\n              ";
            } else if (declaration.type === 'CallExpression' || declaration.type === 'FunctionDeclaration') {
              // example: export default someFunction();
              var declarationCode = code.slice(declaration.start, declaration.end);
              proxyStatement = "\n                const __mfproxy__awaitdefault = await (" + declarationCode + ");\n                const __mfproxy__default = __mfproxy__awaitdefault;\n              ";
            } else {
              // other
              proxyStatement = "\n                const __mfproxy__awaitdefault = await (" + code.slice(declaration.start, declaration.end) + ");\n                const __mfproxy__default = __mfproxy__awaitdefault;\n              ";
            }
            var _replacement = proxyStatement + "\nexport { __mfproxy__default as " + exportStatement + " };";
            magicString.overwrite(_start, _end, _replacement);
          }
        }
      });
      var transformedCode = magicString.toString();
      return {
        code: processedFlag + "\n" + transformedCode,
        map: magicString.generateMap({
          hires: true
        })
      };
    }
  };
}
function _arrayLikeToArray(r, a) {
  (null == a || a > r.length) && (a = r.length);
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
  return n;
}
function _createForOfIteratorHelperLoose(r, e) {
  var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
  if (t) return (t = t.call(r)).next.bind(t);
  if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
    t && (r = t);
    var o = 0;
    return function () {
      return o >= r.length ? {
        done: !0
      } : {
        done: !1,
        value: r[o++]
      };
    };
  }
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _extends() {
  return _extends = Object.assign ? Object.assign.bind() : function (n) {
    for (var e = 1; e < arguments.length; e++) {
      var t = arguments[e];
      for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
    }
    return n;
  }, _extends.apply(null, arguments);
}
function _unsupportedIterableToArray(r, a) {
  if (r) {
    if ("string" == typeof r) return _arrayLikeToArray(r, a);
    var t = {}.toString.call(r).slice(8, -1);
    return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
  }
}
var warn = function warn(message) {
  return message.split('\n').forEach(function (msg) {
    return console.warn('\x1b[33m%s\x1b[0m', msg);
  });
};
function normalizeExposesItem(key, item) {
  var importPath = '';
  if (typeof item === 'string') {
    importPath = item;
  }
  if (typeof item === 'object') {
    importPath = item["import"];
  }
  return {
    "import": importPath
  };
}
function normalizeExposes(exposes) {
  if (!exposes) return {};
  var res = {};
  Object.keys(exposes).forEach(function (key) {
    res[key] = normalizeExposesItem(key, exposes[key]);
  });
  return res;
}
function normalizeRemotes(remotes) {
  if (!remotes) return {};
  var result = {};
  if (typeof remotes === 'object') {
    Object.keys(remotes).forEach(function (key) {
      result[key] = normalizeRemoteItem(key, remotes[key]);
    });
  }
  return result;
}
function normalizeRemoteItem(key, remote) {
  if (typeof remote === 'string') {
    var _remote$split = remote.split('@'),
      entryGlobalName = _remote$split[0];
    var entry = remote.replace(entryGlobalName + '@', '');
    return {
      type: 'var',
      name: key,
      entry: entry,
      entryGlobalName: entryGlobalName,
      shareScope: 'default'
    };
  }
  return Object.assign({
    type: 'var',
    name: key,
    shareScope: 'default',
    entryGlobalName: key
  }, remote);
}
function removePathFromNpmPackage(packageString) {
  // 匹配npm包名的正则表达式,忽略路径部分
  var regex = /^(?:@[^/]+\/)?[^/]+/;
  // 使用正则表达式匹配并提取包名
  var match = packageString.match(regex);
  // 返回匹配到的包名,如果没有匹配到则返回原字符串
  return match ? match[0] : packageString;
}
/**
 * Tries to find the package.json's version of a shared package
 * if `package.json` is not declared in `exports`
 * @param {string} sharedName
 * @returns {string | undefined}
 */
function searchPackageVersion(sharedName) {
  try {
    var sharedPath = require.resolve(sharedName);
    var potentialPackageJsonDir = path__namespace.dirname(sharedPath);
    var rootDir = path__namespace.parse(potentialPackageJsonDir).root;
    while (path__namespace.parse(potentialPackageJsonDir).base !== 'node_modules' && potentialPackageJsonDir !== rootDir) {
      var potentialPackageJsonPath = path__namespace.join(potentialPackageJsonDir, 'package.json');
      if (fs__namespace.existsSync(potentialPackageJsonPath)) {
        var potentialPackageJson = require(potentialPackageJsonPath);
        if (typeof potentialPackageJson == 'object' && potentialPackageJson !== null && typeof potentialPackageJson.version === 'string' && potentialPackageJson.name === sharedName) {
          return potentialPackageJson.version;
        }
      }
      potentialPackageJsonDir = path__namespace.dirname(potentialPackageJsonDir);
    }
  } catch (_) {}
  return undefined;
}
function normalizeShareItem(key, shareItem) {
  var version;
  try {
    try {
      version = require(path__namespace.join(removePathFromNpmPackage(key), 'package.json')).version;
    } catch (e1) {
      try {
        var localPath = path__namespace.join(process.cwd(), 'node_modules', removePathFromNpmPackage(key), 'package.json');
        version = require(localPath).version;
      } catch (e2) {
        version = searchPackageVersion(key);
        if (!version) console.error(e1);
      }
    }
  } catch (e) {
    console.error("Unexpected error resolving version for " + key + ":", e);
  }
  if (typeof shareItem === 'string') {
    return {
      name: shareItem,
      version: version,
      scope: 'default',
      from: '',
      shareConfig: {
        singleton: false,
        requiredVersion: version ? "^" + version : '*'
      }
    };
  }
  return {
    name: key,
    from: '',
    version: shareItem.version || version,
    scope: shareItem.shareScope || 'default',
    shareConfig: {
      singleton: shareItem.singleton || false,
      requiredVersion: shareItem.requiredVersion || (version ? "^" + version : '*'),
      strictVersion: !!shareItem.strictVersion
    }
  };
}
function normalizeShared(shared) {
  if (!shared) return {};
  var result = {};
  if (Array.isArray(shared)) {
    shared.forEach(function (key) {
      result[key] = normalizeShareItem(key, key);
    });
    return result;
  }
  if (typeof shared === 'object') {
    Object.keys(shared).forEach(function (key) {
      result[key] = normalizeShareItem(key, shared[key]);
    });
  }
  return result;
}
function normalizeLibrary(library) {
  if (!library) return undefined;
  return library;
}
function normalizeManifest(manifest) {
  if (manifest === void 0) {
    manifest = false;
  }
  if (typeof manifest === 'boolean') {
    return manifest;
  }
  return Object.assign({
    filePath: '',
    disableAssetsAnalyze: false,
    fileName: 'mf-manifest.json'
  }, manifest);
}
var config;
function getNormalizeModuleFederationOptions() {
  return config;
}
function getNormalizeShareItem(key) {
  var options = getNormalizeModuleFederationOptions();
  var shareItem = options.shared[key] || options.shared[removePathFromNpmPackage(key)] || options.shared[removePathFromNpmPackage(key) + '/'];
  return shareItem;
}
function normalizeModuleFederationOptions(options) {
  if (options.getPublicPath) {
    warn("We are ignoring the getPublicPath options because they are natively supported by Vite\nwith the \"experimental.renderBuiltUrl\" configuration https://vitejs.dev/guide/build#advanced-base-options");
  }
  if (options.virtualModuleDir && options.virtualModuleDir.includes('/')) {
    throw new Error("Invalid virtualModuleDir: \"" + options.virtualModuleDir + "\". " + "The virtualModuleDir option cannot contain slashes (/). " + "Please use a single directory name like '__mf__virtual__your_app_name'.");
  }
  return config = {
    exposes: normalizeExposes(options.exposes),
    filename: options.filename || 'remoteEntry-[hash]',
    library: normalizeLibrary(options.library),
    name: options.name,
    // remoteType: options.remoteType,
    remotes: normalizeRemotes(options.remotes),
    runtime: options.runtime,
    shareScope: options.shareScope || 'default',
    shared: normalizeShared(options.shared),
    runtimePlugins: options.runtimePlugins || [],
    implementation: options.implementation || require.resolve('@module-federation/runtime'),
    manifest: normalizeManifest(options.manifest),
    dev: options.dev,
    dts: options.dts,
    getPublicPath: options.getPublicPath,
    publicPath: options.publicPath,
    shareStrategy: options.shareStrategy || 'version-first',
    ignoreOrigin: options.ignoreOrigin || false,
    virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
  };
}
/**
 * Escaping rules:
 * Convert using the format __${mapping}__, where _ and $ are not allowed in npm package names but can be used in variable names.
 *  @ => 1
 *  / => 2
 *  - => 3
 *  . => 4
 */
/**
 * Encodes a package name into a valid file name.
 * @param {string} name - The package name, e.g., "@scope/xx-xx.xx".
 * @returns {string} - The encoded file name.
 */
function packageNameEncode(name) {
  if (typeof name !== 'string') throw new Error('A string package name is required');
  return name.replace(/@/g, '_mf_0_').replace(/\//g, '_mf_1_').replace(/-/g, '_mf_2_').replace(/\./g, '_mf_3_');
}
/**
 * Decodes an encoded file name back to the original package name.
 * @param {string} encoded - The encoded file name, e.g., "_mf_0_scope_mf_1_xx_mf_2_xx_mf_3_xx".
 * @returns {string} - The decoded package name.
 */
function packageNameDecode(encoded) {
  if (typeof encoded !== 'string') throw new Error('A string encoded file name is required');
  return encoded.replace(/_mf_0_/g, '@').replace(/_mf_1_/g, '/').replace(/_mf_2_/g, '-').replace(/_mf_3_/g, '.');
}
/**
 * https://github.com/module-federation/vite/issues/68
 */
function getLocalSharedImportMapPath_temp() {
  var _getNormalizeModuleFe = getNormalizeModuleFederationOptions(),
    name = _getNormalizeModuleFe.name;
  return path__default["default"].resolve('.__mf__temp', packageNameEncode(name), 'localSharedImportMap');
}
function writeLocalSharedImportMap_temp(content) {
  var localSharedImportMapId = getLocalSharedImportMapPath_temp();
  createFile(localSharedImportMapId + '.js', '\n// Windows temporarily needs this file, https://github.com/module-federation/vite/issues/68\n' + content);
}
function createFile(filePath, content) {
  var dir = path__default["default"].dirname(filePath);
  fs.mkdirSync(dir, {
    recursive: true
  });
  fs.writeFileSync(filePath, content);
}
// Cache root path
var rootDir;
function findNodeModulesDir(root) {
  if (root === void 0) {
    root = process.cwd();
  }
  var currentDir = root;
  while (currentDir !== path.parse(currentDir).root) {
    var nodeModulesPath = path.join(currentDir, 'node_modules');
    if (fs.existsSync(nodeModulesPath)) {
      return nodeModulesPath;
    }
    currentDir = path.dirname(currentDir);
  }
  return '';
}
// Cache nodeModulesDir result to avoid repeated calculations
var cachedNodeModulesDir;
function getNodeModulesDir() {
  if (!cachedNodeModulesDir) {
    cachedNodeModulesDir = findNodeModulesDir(rootDir);
  }
  return cachedNodeModulesDir;
}
function getSuffix(name) {
  var base = path.basename(name);
  var dotIndex = base.lastIndexOf('.');
  if (dotIndex > 0 && dotIndex < base.length - 1) {
    return base.slice(dotIndex);
  }
  return '.js';
}
var patternMap = {};
var cacheMap = {};
/**
 * Physically generate files as virtual modules under node_modules/__mf__virtual/*
 */
function assertModuleFound(tag, str) {
  if (str === void 0) {
    str = '';
  }
  var module = VirtualModule.findModule(tag, str);
  if (!module) {
    throw new Error("Module Federation shared module '" + str + "' not found. Please ensure it's installed as a dependency in your package.json.");
  }
  return module;
}
var VirtualModule = /*#__PURE__*/function () {
  function VirtualModule(name, tag, suffix) {
    if (tag === void 0) {
      tag = '__mf_v__';
    }
    if (suffix === void 0) {
      suffix = '';
    }
    this.name = void 0;
    this.tag = void 0;
    this.suffix = void 0;
    this.inited = false;
    this.name = name;
    this.tag = tag;
    this.suffix = suffix || getSuffix(name);
    if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
    cacheMap[this.tag][this.name] = this;
  }
  /**
   * Set the root path for finding node_modules
   * @param root - Root path
   */
  VirtualModule.setRoot = function setRoot(root) {
    rootDir = root;
    // Reset cache to ensure using the new root path
    cachedNodeModulesDir = undefined;
  }
  /**
   * Ensure virtual package directory exists
   */;
  VirtualModule.ensureVirtualPackageExists = function ensureVirtualPackageExists() {
    var nodeModulesDir = getNodeModulesDir();
    var _getNormalizeModuleFe = getNormalizeModuleFederationOptions(),
      virtualModuleDir = _getNormalizeModuleFe.virtualModuleDir;
    var virtualPackagePath = path.resolve(nodeModulesDir, virtualModuleDir);
    if (!fs.existsSync(virtualPackagePath)) {
      fs.mkdirSync(virtualPackagePath);
      fs.writeFileSync(path.resolve(virtualPackagePath, 'empty.js'), '');
      fs.writeFileSync(path.resolve(virtualPackagePath, 'package.json'), JSON.stringify({
        name: virtualModuleDir,
        main: 'empty.js'
      }));
    }
  };
  VirtualModule.findModule = function findModule(tag, str) {
    if (str === void 0) {
      str = '';
    }
    if (!patternMap[tag]) patternMap[tag] = new RegExp("(.*" + packageNameEncode(tag) + "(.+?)" + packageNameEncode(tag) + ".*)");
    var moduleName = (str.match(patternMap[tag]) || [])[2];
    if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
    return undefined;
  };
  var _proto = VirtualModule.prototype;
  _proto.getPath = function getPath() {
    return path.resolve(getNodeModulesDir(), this.getImportId());
  };
  _proto.getImportId = function getImportId() {
    var _getNormalizeModuleFe2 = getNormalizeModuleFederationOptions(),
      mfName = _getNormalizeModuleFe2.name,
      virtualModuleDir = _getNormalizeModuleFe2.virtualModuleDir;
    return virtualModuleDir + "/" + packageNameEncode("" + mfName + this.tag + this.name + this.tag) + this.suffix;
  };
  _proto.writeSync = function writeSync(code, force) {
    if (!force && this.inited) return;
    if (!this.inited) {
      this.inited = true;
    }
    fs.writeFileSync(this.getPath(), code);
  };
  _proto.write = function write(code) {
    fs.writeFile(this.getPath(), code, function () {});
  };
  return VirtualModule;
}();
var VIRTUAL_EXPOSES = 'virtual:mf-exposes';
function generateExposes() {
  var options = getNormalizeModuleFederationOptions();
  return "\n    export default {\n    " + Object.keys(options.exposes).map(function (key) {
    return "\n        " + JSON.stringify(key) + ": async () => {\n          const importModule = await import(" + JSON.stringify(options.exposes[key]["import"]) + ")\n          const exportModule = {}\n          Object.assign(exportModule, importModule)\n          Object.defineProperty(exportModule, \"__esModule\", {\n            value: true,\n            enumerable: false\n          })\n          return exportModule\n        }\n      ";
  }).join(',') + "\n  }\n  ";
}
var virtualRuntimeInitStatus = new VirtualModule('runtimeInit');
function writeRuntimeInitStatus() {
  virtualRuntimeInitStatus.writeSync("\n    let initResolve, initReject\n    const initPromise = new Promise((re, rj) => {\n      initResolve = re\n      initReject = rj\n    })\n    module.exports = {\n      initPromise,\n      initResolve,\n      initReject\n    }\n    ");
}
var cacheRemoteMap = {};
var LOAD_REMOTE_TAG = '__loadRemote__';
function getRemoteVirtualModule(remote, command) {
  if (!cacheRemoteMap[remote]) {
    cacheRemoteMap[remote] = new VirtualModule(remote, LOAD_REMOTE_TAG, '.js');
    cacheRemoteMap[remote].writeSync(generateRemotes(remote, command));
  }
  var virtual = cacheRemoteMap[remote];
  return virtual;
}
var usedRemotesMap = {
  // remote1: {remote1/App, remote1, remote1/Button}
};
function addUsedRemote(remoteKey, remoteModule) {
  if (!usedRemotesMap[remoteKey]) usedRemotesMap[remoteKey] = new Set();
  usedRemotesMap[remoteKey].add(remoteModule);
}
function getUsedRemotesMap() {
  return usedRemotesMap;
}
function generateRemotes(id, command) {
  return "\n    const {loadRemote} = require(\"@module-federation/runtime\")\n    const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n    const res = initPromise.then(_ => loadRemote(" + JSON.stringify(id) + "))\n    const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "initPromise.then(_ => res)\n    module.exports = exportModule\n  ";
}
/**
 * Even the resolveId hook cannot interfere with vite pre-build,
 * and adding query parameter virtual modules will also fail.
 * You can only proxy to the real file through alias
 */
// *** __prebuild__
var preBuildCacheMap = {};
var PREBUILD_TAG = '__prebuild__';
function writePreBuildLibPath(pkg) {
  if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG);
  preBuildCacheMap[pkg].writeSync('');
}
function getPreBuildLibImportId(pkg) {
  if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG);
  var importId = preBuildCacheMap[pkg].getImportId();
  return importId;
}
// *** __loadShare__
var LOAD_SHARE_TAG = '__loadShare__';
var loadShareCacheMap = {};
function getLoadShareModulePath(pkg) {
  if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, '.js');
  var filepath = loadShareCacheMap[pkg].getPath();
  return filepath;
}
function writeLoadShareModule(pkg, shareItem, command) {
  loadShareCacheMap[pkg].writeSync("\n\n    ;() => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n    // dev uses dynamic import to separate chunks\n    " + (command !== 'build' ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n    const {loadShare} = require(\"@module-federation/runtime\")\n    const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n    const res = initPromise.then(_ => loadShare(" + JSON.stringify(pkg) + ", {\n    customShareInfo: {shareConfig:{\n      singleton: " + shareItem.shareConfig.singleton + ",\n      strictVersion: " + shareItem.shareConfig.strictVersion + ",\n      requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n    }}}))\n    const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n    module.exports = exportModule\n  ");
}
var usedShares = new Set();
function getUsedShares() {
  return usedShares;
}
function addUsedShares(pkg) {
  usedShares.add(pkg);
}
// *** Expose locally provided shared modules here
new VirtualModule('localSharedImportMap');
function getLocalSharedImportMapPath() {
  return getLocalSharedImportMapPath_temp();
  // return localSharedImportMapModule.getPath()
}
var prevSharedCount;
function writeLocalSharedImportMap() {
  var sharedCount = getUsedShares().size;
  if (prevSharedCount !== sharedCount) {
    prevSharedCount = sharedCount;
    writeLocalSharedImportMap_temp(generateLocalSharedImportMap());
    //   localSharedImportMapModule.writeSync(generateLocalSharedImportMap(), true)
  }
}
function generateLocalSharedImportMap() {
  var options = getNormalizeModuleFederationOptions();
  return "\n    const importMap = {\n      " + Array.from(getUsedShares()).sort().map(function (pkg) {
    return "\n        " + JSON.stringify(pkg) + ": async () => {\n          let pkg = await import(\"" + getPreBuildLibImportId(pkg) + "\")\n          return pkg\n        }\n      ";
  }).join(',') + "\n    }\n      const usedShared = {\n      " + Array.from(getUsedShares()).sort().map(function (key) {
    var shareItem = getNormalizeShareItem(key);
    if (!shareItem) return null;
    return "\n          " + JSON.stringify(key) + ": {\n            name: " + JSON.stringify(key) + ",\n            version: " + JSON.stringify(shareItem.version) + ",\n            scope: [" + JSON.stringify(shareItem.scope) + "],\n            loaded: false,\n            from: " + JSON.stringify(options.name) + ",\n            async get () {\n              usedShared[" + JSON.stringify(key) + "].loaded = true\n              const {" + JSON.stringify(key) + ": pkgDynamicImport} = importMap \n              const res = await pkgDynamicImport()\n              const exportModule = {...res}\n              // All npm packages pre-built by vite will be converted to esm\n              Object.defineProperty(exportModule, \"__esModule\", {\n                value: true,\n                enumerable: false\n              })\n              return function () {\n                return exportModule\n              }\n            },\n            shareConfig: {\n              singleton: " + shareItem.shareConfig.singleton + ",\n              requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n            }\n          }\n        ";
  }).filter(function (x) {
    return x !== null;
  }).join(',') + "\n    }\n      const usedRemotes = [" + Object.keys(getUsedRemotesMap()).map(function (key) {
    var _JSON$stringify;
    var remote = options.remotes[key];
    if (!remote) return null;
    return "\n                {\n                  entryGlobalName: " + JSON.stringify(remote.entryGlobalName) + ",\n                  name: " + JSON.stringify(remote.name) + ",\n                  type: " + JSON.stringify(remote.type) + ",\n                  entry: " + JSON.stringify(remote.entry) + ",\n                  shareScope: " + ((_JSON$stringify = JSON.stringify(remote.shareScope)) != null ? _JSON$stringify : 'default') + ",\n                }\n          ";
  }).filter(function (x) {
    return x !== null;
  }).join(',') + "\n      ]\n      export {\n        usedShared,\n        usedRemotes\n      }\n      ";
}
var REMOTE_ENTRY_ID = 'virtual:mf-REMOTE_ENTRY_ID';
function generateRemoteEntry(options) {
  var pluginImportNames = options.runtimePlugins.map(function (p, i) {
    return ["$runtimePlugin_" + i, "import $runtimePlugin_" + i + " from \"" + p + "\";"];
  });
  return "\n  import {init as runtimeInit, loadRemote} from \"@module-federation/runtime\";\n  " + pluginImportNames.map(function (item) {
    return item[1];
  }).join('\n') + "\n  import exposesMap from \"" + VIRTUAL_EXPOSES + "\"\n  import {usedShared, usedRemotes} from \"" + getLocalSharedImportMapPath() + "\"\n  import {\n    initResolve\n  } from \"" + virtualRuntimeInitStatus.getImportId() + "\"\n  const initTokens = {}\n  const shareScopeName = " + JSON.stringify(options.shareScope) + "\n  const mfName = " + JSON.stringify(options.name) + "\n  async function init(shared = {}, initScope = []) {\n    const initRes = runtimeInit({\n      name: mfName,\n      remotes: usedRemotes,\n      shared: usedShared,\n      plugins: [" + pluginImportNames.map(function (item) {
    return item[0] + "()";
  }).join(', ') + "],\n      " + (options.shareStrategy ? "shareStrategy: '" + options.shareStrategy + "'" : '') + "\n    });\n    // handling circular init calls\n    var initToken = initTokens[shareScopeName];\n    if (!initToken)\n      initToken = initTokens[shareScopeName] = { from: mfName };\n    if (initScope.indexOf(initToken) >= 0) return;\n    initScope.push(initToken);\n    initRes.initShareScopeMap('" + options.shareScope + "', shared);\n    try {\n      await Promise.all(await initRes.initializeSharing('" + options.shareScope + "', {\n        strategy: '" + options.shareStrategy + "',\n        from: \"build\",\n        initScope\n      }));\n    } catch (e) {\n      console.error(e)\n    }\n    initResolve(initRes)\n    return initRes\n  }\n\n  function getExposes(moduleName) {\n    if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n    return (exposesMap[moduleName])().then(res => () => res)\n  }\n  export {\n      init,\n      getExposes as get\n  }\n  ";
}
/**
 * Inject entry file, automatically init when used as host,
 * and will not inject remoteEntry
 */
var HOST_AUTO_INIT_TAG = '__H_A_I__';
var hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
function writeHostAutoInit() {
  hostAutoInitModule.writeSync("\n    const remoteEntryPromise = import(\"" + REMOTE_ENTRY_ID + "\")\n    // __tla only serves as a hack for vite-plugin-top-level-await. \n    Promise.resolve(remoteEntryPromise)\n      .then(remoteEntry => {\n        return Promise.resolve(remoteEntry.__tla)\n          .then(remoteEntry.init).catch(remoteEntry.init)\n      })\n    ");
}
function getHostAutoInitImportId() {
  return hostAutoInitModule.getImportId();
}
function getHostAutoInitPath() {
  return hostAutoInitModule.getPath();
}
function initVirtualModules() {
  writeLocalSharedImportMap();
  writeHostAutoInit();
  writeRuntimeInitStatus();
}
var ASSET_TYPES = ['js', 'css'];
var LOAD_TIMINGS = ['sync', 'async'];
var JS_EXTENSIONS = ['.ts', '.tsx', '.jsx', '.mjs', '.cjs'];
/**
 * Creates an empty asset map structure for tracking JS and CSS assets
 * @returns Initialized asset map with sync/async arrays for JS and CSS
 */
var createEmptyAssetMap = function createEmptyAssetMap() {
  return {
    js: {
      sync: [],
      async: []
    },
    css: {
      sync: [],
      async: []
    }
  };
};
/**
 * Tracks an asset in the preload map with deduplication
 * @param map - The preload map to update
 * @param key - The module key to track under
 * @param fileName - The asset filename to track
 * @param isAsync - Whether the asset is loaded async
 * @param type - The asset type ('js' or 'css')
 */
var trackAsset = function trackAsset(map, key, fileName, isAsync, type) {
  if (!map[key]) {
    map[key] = createEmptyAssetMap();
  }
  var target = isAsync ? map[key][type].async : map[key][type].sync;
  if (!target.includes(fileName)) {
    target.push(fileName);
  }
};
/**
 * Checks if a file is a CSS file by extension
 * @param fileName - The filename to check
 * @returns True if file has a CSS extension (.css, .scss, .less)
 */
var isCSSFile = function isCSSFile(fileName) {
  return fileName.endsWith('.css') || fileName.endsWith('.scss') || fileName.endsWith('.less');
};
/**
 * Collects all CSS assets from the bundle
 * @param bundle - The Rollup output bundle
 * @returns Set of CSS asset filenames
 */
var collectCssAssets = function collectCssAssets(bundle) {
  var cssAssets = new Set();
  for (var _i = 0, _Object$entries = Object.entries(bundle); _i < _Object$entries.length; _i++) {
    var _Object$entries$_i = _Object$entries[_i],
      fileName = _Object$entries$_i[0],
      fileData = _Object$entries$_i[1];
    if (fileData.type === 'asset' && isCSSFile(fileName)) {
      cssAssets.add(fileName);
    }
  }
  return cssAssets;
};
/**
 * Processes module assets and tracks them in the files map
 * @param bundle - The Rollup output bundle
 * @param filesMap - The preload map to populate
 * @param moduleMatcher - Function that matches module paths to keys
 */
var processModuleAssets = function processModuleAssets(bundle, filesMap, moduleMatcher) {
  for (var _i2 = 0, _Object$entries2 = Object.entries(bundle); _i2 < _Object$entries2.length; _i2++) {
    var _Object$entries2$_i = _Object$entries2[_i2],
      fileName = _Object$entries2$_i[0],
      fileData = _Object$entries2$_i[1];
    if (fileData.type !== 'chunk') continue;
    if (!fileData.modules) continue;
    for (var _i3 = 0, _Object$keys = Object.keys(fileData.modules); _i3 < _Object$keys.length; _i3++) {
      var modulePath = _Object$keys[_i3];
      var matchKey = moduleMatcher(modulePath);
      if (!matchKey) continue;
      // Track main JS chunk
      trackAsset(filesMap, matchKey, fileName, false, 'js');
      // Handle dynamic imports
      if (fileData.dynamicImports) {
        for (var _iterator = _createForOfIteratorHelperLoose(fileData.dynamicImports), _step; !(_step = _iterator()).done;) {
          var dynamicImport = _step.value;
          var importData = bundle[dynamicImport];
          if (!importData) continue;
          var isCss = isCSSFile(dynamicImport);
          trackAsset(filesMap, matchKey, dynamicImport, true, isCss ? 'css' : 'js');
        }
      }
    }
  }
};
/**
 * Deduplicates assets in the files map
 * @param filesMap - The preload map to deduplicate
 * @returns New deduplicated preload map
 */
var deduplicateAssets = function deduplicateAssets(filesMap) {
  var result = {};
  for (var _i4 = 0, _Object$entries3 = Object.entries(filesMap); _i4 < _Object$entries3.length; _i4++) {
    var _Object$entries3$_i = _Object$entries3[_i4],
      key = _Object$entries3$_i[0],
      assetMaps = _Object$entries3$_i[1];
    result[key] = createEmptyAssetMap();
    for (var _i5 = 0, _ASSET_TYPES = ASSET_TYPES; _i5 < _ASSET_TYPES.length; _i5++) {
      var type = _ASSET_TYPES[_i5];
      for (var _i6 = 0, _LOAD_TIMINGS = LOAD_TIMINGS; _i6 < _LOAD_TIMINGS.length; _i6++) {
        var timing = _LOAD_TIMINGS[_i6];
        result[key][type][timing] = Array.from(new Set(assetMaps[type][timing]));
      }
    }
  }
  return result;
};
/**
 * Builds a mapping between module files and their share keys
 * @param shareKeys - Set of share keys to map
 * @param resolveFn - Function to resolve module paths
 * @returns Map of file paths to their corresponding share keys
 */
var buildFileToShareKeyMap = function buildFileToShareKeyMap(shareKeys, resolveFn) {
  try {
    var fileToShareKey = new Map();
    return Promise.resolve(Promise.all(Array.from(shareKeys).map(function (shareKey) {
      return resolveFn(getPreBuildLibImportId(shareKey)).then(function (resolution) {
        var _resolution$id;
        return {
          shareKey: shareKey,
          file: resolution == null || (_resolution$id = resolution.id) == null ? void 0 : _resolution$id.split('?')[0]
        };
      })["catch"](function () {
        return null;
      });
    }))).then(function (resolutions) {
      for (var _iterator2 = _createForOfIteratorHelperLoose(resolutions), _step2; !(_step2 = _iterator2()).done;) {
        var resolution = _step2.value;
        if (resolution != null && resolution.file) {
          fileToShareKey.set(resolution.file, resolution.shareKey);
        }
      }
      return fileToShareKey;
    });
  } catch (e) {
    return Promise.reject(e);
  }
};
/**
 * Resolves the public path for remote entries
 * @param options - Module Federation options
 * @param viteBase - Vite's base config value
 * @param originalBase - Original base config before any transformations
 * @returns The resolved public path
 */
function resolvePublicPath(options, viteBase, originalBase) {
  // Use explicitly set publicPath if provided
  if (options.publicPath) {
    return options.publicPath;
  }
  // Handle empty original base case
  if (originalBase === '') {
    return 'auto';
  }
  // Use viteBase if available, ensuring it ends with a slash
  if (viteBase) {
    return viteBase.replace(/\/?$/, '/');
  }
  // Fallback to auto if no base is specified
  return 'auto';
}
var Manifest = function Manifest() {
  var mfOptions = getNormalizeModuleFederationOptions();
  var name = mfOptions.name,
    filename = mfOptions.filename,
    getPublicPath = mfOptions.getPublicPath,
    manifestOptions = mfOptions.manifest;
  var mfManifestName = '';
  if (manifestOptions === true) {
    mfManifestName = 'mf-manifest.json';
  }
  if (typeof manifestOptions !== 'boolean') {
    mfManifestName = path__namespace.join((manifestOptions == null ? void 0 : manifestOptions.filePath) || '', (manifestOptions == null ? void 0 : manifestOptions.fileName) || '');
  }
  var root;
  var remoteEntryFile;
  var publicPath;
  var _command;
  var _originalConfigBase;
  var viteConfig;
  /**
   * Adds global CSS assets to all module exports
   * @param filesMap - The preload map to update
   * @param cssAssets - Set of CSS asset filenames to add
   */
  var addCssAssetsToAllExports = function addCssAssetsToAllExports(filesMap, cssAssets) {
    Object.keys(filesMap).forEach(function (key) {
      cssAssets.forEach(function (cssAsset) {
        trackAsset(filesMap, key, cssAsset, false, 'css');
      });
    });
  };
  return [{
    name: 'module-federation-manifest',
    apply: 'serve',
    /**
     * Stores resolved Vite config for later use
     */
    /**
     * Finalizes configuration after all plugins are resolved
     * @param config - Fully resolved Vite config
     */
    configResolved: function configResolved(config) {
      viteConfig = config;
    },
    /**
     * Configures dev server middleware to handle manifest requests
     * @param server - Vite dev server instance
     */
    configureServer: function configureServer(server) {
      server.middlewares.use(function (req, res, next) {
        var _req$url;
        if (!mfManifestName) {
          next();
          return;
        }
        if (((_req$url = req.url) == null ? void 0 : _req$url.replace(/\?.*/, '')) === (viteConfig.base + mfManifestName).replace(/^\/?/, '/')) {
          res.setHeader('Content-Type', 'application/json');
          res.setHeader('Access-Control-Allow-Origin', '*');
          res.end(JSON.stringify(_extends({}, generateMFManifest({}), {
            id: name,
            name: name,
            metaData: {
              name: name,
              type: 'app',
              buildInfo: {
                buildVersion: '1.0.0',
                buildName: name
              },
              remoteEntry: {
                name: filename,
                path: '',
                type: 'module'
              },
              ssrRemoteEntry: {
                name: filename,
                path: '',
                type: 'module'
              },
              types: {
                path: '',
                name: ''
              },
              globalName: name,
              pluginVersion: '0.2.5',
              publicPath: publicPath
            }
          })));
        } else {
          next();
        }
      });
    }
  }, {
    name: 'module-federation-manifest',
    enforce: 'post',
    /**
     * Initial plugin configuration
     * @param config - Vite config object
     * @param command - Current Vite command (serve/build)
     */
    config: function config(_config, _ref) {
      var command = _ref.command;
      if (!_config.build) _config.build = {};
      if (!_config.build.manifest) {
        _config.build.manifest = _config.build.manifest || !!manifestOptions;
      }
      _command = command;
      _originalConfigBase = _config.base;
    },
    configResolved: function configResolved(config) {
      root = config.root;
      var base = config.base;
      if (_command === 'serve') {
        base = (config.server.origin || '') + config.base;
      }
      publicPath = resolvePublicPath(mfOptions, base, _originalConfigBase);
    },
    /**
     * Generates the module federation manifest file
     * @param options - Rollup output options
     * @param bundle - Generated bundle assets
     */
    generateBundle: function generateBundle(options, bundle) {
      try {
        var _this = this;
        if (!mfManifestName) return Promise.resolve();
        var filesMap = {};
        // First pass: Find remoteEntry file
        for (var _i = 0, _Object$entries = Object.entries(bundle); _i < _Object$entries.length; _i++) {
          var _Object$entries$_i = _Object$entries[_i],
            _ = _Object$entries$_i[0],
            fileData = _Object$entries$_i[1];
          if (mfOptions.filename.replace(/[\[\]]/g, '_').replace(/\.[^/.]+$/, '') === fileData.name || fileData.name === 'remoteEntry') {
            remoteEntryFile = fileData.fileName;
            break; // We can break early since we only need to find remoteEntry once
          }
        }
        // Second pass: Collect all CSS assets
        var allCssAssets = collectCssAssets(bundle);
        var exposesModules = Object.keys(mfOptions.exposes).map(function (item) {
          return mfOptions.exposes[item]["import"];
        });
        // Process exposed modules
        processModuleAssets(bundle, filesMap, function (modulePath) {
          var absoluteModulePath = path__namespace.resolve(root, modulePath);
          return exposesModules.find(function (exposeModule) {
            var exposePath = path__namespace.resolve(root, exposeModule);
            // First try exact path match
            if (absoluteModulePath === exposePath) {
              return true;
            }
            // Then try path match without known extensions
            var getPathWithoutKnownExt = function getPathWithoutKnownExt(filePath) {
              var ext = path__namespace.extname(filePath);
              return JS_EXTENSIONS.includes(ext) ? path__namespace.join(path__namespace.dirname(filePath), path__namespace.basename(filePath, ext)) : filePath;
            };
            var modulePathNoExt = getPathWithoutKnownExt(absoluteModulePath);
            var exposePathNoExt = getPathWithoutKnownExt(exposePath);
            return modulePathNoExt === exposePathNoExt;
          });
        });
        // Process shared modules
        return Promise.resolve(buildFileToShareKeyMap(getUsedShares(), _this.resolve.bind(_this))).then(function (fileToShareKey) {
          processModuleAssets(bundle, filesMap, function (modulePath) {
            return fileToShareKey.get(modulePath);
          });
          // Add all CSS assets to every export
          addCssAssetsToAllExports(filesMap, allCssAssets);
          // Final deduplication of all assets
          filesMap = deduplicateAssets(filesMap);
          _this.emitFile({
            type: 'asset',
            fileName: mfManifestName,
            source: JSON.stringify(generateMFManifest(filesMap))
          });
        });
      } catch (e) {
        return Promise.reject(e);
      }
    }
  }];
  /**
   * Generates the final manifest JSON structure
   * @param preloadMap - Map of module assets to include
   * @returns Complete manifest object
   */
  function generateMFManifest(preloadMap) {
    var options = getNormalizeModuleFederationOptions();
    var name = options.name;
    var remoteEntry = {
      name: remoteEntryFile,
      path: '',
      type: 'module'
    };
    // Process remotes
    var remotes = Array.from(Object.entries(getUsedRemotesMap())).flatMap(function (_ref2) {
      var remoteKey = _ref2[0],
        modules = _ref2[1];
      return Array.from(modules).map(function (moduleKey) {
        return {
          federationContainerName: options.remotes[remoteKey].entry,
          moduleName: moduleKey.replace(remoteKey, '').replace('/', ''),
          alias: remoteKey,
          entry: '*'
        };
      });
    });
    // Process shared dependencies
    var shared = Array.from(getUsedShares()).map(function (shareKey) {
      var shareItem = getNormalizeShareItem(shareKey);
      var assets = preloadMap[shareKey] || createEmptyAssetMap();
      return {
        id: name + ":" + shareKey,
        name: shareKey,
        version: shareItem.version,
        requiredVersion: shareItem.shareConfig.requiredVersion,
        assets: {
          js: {
            async: assets.js.async,
            sync: assets.js.sync
          },
          css: {
            async: assets.css.async,
            sync: assets.css.sync
          }
        }
      };
    }).filter(Boolean);
    // Process exposed modules
    var exposes = Object.entries(options.exposes).map(function (_ref3) {
      var key = _ref3[0],
        value = _ref3[1];
      var formatKey = key.replace('./', '');
      var sourceFile = value["import"];
      var assets = preloadMap[sourceFile] || createEmptyAssetMap();
      return {
        id: name + ":" + formatKey,
        name: formatKey,
        assets: {
          js: {
            async: assets.js.async,
            sync: assets.js.sync
          },
          css: {
            async: assets.css.async,
            sync: assets.css.sync
          }
        },
        path: key
      };
    }).filter(Boolean);
    return {
      id: name,
      name: name,
      metaData: _extends({
        name: name,
        type: 'app',
        buildInfo: {
          buildVersion: '1.0.0',
          buildName: name
        },
        remoteEntry: remoteEntry,
        ssrRemoteEntry: remoteEntry,
        types: {
          path: '',
          name: ''
        },
        globalName: name,
        pluginVersion: '0.2.5'
      }, !!getPublicPath ? {
        getPublicPath: getPublicPath
      } : {
        publicPath: publicPath
      }),
      shared: shared,
      remotes: remotes,
      exposes: exposes
    };
  }
};
var _resolve,
  promise = new Promise(function (resolve, reject) {
    _resolve = resolve;
  });
var parsePromise = promise;
var exposesParseEnd = false;
var parseStartSet = new Set();
var parseEndSet = new Set();
function pluginModuleParseEnd (excludeFn) {
  return [{
    name: '_',
    apply: 'serve',
    config: function config() {
      // No waitin