提交学习笔记专用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.3 KiB

  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { ModuleExternalInitFragment } = require("./ExternalModule");
  7. const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin");
  8. const ConcatenatedModule = require("./optimize/ConcatenatedModule");
  9. /** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
  10. /** @typedef {import("./Compiler")} Compiler */
  11. /** @typedef {import("./ExternalModule").Imported} Imported */
  12. const PLUGIN_NAME = "ExternalsPlugin";
  13. class ExternalsPlugin {
  14. /**
  15. * @param {string} type default external type
  16. * @param {Externals} externals externals config
  17. */
  18. constructor(type, externals) {
  19. this.type = type;
  20. this.externals = externals;
  21. }
  22. /**
  23. * Apply the plugin
  24. * @param {Compiler} compiler the compiler instance
  25. * @returns {void}
  26. */
  27. apply(compiler) {
  28. compiler.hooks.compile.tap(PLUGIN_NAME, ({ normalModuleFactory }) => {
  29. new ExternalModuleFactoryPlugin(this.type, this.externals).apply(
  30. normalModuleFactory
  31. );
  32. });
  33. compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
  34. const { concatenatedModuleInfo } =
  35. ConcatenatedModule.getCompilationHooks(compilation);
  36. concatenatedModuleInfo.tap(PLUGIN_NAME, (updatedInfo, moduleInfo) => {
  37. const rawExportMap = updatedInfo.rawExportMap;
  38. if (!rawExportMap) {
  39. return;
  40. }
  41. const chunkInitFragments = moduleInfo.chunkInitFragments;
  42. const moduleExternalInitFragments =
  43. /** @type {ModuleExternalInitFragment[]} */
  44. (
  45. chunkInitFragments
  46. ? /** @type {unknown[]} */
  47. (chunkInitFragments).filter(
  48. (fragment) => fragment instanceof ModuleExternalInitFragment
  49. )
  50. : []
  51. );
  52. let initFragmentChanged = false;
  53. for (const fragment of moduleExternalInitFragments) {
  54. const imported = fragment.getImported();
  55. if (Array.isArray(imported)) {
  56. const newImported =
  57. /** @type {Imported} */
  58. (
  59. imported.map(([specifier, finalName]) => [
  60. specifier,
  61. rawExportMap.has(specifier)
  62. ? rawExportMap.get(specifier)
  63. : finalName
  64. ])
  65. );
  66. fragment.setImported(newImported);
  67. initFragmentChanged = true;
  68. }
  69. }
  70. if (initFragmentChanged) {
  71. return true;
  72. }
  73. });
  74. });
  75. }
  76. }
  77. module.exports = ExternalsPlugin;