WebpackOptionsApply.js 26 KB

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