EntryOptionPlugin.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { SyncBailHook } = require("tapable");
  7. /**
  8. * @import {
  9. * EntryDescriptionNormalized as EntryDescription,
  10. * EntryNormalized as Entry
  11. * } from "../declarations/WebpackOptions"
  12. */
  13. /** @import Compiler from "./Compiler" */
  14. /** @import { EntryOptions } from "./Entrypoint" */
  15. /**
  16. * @typedef {object} EntryOptionPluginHooks
  17. * @property {SyncBailHook<[string, string, EntryDescription], string | undefined>} entry transform an entry into a different request (e.g. wrap a non-HTML entry in a synthetic HTML module); return `undefined` to keep the default behavior
  18. */
  19. const PLUGIN_NAME = "EntryOptionPlugin";
  20. /** @type {WeakMap<Compiler, EntryOptionPluginHooks>} */
  21. const hooksMap = new WeakMap();
  22. class EntryOptionPlugin {
  23. /**
  24. * @param {Compiler} compiler the compiler
  25. * @returns {EntryOptionPluginHooks} the hooks
  26. */
  27. static getHooks(compiler) {
  28. let hooks = hooksMap.get(compiler);
  29. if (hooks === undefined) {
  30. hooks = {
  31. entry: new SyncBailHook(["context", "name", "entryDescription"])
  32. };
  33. hooksMap.set(compiler, hooks);
  34. }
  35. return hooks;
  36. }
  37. /**
  38. * Applies the plugin by registering its hooks on the compiler.
  39. * @param {Compiler} compiler the compiler instance one is tapping into
  40. * @returns {void}
  41. */
  42. apply(compiler) {
  43. compiler.hooks.entryOption.tap(PLUGIN_NAME, (context, entry) => {
  44. EntryOptionPlugin.applyEntryOption(compiler, context, entry);
  45. return true;
  46. });
  47. }
  48. /**
  49. * Apply entry option.
  50. * @param {Compiler} compiler the compiler
  51. * @param {string} context context directory
  52. * @param {Entry} entry request
  53. * @returns {void}
  54. */
  55. static applyEntryOption(compiler, context, entry) {
  56. if (typeof entry === "function") {
  57. const DynamicEntryPlugin = require("./DynamicEntryPlugin");
  58. new DynamicEntryPlugin(context, entry).apply(compiler);
  59. } else {
  60. const EntryPlugin = require("./EntryPlugin");
  61. for (const name of Object.keys(entry)) {
  62. const desc = entry[name];
  63. const options = EntryOptionPlugin.entryDescriptionToOptions(
  64. compiler,
  65. name,
  66. desc
  67. );
  68. const descImport =
  69. /** @type {Exclude<EntryDescription["import"], undefined>} */
  70. (desc.import);
  71. // A plugin (e.g. HtmlModulesPlugin) may rewrite the entry into a
  72. // single synthetic request; otherwise each import becomes an entry.
  73. const request = EntryOptionPlugin.getHooks(compiler).entry.call(
  74. context,
  75. name,
  76. desc
  77. );
  78. if (request !== undefined) {
  79. new EntryPlugin(context, request, options).apply(compiler);
  80. } else {
  81. for (const entry of descImport) {
  82. new EntryPlugin(context, entry, options).apply(compiler);
  83. }
  84. }
  85. }
  86. }
  87. }
  88. /**
  89. * Entry description to options.
  90. * @param {Compiler} compiler the compiler
  91. * @param {string} name entry name
  92. * @param {EntryDescription} desc entry description
  93. * @returns {EntryOptions} options for the entry
  94. */
  95. static entryDescriptionToOptions(compiler, name, desc) {
  96. /** @type {EntryOptions} */
  97. const options = {
  98. name,
  99. filename: desc.filename,
  100. runtime: desc.runtime,
  101. layer: desc.layer,
  102. dependOn: desc.dependOn,
  103. baseUri: desc.baseUri,
  104. publicPath: desc.publicPath,
  105. chunkLoading: desc.chunkLoading,
  106. asyncChunks: desc.asyncChunks,
  107. wasmLoading: desc.wasmLoading,
  108. worker: desc.worker,
  109. library: desc.library
  110. };
  111. if (desc.chunkLoading) {
  112. const EnableChunkLoadingPlugin = require("./javascript/EnableChunkLoadingPlugin");
  113. EnableChunkLoadingPlugin.checkEnabled(compiler, desc.chunkLoading);
  114. }
  115. if (desc.wasmLoading) {
  116. const EnableWasmLoadingPlugin = require("./wasm/EnableWasmLoadingPlugin");
  117. EnableWasmLoadingPlugin.checkEnabled(compiler, desc.wasmLoading);
  118. }
  119. if (desc.library) {
  120. const EnableLibraryPlugin = require("./library/EnableLibraryPlugin");
  121. EnableLibraryPlugin.checkEnabled(compiler, desc.library.type);
  122. }
  123. return options;
  124. }
  125. }
  126. module.exports = EntryOptionPlugin;