DynamicEntryPlugin.js 2.5 KB

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