/*
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
Author Tobias Koppers @sokra
|
*/
|
|
"use strict";
|
|
const { ModuleExternalInitFragment } = require("./ExternalModule");
|
const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin");
|
const ConcatenatedModule = require("./optimize/ConcatenatedModule");
|
|
/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
|
/** @typedef {import("./Compiler")} Compiler */
|
/** @typedef {import("./optimize/ConcatenatedModule").ConcatenatedModuleInfo} ConcatenatedModuleInfo */
|
|
const PLUGIN_NAME = "ExternalsPlugin";
|
|
class ExternalsPlugin {
|
/**
|
* @param {string | undefined} type default external type
|
* @param {Externals} externals externals config
|
*/
|
constructor(type, externals) {
|
this.type = type;
|
this.externals = externals;
|
}
|
|
/**
|
* Apply the plugin
|
* @param {Compiler} compiler the compiler instance
|
* @returns {void}
|
*/
|
apply(compiler) {
|
compiler.hooks.compile.tap(PLUGIN_NAME, ({ normalModuleFactory }) => {
|
new ExternalModuleFactoryPlugin(this.type, this.externals).apply(
|
normalModuleFactory
|
);
|
});
|
|
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
const { concatenatedModuleInfo } =
|
ConcatenatedModule.getCompilationHooks(compilation);
|
concatenatedModuleInfo.tap(PLUGIN_NAME, (updatedInfo, moduleInfo) => {
|
const rawExportMap =
|
/** @type {ConcatenatedModuleInfo} */ updatedInfo.rawExportMap;
|
|
if (!rawExportMap) {
|
return;
|
}
|
|
const chunkInitFragments =
|
/** @type {ConcatenatedModuleInfo} */ moduleInfo.chunkInitFragments;
|
const moduleExternalInitFragments = chunkInitFragments
|
? chunkInitFragments.filter(
|
(fragment) => fragment instanceof ModuleExternalInitFragment
|
)
|
: [];
|
|
let initFragmentChanged = false;
|
|
for (const fragment of moduleExternalInitFragments) {
|
const imported = fragment.getImported();
|
|
if (Array.isArray(imported)) {
|
const newImported = imported.map(([specifier, finalName]) => [
|
specifier,
|
rawExportMap.has(specifier)
|
? rawExportMap.get(specifier)
|
: finalName
|
]);
|
fragment.setImported(newImported);
|
initFragmentChanged = true;
|
}
|
}
|
|
if (initFragmentChanged) {
|
return true;
|
}
|
});
|
});
|
}
|
}
|
|
module.exports = ExternalsPlugin;
|