@module-federation/vite 1.9.3 → 1.9.5

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/lib/index.esm.js CHANGED
@@ -6,6 +6,9 @@ import path__default, { resolve, basename, parse, join, dirname } from 'pathe';
6
6
  import MagicString from 'magic-string';
7
7
  import { createFilter } from '@rollup/pluginutils';
8
8
  import { walk } from 'estree-walker';
9
+ import { normalizeOptions } from '@module-federation/sdk';
10
+ import { normalizeGenerateTypesOptions, generateTypesAPI, normalizeDtsOptions, normalizeConsumeTypesOptions, consumeTypesAPI, isTSProject } from '@module-federation/dts-plugin';
11
+ import { rpc } from '@module-federation/dts-plugin/core';
9
12
 
10
13
  var mapCodeToCodeWithSourcemap = function mapCodeToCodeWithSourcemap(code) {
11
14
  return Promise.resolve(code).then(function (resolvedCode) {
@@ -123,9 +126,11 @@ var addEntry = function addEntry(_ref) {
123
126
  }
124
127
  },
125
128
  generateBundle: function generateBundle(options, bundle) {
129
+ var _viteConfig$experimen, _viteConfig$experimen2;
126
130
  if (!injectHtml()) return;
127
131
  var file = this.getFileName(emitFileId);
128
- var scriptContent = "\n <script type=\"module\" src=\"" + (viteConfig.base + file) + "\"></script>\n ";
132
+ var path = (_viteConfig$experimen = viteConfig.experimental) != null && _viteConfig$experimen.renderBuiltUrl ? (_viteConfig$experimen2 = viteConfig.experimental) == null ? void 0 : _viteConfig$experimen2.renderBuiltUrl(file) : viteConfig.base + file;
133
+ var scriptContent = "\n <script type=\"module\" src=\"" + path + "\"></script>\n ";
129
134
  for (var _fileName in bundle) {
130
135
  if (_fileName.endsWith('.html')) {
131
136
  var htmlAsset = bundle[_fileName];
@@ -561,6 +566,96 @@ function createFile(filePath, content) {
561
566
  writeFileSync(filePath, content);
562
567
  }
563
568
 
569
+ /**
570
+ * Serializes a JavaScript object into a string of source code that can be evaluated.
571
+ * This function is used to create runtime plugin options without relying solely on JSON.stringify,
572
+ * allowing support for non-JSON types like RegExp, Date, Map, Set, and Functions.
573
+ * It also safely handles circular references.
574
+ *
575
+ * @param {Record<string, unknown>} options - The options object to serialize.
576
+ * @returns {string} The resulting JavaScript source code string.
577
+ */
578
+ function serializeRuntimeOptions(options) {
579
+ // Use a WeakSet to track objects already encountered, which helps in detecting circular references.
580
+ var seenObjects = new WeakSet();
581
+ /**
582
+ * Recursive inner function to serialize any value into a source code string.
583
+ */
584
+ function valueToCode(val) {
585
+ // 1. Handle primitive values
586
+ if (val === null) return 'null';
587
+ var type = typeof val;
588
+ if (type === 'string') return JSON.stringify(val);
589
+ if (type === 'number' || type === 'boolean') return String(val);
590
+ if (type === 'undefined') return 'undefined';
591
+ // Handle Symbol
592
+ if (type === 'symbol') {
593
+ var _val$description;
594
+ var desc = (_val$description = val.description) != null ? _val$description : '';
595
+ return "Symbol(" + JSON.stringify(desc) + ")";
596
+ }
597
+ // Handle Function (returns the function's source code)
598
+ if (type === 'function') return val.toString();
599
+ // 2. Handle special built-in objects
600
+ if (val instanceof Date) return "new Date(" + JSON.stringify(val.toISOString()) + ")";
601
+ if (val instanceof RegExp) {
602
+ return "new RegExp(" + JSON.stringify(val.source) + ", " + JSON.stringify(val.flags) + ")";
603
+ }
604
+ // 3. Check for circular references and mark object as seen
605
+ // This applies to objects, arrays, maps, and sets.
606
+ if (type === 'object') {
607
+ if (seenObjects.has(val)) {
608
+ // This object has been seen previously in the recursion path
609
+ return "\"__circular__\"";
610
+ }
611
+ seenObjects.add(val);
612
+ }
613
+ // 4. Handle Array, Map, Set
614
+ if (Array.isArray(val)) {
615
+ // Recursively serialize each element
616
+ return "[" + val.map(valueToCode).join(', ') + "]";
617
+ }
618
+ if (val instanceof Map) {
619
+ // Serialize Map entries into an array of [key, value] pairs
620
+ var entries = Array.from(val.entries()).map(function (_ref) {
621
+ var k = _ref[0],
622
+ v = _ref[1];
623
+ return "[" + valueToCode(k) + ", " + valueToCode(v) + "]";
624
+ });
625
+ return "new Map([" + entries.join(', ') + "])";
626
+ }
627
+ if (val instanceof Set) {
628
+ // Serialize Set values into an array
629
+ var items = Array.from(val.values()).map(valueToCode);
630
+ return "new Set([" + items.join(', ') + "])";
631
+ }
632
+ // 5. Handle plain objects (the default object type)
633
+ if (type === 'object') {
634
+ var properties = [];
635
+ // Iterate over the object's own enumerable properties
636
+ for (var key in val) {
637
+ if (Object.prototype.hasOwnProperty.call(val, key)) {
638
+ // Wrap the key in JSON.stringify to handle non-identifier keys
639
+ properties.push(JSON.stringify(key) + ": " + valueToCode(val[key]));
640
+ }
641
+ }
642
+ return "{" + properties.join(', ') + "}";
643
+ }
644
+ // 6. Fallback case (e.g., BigInt, other object types)
645
+ // Coerce to string and then JSON.stringify that string for safety
646
+ return JSON.stringify(String(val));
647
+ }
648
+ // Start serialization for the top-level object
649
+ var topLevelProps = [];
650
+ // Iterate over the properties of the root 'options' object
651
+ for (var key in options) {
652
+ if (Object.prototype.hasOwnProperty.call(options, key)) {
653
+ topLevelProps.push(JSON.stringify(key) + ": " + valueToCode(options[key]));
654
+ }
655
+ }
656
+ return "{" + topLevelProps.join(', ') + "}";
657
+ }
658
+
564
659
  // Cache root path
565
660
  var rootDir;
566
661
  function findNodeModulesDir(root) {
@@ -797,12 +892,16 @@ function generateLocalSharedImportMap() {
797
892
  var REMOTE_ENTRY_ID = 'virtual:mf-REMOTE_ENTRY_ID';
798
893
  function generateRemoteEntry(options) {
799
894
  var pluginImportNames = options.runtimePlugins.map(function (p, i) {
800
- return ["$runtimePlugin_" + i, "import $runtimePlugin_" + i + " from \"" + p + "\";"];
895
+ if (typeof p === 'string') {
896
+ return ["$runtimePlugin_" + i, "import $runtimePlugin_" + i + " from \"" + p + "\";", "undefined"];
897
+ } else {
898
+ return ["$runtimePlugin_" + i, "import $runtimePlugin_" + i + " from \"" + p[0] + "\";", serializeRuntimeOptions(p[1])];
899
+ }
801
900
  });
802
901
  return "\n import {init as runtimeInit, loadRemote} from \"@module-federation/runtime\";\n " + pluginImportNames.map(function (item) {
803
902
  return item[1];
804
903
  }).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) {
805
- return item[0] + "()";
904
+ return item[0] + "(" + item[2] + ")";
806
905
  }).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 ";
807
906
  }
808
907
  /**
@@ -1416,6 +1515,317 @@ function pluginProxyRemotes (options) {
1416
1515
  };
1417
1516
  }
1418
1517
 
1518
+ function _catch(body, recover) {
1519
+ try {
1520
+ var result = body();
1521
+ } catch (e) {
1522
+ return recover(e);
1523
+ }
1524
+ if (result && result.then) {
1525
+ return result.then(void 0, recover);
1526
+ }
1527
+ return result;
1528
+ }
1529
+ var DEFAULT_DEV_OPTIONS = {
1530
+ disableLiveReload: true,
1531
+ disableHotTypesReload: false,
1532
+ disableDynamicRemoteTypeHints: false
1533
+ };
1534
+ var DYNAMIC_HINTS_PLUGIN = '@module-federation/dts-plugin/dynamic-remote-type-hints-plugin';
1535
+ var getIPv4 = function getIPv4() {
1536
+ return process.env['FEDERATION_IPV4'] || '127.0.0.1';
1537
+ };
1538
+ var forkDevWorkerPath = function () {
1539
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
1540
+ return require.resolve('@module-federation/dts-plugin/dist/fork-dev-worker.js');
1541
+ }();
1542
+ var DevWorker = /*#__PURE__*/function () {
1543
+ function DevWorker(options) {
1544
+ this.worker = rpc.createRpcWorker(forkDevWorkerPath, {}, undefined, false);
1545
+ this.worker.connect(options);
1546
+ }
1547
+ var _proto = DevWorker.prototype;
1548
+ _proto.update = function update() {
1549
+ var _this$worker$process;
1550
+ (_this$worker$process = this.worker.process) == null || _this$worker$process.send == null || _this$worker$process.send({
1551
+ type: rpc.RpcGMCallTypes.CALL,
1552
+ id: this.worker.id,
1553
+ args: [undefined, 'update']
1554
+ });
1555
+ };
1556
+ _proto.exit = function exit() {
1557
+ this.worker.terminate();
1558
+ };
1559
+ return DevWorker;
1560
+ }();
1561
+ var normalizeDevOptions = function normalizeDevOptions(dev) {
1562
+ if (dev === false) {
1563
+ return false;
1564
+ }
1565
+ if (dev === true || typeof dev === 'undefined') {
1566
+ return _extends({}, DEFAULT_DEV_OPTIONS);
1567
+ }
1568
+ return _extends({}, DEFAULT_DEV_OPTIONS, dev);
1569
+ };
1570
+ var buildDtsModuleFederationConfig = function buildDtsModuleFederationConfig(options) {
1571
+ var exposes = {};
1572
+ Object.entries(options.exposes).forEach(function (_ref) {
1573
+ var key = _ref[0],
1574
+ value = _ref[1];
1575
+ if (typeof value === 'string') {
1576
+ exposes[key] = value;
1577
+ return;
1578
+ }
1579
+ var importValue = Array.isArray(value["import"]) ? value["import"][0] : value["import"];
1580
+ if (importValue) {
1581
+ exposes[key] = importValue;
1582
+ }
1583
+ });
1584
+ var remotes = {};
1585
+ Object.entries(options.remotes).forEach(function (_ref2) {
1586
+ var _remote$entryGlobalNa, _remote$entryGlobalNa2;
1587
+ var key = _ref2[0],
1588
+ remote = _ref2[1];
1589
+ if (typeof remote === 'string') {
1590
+ remotes[key] = remote;
1591
+ return;
1592
+ }
1593
+ if (!remote.entry) {
1594
+ return;
1595
+ }
1596
+ var entryLooksLikeUrl = ((_remote$entryGlobalNa = remote.entryGlobalName) == null ? void 0 : _remote$entryGlobalNa.startsWith('http')) || ((_remote$entryGlobalNa2 = remote.entryGlobalName) == null ? void 0 : _remote$entryGlobalNa2.includes('.json'));
1597
+ var entryGlobalName = entryLooksLikeUrl ? remote.name || key : remote.entryGlobalName || remote.name || key;
1598
+ remotes[key] = entryGlobalName + "@" + remote.entry;
1599
+ });
1600
+ return _extends({}, options, {
1601
+ exposes: exposes,
1602
+ remotes: remotes
1603
+ });
1604
+ };
1605
+ var resolveOutputDir = function resolveOutputDir(config) {
1606
+ var outDir = config.build.outDir;
1607
+ if (path.isAbsolute(outDir)) {
1608
+ return path.relative(config.root, outDir);
1609
+ }
1610
+ return outDir;
1611
+ };
1612
+ var ensureRuntimePlugin = function ensureRuntimePlugin(options, pluginId) {
1613
+ var hasPlugin = options.runtimePlugins.some(function (plugin) {
1614
+ if (typeof plugin === 'string') {
1615
+ return plugin === pluginId;
1616
+ }
1617
+ return plugin[0] === pluginId;
1618
+ });
1619
+ if (!hasPlugin) {
1620
+ options.runtimePlugins.push(pluginId);
1621
+ }
1622
+ };
1623
+ var normalizeDevDtsOptions = function normalizeDevDtsOptions(dts, context) {
1624
+ var defaultGenerateTypes = {
1625
+ compileInChildProcess: true
1626
+ };
1627
+ var defaultConsumeTypes = {
1628
+ consumeAPITypes: true
1629
+ };
1630
+ return normalizeOptions(isTSProject(dts, context), {
1631
+ generateTypes: defaultGenerateTypes,
1632
+ consumeTypes: defaultConsumeTypes,
1633
+ extraOptions: {},
1634
+ displayErrorInTerminal: typeof dts === 'object' && dts ? dts.displayErrorInTerminal : undefined
1635
+ }, 'mfOptions.dts')(dts);
1636
+ };
1637
+ var logDtsError = function logDtsError(error, dtsOptions) {
1638
+ if (dtsOptions && dtsOptions.displayErrorInTerminal !== false) {
1639
+ console.error(error);
1640
+ }
1641
+ };
1642
+ function pluginDts(options) {
1643
+ if (options.dts === false) {
1644
+ return [];
1645
+ }
1646
+ var dtsModuleFederationConfig = buildDtsModuleFederationConfig(options);
1647
+ var resolvedConfig;
1648
+ var devWorker;
1649
+ var normalizedDevOptions;
1650
+ var devPlugin = {
1651
+ name: 'module-federation-dts-dev',
1652
+ apply: 'serve',
1653
+ config: function config(_config) {
1654
+ normalizedDevOptions = normalizeDevOptions(options.dev);
1655
+ if (!normalizedDevOptions) {
1656
+ return;
1657
+ }
1658
+ if (normalizedDevOptions.disableDynamicRemoteTypeHints) {
1659
+ return;
1660
+ }
1661
+ ensureRuntimePlugin(options, DYNAMIC_HINTS_PLUGIN);
1662
+ var define = _config.define ? _extends({}, _config.define) : {};
1663
+ if (!('FEDERATION_IPV4' in define)) {
1664
+ define.FEDERATION_IPV4 = JSON.stringify(getIPv4());
1665
+ }
1666
+ _config.define = define;
1667
+ },
1668
+ configResolved: function configResolved(config) {
1669
+ resolvedConfig = config;
1670
+ },
1671
+ configureServer: function configureServer(server) {
1672
+ if (!normalizedDevOptions || !resolvedConfig) {
1673
+ return;
1674
+ }
1675
+ var devOptions = normalizedDevOptions;
1676
+ if (devOptions.disableDynamicRemoteTypeHints && devOptions.disableHotTypesReload && devOptions.disableLiveReload) {
1677
+ return;
1678
+ }
1679
+ if (!options.name) {
1680
+ throw new Error('name is required if you want to enable dev server!');
1681
+ }
1682
+ var outputDir = resolveOutputDir(resolvedConfig);
1683
+ var normalizedDtsOptions = normalizeDevDtsOptions(options.dts, resolvedConfig.root);
1684
+ if (typeof normalizedDtsOptions !== 'object') {
1685
+ return;
1686
+ }
1687
+ var normalizedGenerateTypes = normalizeOptions(Boolean(normalizedDtsOptions), {
1688
+ compileInChildProcess: true
1689
+ }, 'mfOptions.dts.generateTypes')(normalizedDtsOptions.generateTypes);
1690
+ var remote = normalizedGenerateTypes === false ? undefined : _extends({
1691
+ implementation: normalizedDtsOptions.implementation,
1692
+ context: resolvedConfig.root,
1693
+ outputDir: outputDir,
1694
+ moduleFederationConfig: _extends({}, dtsModuleFederationConfig),
1695
+ hostRemoteTypesFolder: normalizedGenerateTypes.typesFolder || '@mf-types'
1696
+ }, normalizedGenerateTypes, {
1697
+ typesFolder: '.dev-server'
1698
+ });
1699
+ if (remote && !remote.tsConfigPath && typeof normalizedDtsOptions === 'object' && normalizedDtsOptions.tsConfigPath) {
1700
+ remote.tsConfigPath = normalizedDtsOptions.tsConfigPath;
1701
+ }
1702
+ var normalizedConsumeTypes = normalizeOptions(Boolean(normalizedDtsOptions), {
1703
+ consumeAPITypes: true
1704
+ }, 'mfOptions.dts.consumeTypes')(normalizedDtsOptions.consumeTypes);
1705
+ var host = normalizedConsumeTypes === false ? undefined : _extends({
1706
+ implementation: normalizedDtsOptions.implementation,
1707
+ context: resolvedConfig.root,
1708
+ moduleFederationConfig: dtsModuleFederationConfig,
1709
+ typesFolder: normalizedConsumeTypes.typesFolder || '@mf-types',
1710
+ abortOnError: false
1711
+ }, normalizedConsumeTypes);
1712
+ var extraOptions = normalizedDtsOptions.extraOptions || {};
1713
+ if (!remote && !host && devOptions.disableLiveReload) {
1714
+ return;
1715
+ }
1716
+ var startDevWorker = function startDevWorker() {
1717
+ try {
1718
+ var _temp2 = function _temp2() {
1719
+ var _server$httpServer;
1720
+ devWorker = new DevWorker({
1721
+ name: options.name,
1722
+ remote: remote,
1723
+ host: host ? _extends({}, host, {
1724
+ remoteTypeUrls: remoteTypeUrls
1725
+ }) : undefined,
1726
+ extraOptions: extraOptions,
1727
+ disableLiveReload: devOptions.disableLiveReload,
1728
+ disableHotTypesReload: devOptions.disableHotTypesReload
1729
+ });
1730
+ var update = function update() {
1731
+ var _devWorker;
1732
+ return (_devWorker = devWorker) == null ? void 0 : _devWorker.update();
1733
+ };
1734
+ server.watcher.on('change', update);
1735
+ server.watcher.on('add', update);
1736
+ server.watcher.on('unlink', update);
1737
+ (_server$httpServer = server.httpServer) == null || _server$httpServer.once('close', function () {
1738
+ var _devWorker2;
1739
+ (_devWorker2 = devWorker) == null || _devWorker2.exit();
1740
+ server.watcher.off('change', update);
1741
+ server.watcher.off('add', update);
1742
+ server.watcher.off('unlink', update);
1743
+ });
1744
+ };
1745
+ var remoteTypeUrls;
1746
+ var _temp = function () {
1747
+ if (host) {
1748
+ return Promise.resolve(new Promise(function (resolve) {
1749
+ consumeTypesAPI({
1750
+ host: host,
1751
+ extraOptions: extraOptions,
1752
+ displayErrorInTerminal: normalizedDtsOptions.displayErrorInTerminal
1753
+ }, resolve);
1754
+ })).then(function (_Promise) {
1755
+ remoteTypeUrls = _Promise;
1756
+ });
1757
+ }
1758
+ }();
1759
+ return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
1760
+ } catch (e) {
1761
+ return Promise.reject(e);
1762
+ }
1763
+ };
1764
+ startDevWorker()["catch"](function (error) {
1765
+ logDtsError(error, normalizedDtsOptions);
1766
+ });
1767
+ }
1768
+ };
1769
+ var buildPlugin = {
1770
+ name: 'module-federation-dts-build',
1771
+ apply: 'build',
1772
+ configResolved: function configResolved(config) {
1773
+ resolvedConfig = config;
1774
+ },
1775
+ closeBundle: function closeBundle() {
1776
+ try {
1777
+ var _temp6 = function _temp6() {
1778
+ var generateOptions = normalizeGenerateTypesOptions({
1779
+ context: context,
1780
+ outputDir: outputDir,
1781
+ dtsOptions: normalizedDtsOptions,
1782
+ pluginOptions: dtsModuleFederationConfig
1783
+ });
1784
+ if (!generateOptions) {
1785
+ return;
1786
+ }
1787
+ var _temp4 = _catch(function () {
1788
+ return Promise.resolve(generateTypesAPI({
1789
+ dtsManagerOptions: generateOptions
1790
+ })).then(function () {});
1791
+ }, function (error) {
1792
+ logDtsError(error, normalizedDtsOptions);
1793
+ });
1794
+ if (_temp4 && _temp4.then) return _temp4.then(function () {});
1795
+ };
1796
+ if (!resolvedConfig) {
1797
+ return Promise.resolve();
1798
+ }
1799
+ var normalizedDtsOptions = normalizeDtsOptions(dtsModuleFederationConfig, resolvedConfig.root);
1800
+ if (typeof normalizedDtsOptions !== 'object') {
1801
+ return Promise.resolve();
1802
+ }
1803
+ var context = resolvedConfig.root;
1804
+ var outputDir = resolveOutputDir(resolvedConfig);
1805
+ var consumeOptions = normalizeConsumeTypesOptions({
1806
+ context: context,
1807
+ dtsOptions: normalizedDtsOptions,
1808
+ pluginOptions: dtsModuleFederationConfig
1809
+ });
1810
+ var _temp5 = function (_consumeOptions$host) {
1811
+ if (consumeOptions != null && (_consumeOptions$host = consumeOptions.host) != null && _consumeOptions$host.typesOnBuild) {
1812
+ var _temp3 = _catch(function () {
1813
+ return Promise.resolve(consumeTypesAPI(consumeOptions)).then(function () {});
1814
+ }, function (error) {
1815
+ logDtsError(error, normalizedDtsOptions);
1816
+ });
1817
+ if (_temp3 && _temp3.then) return _temp3.then(function () {});
1818
+ }
1819
+ }();
1820
+ return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
1821
+ } catch (e) {
1822
+ return Promise.reject(e);
1823
+ }
1824
+ }
1825
+ };
1826
+ return [devPlugin, buildPlugin];
1827
+ }
1828
+
1419
1829
  /**
1420
1830
  * example:
1421
1831
  * const store = new PromiseStore<number>();
@@ -1593,7 +2003,7 @@ function federation(mfUserOptions) {
1593
2003
  }
1594
2004
  }, aliasToArrayPlugin, checkAliasConflicts({
1595
2005
  shared: shared
1596
- }), normalizeOptimizeDepsPlugin].concat(addEntry({
2006
+ }), normalizeOptimizeDepsPlugin].concat(pluginDts(options), addEntry({
1597
2007
  entryName: 'remoteEntry',
1598
2008
  entryPath: REMOTE_ENTRY_ID,
1599
2009
  fileName: filename