UNPKG

@module-federation/rspack

Version:
301 lines (297 loc) 14.8 kB
'use strict'; var sdk = require('@module-federation/sdk'); var manifest = require('@module-federation/manifest'); var managers = require('@module-federation/managers'); var dtsPlugin = require('@module-federation/dts-plugin'); var ReactBridgePlugin = require('@module-federation/bridge-react-webpack-plugin'); var path = require('node:path'); var fs = require('node:fs'); var remoteEntryPlugin = require('./remote-entry-plugin.cjs.js'); function _class_call_check(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for(var i = 0; i < props.length; i++){ var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _create_class(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); return Constructor; } function _define_property(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } function _object_spread(target) { for(var i = 1; i < arguments.length; i++){ var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _define_property(target, key, source[key]); }); } return target; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); keys.push.apply(keys, symbols); } return keys; } function _object_spread_props(target, source) { source = source != null ? source : {}; if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function(key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _type_of(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } var RuntimeToolsPath = require.resolve('@module-federation/runtime-tools'); var PLUGIN_NAME = 'RspackModuleFederationPlugin'; var ModuleFederationPlugin = /*#__PURE__*/ function() { function ModuleFederationPlugin(options) { _class_call_check(this, ModuleFederationPlugin); this.name = PLUGIN_NAME; this._options = options; } _create_class(ModuleFederationPlugin, [ { key: "_patchBundlerConfig", value: function _patchBundlerConfig(compiler) { var _experiments_optimization; var _this__options = this._options, name = _this__options.name, experiments = _this__options.experiments; var definePluginOptions = {}; if (name) { definePluginOptions['FEDERATION_BUILD_IDENTIFIER'] = JSON.stringify(sdk.composeKeyWithSeparator(name, managers.utils.getBuildVersion())); } var _experiments_optimization_disableSnapshot; // Add FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN var disableSnapshot = (_experiments_optimization_disableSnapshot = experiments === null || experiments === void 0 ? void 0 : (_experiments_optimization = experiments.optimization) === null || _experiments_optimization === void 0 ? void 0 : _experiments_optimization.disableSnapshot) !== null && _experiments_optimization_disableSnapshot !== void 0 ? _experiments_optimization_disableSnapshot : false; definePluginOptions['FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN'] = disableSnapshot; // Determine ENV_TARGET: only if manually specified in experiments.optimization.target if ((experiments === null || experiments === void 0 ? void 0 : experiments.optimization) && _type_of(experiments.optimization) === 'object' && experiments.optimization !== null && 'target' in experiments.optimization) { var manualTarget = experiments.optimization.target; // Ensure the target is one of the expected values before setting if (manualTarget === 'web' || manualTarget === 'node') { definePluginOptions['ENV_TARGET'] = JSON.stringify(manualTarget); } } // No inference for ENV_TARGET. If not manually set and valid, it's not defined. new compiler.webpack.DefinePlugin(definePluginOptions).apply(compiler); } }, { key: "_checkSingleton", value: function _checkSingleton(compiler) { var _this = this; var count = 0; compiler.options.plugins.forEach(function(p) { if ((typeof p === "undefined" ? "undefined" : _type_of(p)) !== 'object' || !p) { return; } if (p['name'] === _this.name) { count++; if (count > 1) { throw new Error("Detect duplicate register ".concat(_this.name, ",please ensure ").concat(_this.name, " is singleton!")); } } }); } }, { key: "apply", value: function apply(compiler) { var _options_experiments, _options_experiments1; var _this = this, options = _this._options; if (!options.name) { throw new Error('[ ModuleFederationPlugin ]: name is required'); } this._checkSingleton(compiler); this._patchBundlerConfig(compiler); var containerManager = new managers.ContainerManager(); containerManager.init(options); if (containerManager.enable) { this._patchChunkSplit(compiler, options.name); } // must before ModuleFederationPlugin new remoteEntryPlugin.RemoteEntryPlugin(options).apply(compiler); if ((_options_experiments = options.experiments) === null || _options_experiments === void 0 ? void 0 : _options_experiments.provideExternalRuntime) { if (options.exposes) { throw new Error('You can only set provideExternalRuntime: true in pure consumer which not expose modules.'); } var runtimePlugins = options.runtimePlugins || []; options.runtimePlugins = runtimePlugins.concat(require.resolve('@module-federation/inject-external-runtime-core-plugin')); } if (((_options_experiments1 = options.experiments) === null || _options_experiments1 === void 0 ? void 0 : _options_experiments1.externalRuntime) === true) { var Externals = compiler.webpack.ExternalsPlugin; new Externals(compiler.options.externalsType || 'global', { '@module-federation/runtime-core': '_FEDERATION_RUNTIME_CORE' }).apply(compiler); } options.implementation = options.implementation || RuntimeToolsPath; var disableManifest = options.manifest === false; var disableDts = options.dts === false; if (!disableDts) { var dtsPlugin$1 = new dtsPlugin.DtsPlugin(options); // @ts-ignore dtsPlugin$1.apply(compiler); dtsPlugin$1.addRuntimePlugins(); } if (!disableManifest && options.exposes) { try { options.exposes = containerManager.containerPluginExposesOptions; } catch (err) { if (_instanceof(err, Error)) { err.message = "[ ModuleFederationPlugin ]: Manifest will not generate, because: ".concat(err.message); } console.warn(err); disableManifest = true; } } new compiler.webpack.container.ModuleFederationPlugin(options).apply(compiler); var runtimeESMPath = require.resolve('@module-federation/runtime/dist/index.esm.js', { paths: [ options.implementation ] }); compiler.hooks.afterPlugins.tap('PatchAliasWebpackPlugin', function() { compiler.options.resolve.alias = _object_spread_props(_object_spread({}, compiler.options.resolve.alias), { '@module-federation/runtime$': runtimeESMPath }); }); if (!disableManifest) { this._statsPlugin = new manifest.StatsPlugin(options, { pluginVersion: "0.17.1", bundler: 'rspack' }); // @ts-ignore this._statsPlugin.apply(compiler); } // react bridge plugin var nodeModulesPath = path.resolve(compiler.context, 'node_modules'); var reactPath = path.join(nodeModulesPath, '@module-federation/bridge-react'); // Check whether react exists if (fs.existsSync(reactPath) && (!(options === null || options === void 0 ? void 0 : options.bridge) || !options.bridge.disableAlias)) { new ReactBridgePlugin({ moduleFederationOptions: this._options }).apply(compiler); } } }, { key: "_patchChunkSplit", value: function _patchChunkSplit(compiler, name) { var splitChunks = compiler.options.optimization.splitChunks; var patchChunkSplit = function(cacheGroup) { switch(typeof cacheGroup === "undefined" ? "undefined" : _type_of(cacheGroup)){ case 'boolean': case 'string': case 'function': break; // cacheGroup.chunks will inherit splitChunks.chunks, so you only need to modify the chunks that are set separately case 'object': { if (_instanceof(cacheGroup, RegExp)) { break; } if (!cacheGroup.chunks) { break; } if (typeof cacheGroup.chunks === 'function') { var prevChunks = cacheGroup.chunks; cacheGroup.chunks = function(chunk) { if (chunk.name && (chunk.name === name || chunk.name === name + '_partial')) { return false; } return prevChunks(chunk); }; break; } if (cacheGroup.chunks === 'all') { cacheGroup.chunks = function(chunk) { if (chunk.name && (chunk.name === name || chunk.name === name + '_partial')) { return false; } return true; }; break; } if (cacheGroup.chunks === 'initial') { cacheGroup.chunks = function(chunk) { if (chunk.name && (chunk.name === name || chunk.name === name + '_partial')) { return false; } return chunk.isOnlyInitial(); }; break; } break; } } }; if (!splitChunks) { return; } // 修改 splitChunk.chunks patchChunkSplit(splitChunks); var cacheGroups = splitChunks.cacheGroups; if (!cacheGroups) { return; } // 修改 splitChunk.cacheGroups[key].chunks Object.keys(cacheGroups).forEach(function(cacheGroupKey) { patchChunkSplit(cacheGroups[cacheGroupKey]); }); } }, { key: "statsResourceInfo", get: function get() { var _this__statsPlugin; return (_this__statsPlugin = this._statsPlugin) === null || _this__statsPlugin === void 0 ? void 0 : _this__statsPlugin.resourceInfo; } } ]); return ModuleFederationPlugin; }(); var GetPublicPathPlugin = remoteEntryPlugin.RemoteEntryPlugin; exports.GetPublicPathPlugin = GetPublicPathPlugin; exports.ModuleFederationPlugin = ModuleFederationPlugin; exports.PLUGIN_NAME = PLUGIN_NAME;