WebpackOptionsApply.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const OptionsApply = require("./OptionsApply");
  7. const AssetModulesPlugin = require("./asset/AssetModulesPlugin");
  8. const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
  9. const JsonModulesPlugin = require("./json/JsonModulesPlugin");
  10. const ChunkPrefetchPreloadPlugin = require("./prefetch/ChunkPrefetchPreloadPlugin");
  11. const EntryOptionPlugin = require("./EntryOptionPlugin");
  12. const RecordIdsPlugin = require("./RecordIdsPlugin");
  13. const RuntimePlugin = require("./RuntimePlugin");
  14. const APIPlugin = require("./APIPlugin");
  15. const CompatibilityPlugin = require("./CompatibilityPlugin");
  16. const ConstPlugin = require("./ConstPlugin");
  17. const ExportsInfoApiPlugin = require("./ExportsInfoApiPlugin");
  18. const WebpackIsIncludedPlugin = require("./WebpackIsIncludedPlugin");
  19. const TemplatedPathPlugin = require("./TemplatedPathPlugin");
  20. const UseStrictPlugin = require("./UseStrictPlugin");
  21. const WarnCaseSensitiveModulesPlugin = require("./WarnCaseSensitiveModulesPlugin");
  22. const DataUriPlugin = require("./schemes/DataUriPlugin");
  23. const FileUriPlugin = require("./schemes/FileUriPlugin");
  24. const ResolverCachePlugin = require("./cache/ResolverCachePlugin");
  25. const CommonJsPlugin = require("./dependencies/CommonJsPlugin");
  26. const HarmonyModulesPlugin = require("./dependencies/HarmonyModulesPlugin");
  27. const ImportMetaContextPlugin = require("./dependencies/ImportMetaContextPlugin");
  28. const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin");
  29. const ImportPlugin = require("./dependencies/ImportPlugin");
  30. const LoaderPlugin = require("./dependencies/LoaderPlugin");
  31. const RequireContextPlugin = require("./dependencies/RequireContextPlugin");
  32. const RequireEnsurePlugin = require("./dependencies/RequireEnsurePlugin");
  33. const RequireIncludePlugin = require("./dependencies/RequireIncludePlugin");
  34. const SystemPlugin = require("./dependencies/SystemPlugin");
  35. const URLPlugin = require("./dependencies/URLPlugin");
  36. const WorkerPlugin = require("./dependencies/WorkerPlugin");
  37. const InferAsyncModulesPlugin = require("./async-modules/InferAsyncModulesPlugin");
  38. const JavascriptMetaInfoPlugin = require("./JavascriptMetaInfoPlugin");
  39. const DefaultStatsFactoryPlugin = require("./stats/DefaultStatsFactoryPlugin");
  40. const DefaultStatsPresetPlugin = require("./stats/DefaultStatsPresetPlugin");
  41. const DefaultStatsPrinterPlugin = require("./stats/DefaultStatsPrinterPlugin");
  42. const { cleverMerge } = require("./util/cleverMerge");
  43. /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
  44. /** @typedef {import("./Compiler")} Compiler */
  45. class WebpackOptionsApply extends OptionsApply {
  46. constructor() {
  47. super();
  48. }
  49. /**
  50. * @param {WebpackOptions} options options object
  51. * @param {Compiler} compiler compiler object
  52. * @returns {WebpackOptions} options object
  53. */
  54. process(options, compiler) {
  55. compiler.outputPath = options.output.path;
  56. compiler.recordsInputPath = options.recordsInputPath || null;
  57. compiler.recordsOutputPath = options.recordsOutputPath || null;
  58. compiler.name = options.name;
  59. if (options.externals) {
  60. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  61. const ExternalsPlugin = require("./ExternalsPlugin");
  62. new ExternalsPlugin(options.externalsType, options.externals).apply(
  63. compiler
  64. );
  65. }
  66. if (options.externalsPresets.node) {
  67. const NodeTargetPlugin = require("./node/NodeTargetPlugin");
  68. new NodeTargetPlugin().apply(compiler);
  69. }
  70. if (options.externalsPresets.electronMain) {
  71. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  72. const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
  73. new ElectronTargetPlugin("main").apply(compiler);
  74. }
  75. if (options.externalsPresets.electronPreload) {
  76. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  77. const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
  78. new ElectronTargetPlugin("preload").apply(compiler);
  79. }
  80. if (options.externalsPresets.electronRenderer) {
  81. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  82. const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
  83. new ElectronTargetPlugin("renderer").apply(compiler);
  84. }
  85. if (
  86. options.externalsPresets.electron &&
  87. !options.externalsPresets.electronMain &&
  88. !options.externalsPresets.electronPreload &&
  89. !options.externalsPresets.electronRenderer
  90. ) {
  91. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  92. const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
  93. new ElectronTargetPlugin().apply(compiler);
  94. }
  95. if (options.externalsPresets.nwjs) {
  96. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  97. const ExternalsPlugin = require("./ExternalsPlugin");
  98. new ExternalsPlugin("node-commonjs", "nw.gui").apply(compiler);
  99. }
  100. if (options.externalsPresets.webAsync) {
  101. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  102. const ExternalsPlugin = require("./ExternalsPlugin");
  103. new ExternalsPlugin("import", ({ request, dependencyType }, callback) => {
  104. if (dependencyType === "url") {
  105. if (/^(\/\/|https?:\/\/|#)/.test(request))
  106. return callback(null, `asset ${request}`);
  107. } else if (options.experiments.css && dependencyType === "css-import") {
  108. if (/^(\/\/|https?:\/\/|#)/.test(request))
  109. return callback(null, `css-import ${request}`);
  110. } else if (
  111. options.experiments.css &&
  112. /^(\/\/|https?:\/\/|std:)/.test(request)
  113. ) {
  114. if (/^\.css(\?|$)/.test(request))
  115. return callback(null, `css-import ${request}`);
  116. return callback(null, `import ${request}`);
  117. }
  118. callback();
  119. }).apply(compiler);
  120. } else if (options.externalsPresets.web) {
  121. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  122. const ExternalsPlugin = require("./ExternalsPlugin");
  123. new ExternalsPlugin("module", ({ request, dependencyType }, callback) => {
  124. if (dependencyType === "url") {
  125. if (/^(\/\/|https?:\/\/|#)/.test(request))
  126. return callback(null, `asset ${request}`);
  127. } else if (options.experiments.css && dependencyType === "css-import") {
  128. if (/^(\/\/|https?:\/\/|#)/.test(request))
  129. return callback(null, `css-import ${request}`);
  130. } else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
  131. if (options.experiments.css && /^\.css((\?)|$)/.test(request))
  132. return callback(null, `css-import ${request}`);
  133. return callback(null, `module ${request}`);
  134. }
  135. callback();
  136. }).apply(compiler);
  137. } else if (options.externalsPresets.node) {
  138. if (options.experiments.css) {
  139. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  140. const ExternalsPlugin = require("./ExternalsPlugin");
  141. new ExternalsPlugin(
  142. "module",
  143. ({ request, dependencyType }, callback) => {
  144. if (dependencyType === "url") {
  145. if (/^(\/\/|https?:\/\/|#)/.test(request))
  146. return callback(null, `asset ${request}`);
  147. } else if (dependencyType === "css-import") {
  148. if (/^(\/\/|https?:\/\/|#)/.test(request))
  149. return callback(null, `css-import ${request}`);
  150. } else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
  151. if (/^\.css(\?|$)/.test(request))
  152. return callback(null, `css-import ${request}`);
  153. return callback(null, `module ${request}`);
  154. }
  155. callback();
  156. }
  157. ).apply(compiler);
  158. }
  159. }
  160. new ChunkPrefetchPreloadPlugin().apply(compiler);
  161. if (typeof options.output.chunkFormat === "string") {
  162. switch (options.output.chunkFormat) {
  163. case "array-push": {
  164. const ArrayPushCallbackChunkFormatPlugin = require("./javascript/ArrayPushCallbackChunkFormatPlugin");
  165. new ArrayPushCallbackChunkFormatPlugin().apply(compiler);
  166. break;
  167. }
  168. case "commonjs": {
  169. const CommonJsChunkFormatPlugin = require("./javascript/CommonJsChunkFormatPlugin");
  170. new CommonJsChunkFormatPlugin().apply(compiler);
  171. break;
  172. }
  173. case "module": {
  174. const ModuleChunkFormatPlugin = require("./esm/ModuleChunkFormatPlugin");
  175. new ModuleChunkFormatPlugin().apply(compiler);
  176. break;
  177. }
  178. default:
  179. throw new Error(
  180. "Unsupported chunk format '" + options.output.chunkFormat + "'."
  181. );
  182. }
  183. }
  184. if (options.output.enabledChunkLoadingTypes.length > 0) {
  185. for (const type of options.output.enabledChunkLoadingTypes) {
  186. const EnableChunkLoadingPlugin = require("./javascript/EnableChunkLoadingPlugin");
  187. new EnableChunkLoadingPlugin(type).apply(compiler);
  188. }
  189. }
  190. if (options.output.enabledWasmLoadingTypes.length > 0) {
  191. for (const type of options.output.enabledWasmLoadingTypes) {
  192. const EnableWasmLoadingPlugin = require("./wasm/EnableWasmLoadingPlugin");
  193. new EnableWasmLoadingPlugin(type).apply(compiler);
  194. }
  195. }
  196. if (options.output.enabledLibraryTypes.length > 0) {
  197. for (const type of options.output.enabledLibraryTypes) {
  198. const EnableLibraryPlugin = require("./library/EnableLibraryPlugin");
  199. new EnableLibraryPlugin(type).apply(compiler);
  200. }
  201. }
  202. if (options.output.pathinfo) {
  203. const ModuleInfoHeaderPlugin = require("./ModuleInfoHeaderPlugin");
  204. new ModuleInfoHeaderPlugin(options.output.pathinfo !== true).apply(
  205. compiler
  206. );
  207. }
  208. if (options.output.clean) {
  209. const CleanPlugin = require("./CleanPlugin");
  210. new CleanPlugin(
  211. options.output.clean === true ? {} : options.output.clean
  212. ).apply(compiler);
  213. }
  214. if (options.devtool) {
  215. if (options.devtool.includes("source-map")) {
  216. const hidden = options.devtool.includes("hidden");
  217. const inline = options.devtool.includes("inline");
  218. const evalWrapped = options.devtool.includes("eval");
  219. const cheap = options.devtool.includes("cheap");
  220. const moduleMaps = options.devtool.includes("module");
  221. const noSources = options.devtool.includes("nosources");
  222. const Plugin = evalWrapped
  223. ? require("./EvalSourceMapDevToolPlugin")
  224. : require("./SourceMapDevToolPlugin");
  225. new Plugin({
  226. filename: inline ? null : options.output.sourceMapFilename,
  227. moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
  228. fallbackModuleFilenameTemplate:
  229. options.output.devtoolFallbackModuleFilenameTemplate,
  230. append: hidden ? false : undefined,
  231. module: moduleMaps ? true : cheap ? false : true,
  232. columns: cheap ? false : true,
  233. noSources: noSources,
  234. namespace: options.output.devtoolNamespace
  235. }).apply(compiler);
  236. } else if (options.devtool.includes("eval")) {
  237. const EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
  238. new EvalDevToolModulePlugin({
  239. moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
  240. namespace: options.output.devtoolNamespace
  241. }).apply(compiler);
  242. }
  243. }
  244. new JavascriptModulesPlugin().apply(compiler);
  245. new JsonModulesPlugin().apply(compiler);
  246. new AssetModulesPlugin().apply(compiler);
  247. if (!options.experiments.outputModule) {
  248. if (options.output.module) {
  249. throw new Error(
  250. "'output.module: true' is only allowed when 'experiments.outputModule' is enabled"
  251. );
  252. }
  253. if (options.output.enabledLibraryTypes.includes("module")) {
  254. throw new Error(
  255. "library type \"module\" is only allowed when 'experiments.outputModule' is enabled"
  256. );
  257. }
  258. if (options.externalsType === "module") {
  259. throw new Error(
  260. "'externalsType: \"module\"' is only allowed when 'experiments.outputModule' is enabled"
  261. );
  262. }
  263. }
  264. if (options.experiments.syncWebAssembly) {
  265. const WebAssemblyModulesPlugin = require("./wasm-sync/WebAssemblyModulesPlugin");
  266. new WebAssemblyModulesPlugin({
  267. mangleImports: options.optimization.mangleWasmImports
  268. }).apply(compiler);
  269. }
  270. if (options.experiments.asyncWebAssembly) {
  271. const AsyncWebAssemblyModulesPlugin = require("./wasm-async/AsyncWebAssemblyModulesPlugin");
  272. new AsyncWebAssemblyModulesPlugin({
  273. mangleImports: options.optimization.mangleWasmImports
  274. }).apply(compiler);
  275. }
  276. if (options.experiments.css) {
  277. const CssModulesPlugin = require("./css/CssModulesPlugin");
  278. new CssModulesPlugin(options.experiments.css).apply(compiler);
  279. }
  280. if (options.experiments.lazyCompilation) {
  281. const LazyCompilationPlugin = require("./hmr/LazyCompilationPlugin");
  282. const lazyOptions =
  283. typeof options.experiments.lazyCompilation === "object"
  284. ? options.experiments.lazyCompilation
  285. : null;
  286. new LazyCompilationPlugin({
  287. backend:
  288. typeof lazyOptions.backend === "function"
  289. ? lazyOptions.backend
  290. : require("./hmr/lazyCompilationBackend")({
  291. ...lazyOptions.backend,
  292. client:
  293. (lazyOptions.backend && lazyOptions.backend.client) ||
  294. require.resolve(
  295. `../hot/lazy-compilation-${
  296. options.externalsPresets.node ? "node" : "web"
  297. }.js`
  298. )
  299. }),
  300. entries: !lazyOptions || lazyOptions.entries !== false,
  301. imports: !lazyOptions || lazyOptions.imports !== false,
  302. test: (lazyOptions && lazyOptions.test) || undefined
  303. }).apply(compiler);
  304. }
  305. if (options.experiments.buildHttp) {
  306. const HttpUriPlugin = require("./schemes/HttpUriPlugin");
  307. const httpOptions = options.experiments.buildHttp;
  308. new HttpUriPlugin(httpOptions).apply(compiler);
  309. }
  310. new EntryOptionPlugin().apply(compiler);
  311. compiler.hooks.entryOption.call(options.context, options.entry);
  312. new RuntimePlugin().apply(compiler);
  313. new InferAsyncModulesPlugin().apply(compiler);
  314. new DataUriPlugin().apply(compiler);
  315. new FileUriPlugin().apply(compiler);
  316. new CompatibilityPlugin().apply(compiler);
  317. new HarmonyModulesPlugin({
  318. topLevelAwait: options.experiments.topLevelAwait
  319. }).apply(compiler);
  320. if (options.amd !== false) {
  321. const AMDPlugin = require("./dependencies/AMDPlugin");
  322. const RequireJsStuffPlugin = require("./RequireJsStuffPlugin");
  323. new AMDPlugin(options.amd || {}).apply(compiler);
  324. new RequireJsStuffPlugin().apply(compiler);
  325. }
  326. new CommonJsPlugin().apply(compiler);
  327. new LoaderPlugin({}).apply(compiler);
  328. if (options.node !== false) {
  329. const NodeStuffPlugin = require("./NodeStuffPlugin");
  330. new NodeStuffPlugin(options.node).apply(compiler);
  331. }
  332. new APIPlugin({
  333. module: options.output.module
  334. }).apply(compiler);
  335. new ExportsInfoApiPlugin().apply(compiler);
  336. new WebpackIsIncludedPlugin().apply(compiler);
  337. new ConstPlugin().apply(compiler);
  338. new UseStrictPlugin().apply(compiler);
  339. new RequireIncludePlugin().apply(compiler);
  340. new RequireEnsurePlugin().apply(compiler);
  341. new RequireContextPlugin().apply(compiler);
  342. new ImportPlugin().apply(compiler);
  343. new ImportMetaContextPlugin().apply(compiler);
  344. new SystemPlugin().apply(compiler);
  345. new ImportMetaPlugin().apply(compiler);
  346. new URLPlugin().apply(compiler);
  347. new WorkerPlugin(
  348. options.output.workerChunkLoading,
  349. options.output.workerWasmLoading,
  350. options.output.module,
  351. options.output.workerPublicPath
  352. ).apply(compiler);
  353. new DefaultStatsFactoryPlugin().apply(compiler);
  354. new DefaultStatsPresetPlugin().apply(compiler);
  355. new DefaultStatsPrinterPlugin().apply(compiler);
  356. new JavascriptMetaInfoPlugin().apply(compiler);
  357. if (typeof options.mode !== "string") {
  358. const WarnNoModeSetPlugin = require("./WarnNoModeSetPlugin");
  359. new WarnNoModeSetPlugin().apply(compiler);
  360. }
  361. const EnsureChunkConditionsPlugin = require("./optimize/EnsureChunkConditionsPlugin");
  362. new EnsureChunkConditionsPlugin().apply(compiler);
  363. if (options.optimization.removeAvailableModules) {
  364. const RemoveParentModulesPlugin = require("./optimize/RemoveParentModulesPlugin");
  365. new RemoveParentModulesPlugin().apply(compiler);
  366. }
  367. if (options.optimization.removeEmptyChunks) {
  368. const RemoveEmptyChunksPlugin = require("./optimize/RemoveEmptyChunksPlugin");
  369. new RemoveEmptyChunksPlugin().apply(compiler);
  370. }
  371. if (options.optimization.mergeDuplicateChunks) {
  372. const MergeDuplicateChunksPlugin = require("./optimize/MergeDuplicateChunksPlugin");
  373. new MergeDuplicateChunksPlugin().apply(compiler);
  374. }
  375. if (options.optimization.flagIncludedChunks) {
  376. const FlagIncludedChunksPlugin = require("./optimize/FlagIncludedChunksPlugin");
  377. new FlagIncludedChunksPlugin().apply(compiler);
  378. }
  379. if (options.optimization.sideEffects) {
  380. const SideEffectsFlagPlugin = require("./optimize/SideEffectsFlagPlugin");
  381. new SideEffectsFlagPlugin(
  382. options.optimization.sideEffects === true
  383. ).apply(compiler);
  384. }
  385. if (options.optimization.providedExports) {
  386. const FlagDependencyExportsPlugin = require("./FlagDependencyExportsPlugin");
  387. new FlagDependencyExportsPlugin().apply(compiler);
  388. }
  389. if (options.optimization.usedExports) {
  390. const FlagDependencyUsagePlugin = require("./FlagDependencyUsagePlugin");
  391. new FlagDependencyUsagePlugin(
  392. options.optimization.usedExports === "global"
  393. ).apply(compiler);
  394. }
  395. if (options.optimization.innerGraph) {
  396. const InnerGraphPlugin = require("./optimize/InnerGraphPlugin");
  397. new InnerGraphPlugin().apply(compiler);
  398. }
  399. if (options.optimization.mangleExports) {
  400. const MangleExportsPlugin = require("./optimize/MangleExportsPlugin");
  401. new MangleExportsPlugin(
  402. options.optimization.mangleExports !== "size"
  403. ).apply(compiler);
  404. }
  405. if (options.optimization.concatenateModules) {
  406. const ModuleConcatenationPlugin = require("./optimize/ModuleConcatenationPlugin");
  407. new ModuleConcatenationPlugin().apply(compiler);
  408. }
  409. if (options.optimization.splitChunks) {
  410. const SplitChunksPlugin = require("./optimize/SplitChunksPlugin");
  411. new SplitChunksPlugin(options.optimization.splitChunks).apply(compiler);
  412. }
  413. if (options.optimization.runtimeChunk) {
  414. const RuntimeChunkPlugin = require("./optimize/RuntimeChunkPlugin");
  415. new RuntimeChunkPlugin(options.optimization.runtimeChunk).apply(compiler);
  416. }
  417. if (!options.optimization.emitOnErrors) {
  418. const NoEmitOnErrorsPlugin = require("./NoEmitOnErrorsPlugin");
  419. new NoEmitOnErrorsPlugin().apply(compiler);
  420. }
  421. if (options.optimization.realContentHash) {
  422. const RealContentHashPlugin = require("./optimize/RealContentHashPlugin");
  423. new RealContentHashPlugin({
  424. hashFunction: options.output.hashFunction,
  425. hashDigest: options.output.hashDigest
  426. }).apply(compiler);
  427. }
  428. if (options.optimization.checkWasmTypes) {
  429. const WasmFinalizeExportsPlugin = require("./wasm-sync/WasmFinalizeExportsPlugin");
  430. new WasmFinalizeExportsPlugin().apply(compiler);
  431. }
  432. const moduleIds = options.optimization.moduleIds;
  433. if (moduleIds) {
  434. switch (moduleIds) {
  435. case "natural": {
  436. const NaturalModuleIdsPlugin = require("./ids/NaturalModuleIdsPlugin");
  437. new NaturalModuleIdsPlugin().apply(compiler);
  438. break;
  439. }
  440. case "named": {
  441. const NamedModuleIdsPlugin = require("./ids/NamedModuleIdsPlugin");
  442. new NamedModuleIdsPlugin().apply(compiler);
  443. break;
  444. }
  445. case "hashed": {
  446. const WarnDeprecatedOptionPlugin = require("./WarnDeprecatedOptionPlugin");
  447. const HashedModuleIdsPlugin = require("./ids/HashedModuleIdsPlugin");
  448. new WarnDeprecatedOptionPlugin(
  449. "optimization.moduleIds",
  450. "hashed",
  451. "deterministic"
  452. ).apply(compiler);
  453. new HashedModuleIdsPlugin({
  454. hashFunction: options.output.hashFunction
  455. }).apply(compiler);
  456. break;
  457. }
  458. case "deterministic": {
  459. const DeterministicModuleIdsPlugin = require("./ids/DeterministicModuleIdsPlugin");
  460. new DeterministicModuleIdsPlugin().apply(compiler);
  461. break;
  462. }
  463. case "size": {
  464. const OccurrenceModuleIdsPlugin = require("./ids/OccurrenceModuleIdsPlugin");
  465. new OccurrenceModuleIdsPlugin({
  466. prioritiseInitial: true
  467. }).apply(compiler);
  468. break;
  469. }
  470. default:
  471. throw new Error(
  472. `webpack bug: moduleIds: ${moduleIds} is not implemented`
  473. );
  474. }
  475. }
  476. const chunkIds = options.optimization.chunkIds;
  477. if (chunkIds) {
  478. switch (chunkIds) {
  479. case "natural": {
  480. const NaturalChunkIdsPlugin = require("./ids/NaturalChunkIdsPlugin");
  481. new NaturalChunkIdsPlugin().apply(compiler);
  482. break;
  483. }
  484. case "named": {
  485. const NamedChunkIdsPlugin = require("./ids/NamedChunkIdsPlugin");
  486. new NamedChunkIdsPlugin().apply(compiler);
  487. break;
  488. }
  489. case "deterministic": {
  490. const DeterministicChunkIdsPlugin = require("./ids/DeterministicChunkIdsPlugin");
  491. new DeterministicChunkIdsPlugin().apply(compiler);
  492. break;
  493. }
  494. case "size": {
  495. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  496. const OccurrenceChunkIdsPlugin = require("./ids/OccurrenceChunkIdsPlugin");
  497. new OccurrenceChunkIdsPlugin({
  498. prioritiseInitial: true
  499. }).apply(compiler);
  500. break;
  501. }
  502. case "total-size": {
  503. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  504. const OccurrenceChunkIdsPlugin = require("./ids/OccurrenceChunkIdsPlugin");
  505. new OccurrenceChunkIdsPlugin({
  506. prioritiseInitial: false
  507. }).apply(compiler);
  508. break;
  509. }
  510. default:
  511. throw new Error(
  512. `webpack bug: chunkIds: ${chunkIds} is not implemented`
  513. );
  514. }
  515. }
  516. if (options.optimization.nodeEnv) {
  517. const DefinePlugin = require("./DefinePlugin");
  518. new DefinePlugin({
  519. "process.env.NODE_ENV": JSON.stringify(options.optimization.nodeEnv)
  520. }).apply(compiler);
  521. }
  522. if (options.optimization.minimize) {
  523. for (const minimizer of options.optimization.minimizer) {
  524. if (typeof minimizer === "function") {
  525. minimizer.call(compiler, compiler);
  526. } else if (minimizer !== "..." && minimizer) {
  527. minimizer.apply(compiler);
  528. }
  529. }
  530. }
  531. if (options.performance) {
  532. const SizeLimitsPlugin = require("./performance/SizeLimitsPlugin");
  533. new SizeLimitsPlugin(options.performance).apply(compiler);
  534. }
  535. new TemplatedPathPlugin().apply(compiler);
  536. new RecordIdsPlugin({
  537. portableIds: options.optimization.portableRecords
  538. }).apply(compiler);
  539. new WarnCaseSensitiveModulesPlugin().apply(compiler);
  540. const AddManagedPathsPlugin = require("./cache/AddManagedPathsPlugin");
  541. new AddManagedPathsPlugin(
  542. options.snapshot.managedPaths,
  543. options.snapshot.immutablePaths
  544. ).apply(compiler);
  545. if (options.cache && typeof options.cache === "object") {
  546. const cacheOptions = options.cache;
  547. switch (cacheOptions.type) {
  548. case "memory": {
  549. if (isFinite(cacheOptions.maxGenerations)) {
  550. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  551. const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin");
  552. new MemoryWithGcCachePlugin({
  553. maxGenerations: cacheOptions.maxGenerations
  554. }).apply(compiler);
  555. } else {
  556. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  557. const MemoryCachePlugin = require("./cache/MemoryCachePlugin");
  558. new MemoryCachePlugin().apply(compiler);
  559. }
  560. if (cacheOptions.cacheUnaffected) {
  561. if (!options.experiments.cacheUnaffected) {
  562. throw new Error(
  563. "'cache.cacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
  564. );
  565. }
  566. compiler.moduleMemCaches = new Map();
  567. }
  568. break;
  569. }
  570. case "filesystem": {
  571. const AddBuildDependenciesPlugin = require("./cache/AddBuildDependenciesPlugin");
  572. for (const key in cacheOptions.buildDependencies) {
  573. const list = cacheOptions.buildDependencies[key];
  574. new AddBuildDependenciesPlugin(list).apply(compiler);
  575. }
  576. if (!isFinite(cacheOptions.maxMemoryGenerations)) {
  577. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  578. const MemoryCachePlugin = require("./cache/MemoryCachePlugin");
  579. new MemoryCachePlugin().apply(compiler);
  580. } else if (cacheOptions.maxMemoryGenerations !== 0) {
  581. //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  582. const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin");
  583. new MemoryWithGcCachePlugin({
  584. maxGenerations: cacheOptions.maxMemoryGenerations
  585. }).apply(compiler);
  586. }
  587. if (cacheOptions.memoryCacheUnaffected) {
  588. if (!options.experiments.cacheUnaffected) {
  589. throw new Error(
  590. "'cache.memoryCacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
  591. );
  592. }
  593. compiler.moduleMemCaches = new Map();
  594. }
  595. switch (cacheOptions.store) {
  596. case "pack": {
  597. const IdleFileCachePlugin = require("./cache/IdleFileCachePlugin");
  598. const PackFileCacheStrategy = require("./cache/PackFileCacheStrategy");
  599. new IdleFileCachePlugin(
  600. new PackFileCacheStrategy({
  601. compiler,
  602. fs: compiler.intermediateFileSystem,
  603. context: options.context,
  604. cacheLocation: cacheOptions.cacheLocation,
  605. version: cacheOptions.version,
  606. logger: compiler.getInfrastructureLogger(
  607. "webpack.cache.PackFileCacheStrategy"
  608. ),
  609. snapshot: options.snapshot,
  610. maxAge: cacheOptions.maxAge,
  611. profile: cacheOptions.profile,
  612. allowCollectingMemory: cacheOptions.allowCollectingMemory,
  613. compression: cacheOptions.compression,
  614. readonly: cacheOptions.readonly
  615. }),
  616. cacheOptions.idleTimeout,
  617. cacheOptions.idleTimeoutForInitialStore,
  618. cacheOptions.idleTimeoutAfterLargeChanges
  619. ).apply(compiler);
  620. break;
  621. }
  622. default:
  623. throw new Error("Unhandled value for cache.store");
  624. }
  625. break;
  626. }
  627. default:
  628. // @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339)
  629. throw new Error(`Unknown cache type ${cacheOptions.type}`);
  630. }
  631. }
  632. new ResolverCachePlugin().apply(compiler);
  633. if (options.ignoreWarnings && options.ignoreWarnings.length > 0) {
  634. const IgnoreWarningsPlugin = require("./IgnoreWarningsPlugin");
  635. new IgnoreWarningsPlugin(options.ignoreWarnings).apply(compiler);
  636. }
  637. compiler.hooks.afterPlugins.call(compiler);
  638. if (!compiler.inputFileSystem) {
  639. throw new Error("No input filesystem provided");
  640. }
  641. compiler.resolverFactory.hooks.resolveOptions
  642. .for("normal")
  643. .tap("WebpackOptionsApply", resolveOptions => {
  644. resolveOptions = cleverMerge(options.resolve, resolveOptions);
  645. resolveOptions.fileSystem = compiler.inputFileSystem;
  646. return resolveOptions;
  647. });
  648. compiler.resolverFactory.hooks.resolveOptions
  649. .for("context")
  650. .tap("WebpackOptionsApply", resolveOptions => {
  651. resolveOptions = cleverMerge(options.resolve, resolveOptions);
  652. resolveOptions.fileSystem = compiler.inputFileSystem;
  653. resolveOptions.resolveToContext = true;
  654. return resolveOptions;
  655. });
  656. compiler.resolverFactory.hooks.resolveOptions
  657. .for("loader")
  658. .tap("WebpackOptionsApply", resolveOptions => {
  659. resolveOptions = cleverMerge(options.resolveLoader, resolveOptions);
  660. resolveOptions.fileSystem = compiler.inputFileSystem;
  661. return resolveOptions;
  662. });
  663. compiler.hooks.afterResolvers.call(compiler);
  664. return options;
  665. }
  666. }
  667. module.exports = WebpackOptionsApply;