DynamicEntryPlugin.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Naoyuki Kanezawa @nkzawa
  4. */
  5. "use strict";
  6. const EntryOptionPlugin = require("./EntryOptionPlugin");
  7. const EntryPlugin = require("./EntryPlugin");
  8. const EntryDependency = require("./dependencies/EntryDependency");
  9. /**
  10. * @import {
  11. * EntryDescriptionNormalized,
  12. * EntryStatic,
  13. * EntryStaticNormalized
  14. * } from "../declarations/WebpackOptions"
  15. */
  16. /** @import Compiler from "./Compiler" */
  17. const PLUGIN_NAME = "DynamicEntryPlugin";
  18. /** @typedef {() => EntryStatic | Promise<EntryStatic>} RawEntryDynamic */
  19. /** @typedef {() => Promise<EntryStaticNormalized>} EntryDynamic */
  20. class DynamicEntryPlugin {
  21. /**
  22. * Creates an instance of DynamicEntryPlugin.
  23. * @param {string} context the context path
  24. * @param {EntryDynamic} entry the entry value
  25. */
  26. constructor(context, entry) {
  27. /** @type {string} */
  28. this.context = context;
  29. /** @type {EntryDynamic} */
  30. this.entry = entry;
  31. }
  32. /**
  33. * Applies the plugin by registering its hooks on the compiler.
  34. * @param {Compiler} compiler the compiler instance
  35. * @returns {void}
  36. */
  37. apply(compiler) {
  38. compiler.hooks.compilation.tap(
  39. PLUGIN_NAME,
  40. (compilation, { normalModuleFactory }) => {
  41. compilation.dependencyFactories.set(
  42. EntryDependency,
  43. normalModuleFactory
  44. );
  45. }
  46. );
  47. compiler.hooks.make.tapPromise(PLUGIN_NAME, (compilation) =>
  48. Promise.resolve(this.entry())
  49. .then((entry) => {
  50. /** @type {Promise<void>[]} */
  51. const promises = [];
  52. for (const name of Object.keys(entry)) {
  53. const desc = entry[name];
  54. const options = EntryOptionPlugin.entryDescriptionToOptions(
  55. compiler,
  56. name,
  57. desc
  58. );
  59. for (const entry of /** @type {NonNullable<EntryDescriptionNormalized["import"]>} */ (
  60. desc.import
  61. )) {
  62. promises.push(
  63. new Promise(
  64. /**
  65. * Handles the callback logic for this hook.
  66. * @param {(value?: undefined) => void} resolve resolve
  67. * @param {(reason?: Error) => void} reject reject
  68. */
  69. (resolve, reject) => {
  70. compilation.addEntry(
  71. this.context,
  72. EntryPlugin.createDependency(entry, options),
  73. options,
  74. (err) => {
  75. if (err) return reject(err);
  76. resolve();
  77. }
  78. );
  79. }
  80. )
  81. );
  82. }
  83. }
  84. return Promise.all(promises);
  85. })
  86. .then(() => {})
  87. );
  88. }
  89. }
  90. module.exports = DynamicEntryPlugin;