ContainerPlugin.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
  4. */
  5. "use strict";
  6. const createSchemaValidation = require("../util/create-schema-validation");
  7. const ContainerEntryDependency = require("./ContainerEntryDependency");
  8. const ContainerEntryModuleFactory = require("./ContainerEntryModuleFactory");
  9. const ContainerExposedDependency = require("./ContainerExposedDependency");
  10. const { parseOptions } = require("./options");
  11. /** @typedef {import("../../declarations/plugins/container/ContainerPlugin").ContainerPluginOptions} ContainerPluginOptions */
  12. /** @typedef {import("../Compiler")} Compiler */
  13. /** @typedef {import("./ContainerEntryModule").ExposeOptions} ExposeOptions */
  14. /** @typedef {import("./ContainerEntryModule").ExposesList} ExposesList */
  15. const validate = createSchemaValidation(
  16. require("../../schemas/plugins/container/ContainerPlugin.check.js"),
  17. () => require("../../schemas/plugins/container/ContainerPlugin.json"),
  18. {
  19. name: "Container Plugin",
  20. baseDataPath: "options"
  21. }
  22. );
  23. const PLUGIN_NAME = "ContainerPlugin";
  24. class ContainerPlugin {
  25. /**
  26. * @param {ContainerPluginOptions} options options
  27. */
  28. constructor(options) {
  29. validate(options);
  30. this._options = {
  31. name: options.name,
  32. shareScope: options.shareScope || "default",
  33. library: options.library || {
  34. type: "var",
  35. name: options.name
  36. },
  37. runtime: options.runtime,
  38. filename: options.filename || undefined,
  39. exposes: /** @type {ExposesList} */ (
  40. parseOptions(
  41. options.exposes,
  42. item => ({
  43. import: Array.isArray(item) ? item : [item],
  44. name: undefined
  45. }),
  46. item => ({
  47. import: Array.isArray(item.import) ? item.import : [item.import],
  48. name: item.name || undefined
  49. })
  50. )
  51. )
  52. };
  53. }
  54. /**
  55. * Apply the plugin
  56. * @param {Compiler} compiler the compiler instance
  57. * @returns {void}
  58. */
  59. apply(compiler) {
  60. const { name, exposes, shareScope, filename, library, runtime } =
  61. this._options;
  62. if (!compiler.options.output.enabledLibraryTypes.includes(library.type)) {
  63. compiler.options.output.enabledLibraryTypes.push(library.type);
  64. }
  65. compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
  66. const dep = new ContainerEntryDependency(name, exposes, shareScope);
  67. dep.loc = { name };
  68. compilation.addEntry(
  69. compilation.options.context,
  70. dep,
  71. {
  72. name,
  73. filename,
  74. runtime,
  75. library
  76. },
  77. error => {
  78. if (error) return callback(error);
  79. callback();
  80. }
  81. );
  82. });
  83. compiler.hooks.thisCompilation.tap(
  84. PLUGIN_NAME,
  85. (compilation, { normalModuleFactory }) => {
  86. compilation.dependencyFactories.set(
  87. ContainerEntryDependency,
  88. new ContainerEntryModuleFactory()
  89. );
  90. compilation.dependencyFactories.set(
  91. ContainerExposedDependency,
  92. normalModuleFactory
  93. );
  94. }
  95. );
  96. }
  97. }
  98. module.exports = ContainerPlugin;