WebpackOptionsApply.js 27 KB

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