@module-federation/rspack
Version:
301 lines (297 loc) • 14.8 kB
JavaScript
;
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;