ModuleFederationPlugin.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
  4. */
  5. "use strict";
  6. const isValidExternalsType = require("../../schemas/plugins/container/ExternalsType.check");
  7. const SharePlugin = require("../sharing/SharePlugin");
  8. const ContainerPlugin = require("./ContainerPlugin");
  9. const ContainerReferencePlugin = require("./ContainerReferencePlugin");
  10. const HoistContainerReferences = require("./HoistContainerReferencesPlugin");
  11. const getCompilationHooks = require("./moduleFederationHooks");
  12. /**
  13. * @import {
  14. * ExternalsType,
  15. * ModuleFederationPluginOptions
  16. * } from "../../declarations/plugins/container/ModuleFederationPlugin"
  17. */
  18. /** @import Compiler from "../Compiler" */
  19. const PLUGIN_NAME = "ModuleFederationPlugin";
  20. class ModuleFederationPlugin {
  21. /**
  22. * Creates an instance of ModuleFederationPlugin.
  23. * @param {ModuleFederationPluginOptions} options options
  24. */
  25. constructor(options) {
  26. /** @type {ModuleFederationPluginOptions} */
  27. this.options = options;
  28. }
  29. /**
  30. * Applies the plugin by registering its hooks on the compiler.
  31. * @param {Compiler} compiler the compiler instance
  32. * @returns {void}
  33. */
  34. apply(compiler) {
  35. compiler.hooks.validate.tap(PLUGIN_NAME, () => {
  36. compiler.validate(
  37. () =>
  38. require("../../schemas/plugins/container/ModuleFederationPlugin.json"),
  39. this.options,
  40. {
  41. name: "Module Federation Plugin",
  42. baseDataPath: "options"
  43. },
  44. (options) =>
  45. require("../../schemas/plugins/container/ModuleFederationPlugin.check")(
  46. options
  47. )
  48. );
  49. });
  50. const { options } = this;
  51. const library = options.library || { type: "var", name: options.name };
  52. const remoteType =
  53. options.remoteType ||
  54. (options.library && isValidExternalsType(options.library.type)
  55. ? /** @type {ExternalsType} */ (options.library.type)
  56. : "script");
  57. if (
  58. library &&
  59. !compiler.options.output.enabledLibraryTypes.includes(library.type)
  60. ) {
  61. compiler.options.output.enabledLibraryTypes.push(library.type);
  62. }
  63. compiler.hooks.afterPlugins.tap(PLUGIN_NAME, () => {
  64. if (
  65. options.exposes &&
  66. (Array.isArray(options.exposes)
  67. ? options.exposes.length > 0
  68. : Object.keys(options.exposes).length > 0)
  69. ) {
  70. new ContainerPlugin({
  71. name: /** @type {string} */ (options.name),
  72. library,
  73. filename: options.filename,
  74. runtime: options.runtime,
  75. shareScope: options.shareScope,
  76. exposes: options.exposes
  77. }).apply(compiler);
  78. }
  79. if (
  80. options.remotes &&
  81. (Array.isArray(options.remotes)
  82. ? options.remotes.length > 0
  83. : Object.keys(options.remotes).length > 0)
  84. ) {
  85. new ContainerReferencePlugin({
  86. remoteType,
  87. shareScope: options.shareScope,
  88. remotes: options.remotes
  89. }).apply(compiler);
  90. }
  91. if (options.shared) {
  92. new SharePlugin({
  93. shared: options.shared,
  94. shareScope: options.shareScope
  95. }).apply(compiler);
  96. }
  97. new HoistContainerReferences().apply(compiler);
  98. });
  99. }
  100. }
  101. ModuleFederationPlugin.getCompilationHooks = getCompilationHooks;
  102. module.exports = ModuleFederationPlugin;