DynamicEntryPlugin.js 2.6 KB

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