| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Yuta Hiroto @hiroppy | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 02:41:45 +08:00
										 |  |  | const { validate } = require("schema-utils"); | 
					
						
							| 
									
										
										
										
											2021-01-05 18:11:02 +08:00
										 |  |  | const { cleverMerge } = require("../util/cleverMerge"); | 
					
						
							| 
									
										
										
										
											2019-10-16 22:38:04 +08:00
										 |  |  | const { compareModulesByIdentifier } = require("../util/comparators"); | 
					
						
							| 
									
										
										
										
											2020-12-27 05:32:57 +08:00
										 |  |  | const memoize = require("../util/memoize"); | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** @typedef {import("webpack-sources").Source} Source */ | 
					
						
							|  |  |  | /** @typedef {import("../Chunk")} Chunk */ | 
					
						
							|  |  |  | /** @typedef {import("../Compiler")} Compiler */ | 
					
						
							|  |  |  | /** @typedef {import("../Module")} Module */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-05 18:11:02 +08:00
										 |  |  | const getSchema = name => { | 
					
						
							|  |  |  | 	const { definitions } = require("../../schemas/WebpackOptions.json"); | 
					
						
							|  |  |  | 	return { | 
					
						
							|  |  |  | 		definitions, | 
					
						
							|  |  |  | 		oneOf: [{ $ref: `#/definitions/${name}` }] | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-01-23 18:27:12 +08:00
										 |  |  | const getGeneratorSchemaMap = { | 
					
						
							| 
									
										
										
										
											2021-01-05 18:11:02 +08:00
										 |  |  | 	asset: memoize(() => getSchema("AssetGeneratorOptions")), | 
					
						
							|  |  |  | 	"asset/resource": memoize(() => getSchema("AssetResourceGeneratorOptions")), | 
					
						
							|  |  |  | 	"asset/inline": memoize(() => getSchema("AssetInlineGeneratorOptions")) | 
					
						
							| 
									
										
										
										
											2020-01-23 18:27:12 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-05 18:11:02 +08:00
										 |  |  | const getParserSchema = memoize(() => getSchema("AssetParserOptions")); | 
					
						
							| 
									
										
										
										
											2020-12-27 05:32:57 +08:00
										 |  |  | const getAssetGenerator = memoize(() => require("./AssetGenerator")); | 
					
						
							|  |  |  | const getAssetParser = memoize(() => require("./AssetParser")); | 
					
						
							| 
									
										
										
										
											2021-03-11 17:40:03 +08:00
										 |  |  | const getAssetSourceParser = memoize(() => require("./AssetSourceParser")); | 
					
						
							| 
									
										
										
										
											2020-12-27 05:32:57 +08:00
										 |  |  | const getAssetSourceGenerator = memoize(() => | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 	require("./AssetSourceGenerator") | 
					
						
							| 
									
										
										
										
											2019-12-02 23:37:55 +08:00
										 |  |  | ); | 
					
						
							| 
									
										
										
										
											2019-11-26 21:09:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 19:16:27 +08:00
										 |  |  | const type = "asset"; | 
					
						
							|  |  |  | const plugin = "AssetModulesPlugin"; | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 19:33:45 +08:00
										 |  |  | class AssetModulesPlugin { | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2020-04-23 16:48:36 +08:00
										 |  |  | 	 * Apply the plugin | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler the compiler instance | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	apply(compiler) { | 
					
						
							|  |  |  | 		compiler.hooks.compilation.tap( | 
					
						
							|  |  |  | 			plugin, | 
					
						
							|  |  |  | 			(compilation, { normalModuleFactory }) => { | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 				normalModuleFactory.hooks.createParser | 
					
						
							|  |  |  | 					.for("asset") | 
					
						
							|  |  |  | 					.tap(plugin, parserOptions => { | 
					
						
							| 
									
										
										
										
											2020-10-06 02:41:45 +08:00
										 |  |  | 						validate(getParserSchema(), parserOptions, { | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 							name: "Asset Modules Plugin", | 
					
						
							|  |  |  | 							baseDataPath: "parser" | 
					
						
							| 
									
										
										
										
											2019-11-18 00:49:48 +08:00
										 |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2021-01-05 18:11:02 +08:00
										 |  |  | 						parserOptions = cleverMerge( | 
					
						
							|  |  |  | 							compiler.options.module.parser.asset, | 
					
						
							|  |  |  | 							parserOptions | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2019-11-18 00:49:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 						let dataUrlCondition = parserOptions.dataUrlCondition; | 
					
						
							|  |  |  | 						if (!dataUrlCondition || typeof dataUrlCondition === "object") { | 
					
						
							|  |  |  | 							dataUrlCondition = { | 
					
						
							|  |  |  | 								maxSize: 8096, | 
					
						
							|  |  |  | 								...dataUrlCondition | 
					
						
							|  |  |  | 							}; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 						const AssetParser = getAssetParser(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-11 23:41:19 +08:00
										 |  |  | 						return new AssetParser(dataUrlCondition); | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 					}); | 
					
						
							|  |  |  | 				normalModuleFactory.hooks.createParser | 
					
						
							|  |  |  | 					.for("asset/inline") | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 					.tap(plugin, parserOptions => { | 
					
						
							|  |  |  | 						const AssetParser = getAssetParser(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						return new AssetParser(true); | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 				normalModuleFactory.hooks.createParser | 
					
						
							|  |  |  | 					.for("asset/resource") | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 					.tap(plugin, parserOptions => { | 
					
						
							|  |  |  | 						const AssetParser = getAssetParser(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-11 23:41:19 +08:00
										 |  |  | 						return new AssetParser(false); | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2019-11-26 21:05:07 +08:00
										 |  |  | 				normalModuleFactory.hooks.createParser | 
					
						
							|  |  |  | 					.for("asset/source") | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 					.tap(plugin, parserOptions => { | 
					
						
							| 
									
										
										
										
											2021-03-11 17:40:03 +08:00
										 |  |  | 						const AssetSourceParser = getAssetSourceParser(); | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-11 17:40:03 +08:00
										 |  |  | 						return new AssetSourceParser(); | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-29 21:48:46 +08:00
										 |  |  | 				for (const type of ["asset", "asset/inline", "asset/resource"]) { | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 					normalModuleFactory.hooks.createGenerator | 
					
						
							|  |  |  | 						.for(type) | 
					
						
							| 
									
										
										
										
											2019-11-26 21:09:22 +08:00
										 |  |  | 						// eslint-disable-next-line no-loop-func
 | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 						.tap(plugin, generatorOptions => { | 
					
						
							| 
									
										
										
										
											2020-10-06 02:41:45 +08:00
										 |  |  | 							validate(getGeneratorSchemaMap[type](), generatorOptions, { | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 								name: "Asset Modules Plugin", | 
					
						
							|  |  |  | 								baseDataPath: "generator" | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-29 21:48:46 +08:00
										 |  |  | 							let dataUrl = undefined; | 
					
						
							|  |  |  | 							if (type !== "asset/resource") { | 
					
						
							|  |  |  | 								dataUrl = generatorOptions.dataUrl; | 
					
						
							|  |  |  | 								if (!dataUrl || typeof dataUrl === "object") { | 
					
						
							|  |  |  | 									dataUrl = { | 
					
						
							|  |  |  | 										encoding: "base64", | 
					
						
							|  |  |  | 										mimetype: undefined, | 
					
						
							|  |  |  | 										...dataUrl | 
					
						
							|  |  |  | 									}; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							let filename = undefined; | 
					
						
							| 
									
										
										
										
											2021-03-16 02:03:19 +08:00
										 |  |  | 							let publicPath = undefined; | 
					
						
							| 
									
										
										
										
											2020-01-29 21:48:46 +08:00
										 |  |  | 							if (type !== "asset/inline") { | 
					
						
							|  |  |  | 								filename = generatorOptions.filename; | 
					
						
							| 
									
										
										
										
											2021-03-16 02:03:19 +08:00
										 |  |  | 								publicPath = generatorOptions.publicPath; | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 							const AssetGenerator = getAssetGenerator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 01:44:41 +08:00
										 |  |  | 							return new AssetGenerator( | 
					
						
							|  |  |  | 								dataUrl, | 
					
						
							|  |  |  | 								filename, | 
					
						
							| 
									
										
										
										
											2021-03-16 02:03:19 +08:00
										 |  |  | 								publicPath, | 
					
						
							| 
									
										
										
										
											2021-03-12 01:44:41 +08:00
										 |  |  | 								generatorOptions.emit !== false | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2019-11-26 20:56:27 +08:00
										 |  |  | 						}); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-11-26 21:05:07 +08:00
										 |  |  | 				normalModuleFactory.hooks.createGenerator | 
					
						
							|  |  |  | 					.for("asset/source") | 
					
						
							| 
									
										
										
										
											2019-12-04 01:31:39 +08:00
										 |  |  | 					.tap(plugin, () => { | 
					
						
							|  |  |  | 						const AssetSourceGenerator = getAssetSourceGenerator(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						return new AssetSourceGenerator(); | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 18:24:52 +08:00
										 |  |  | 				compilation.hooks.renderManifest.tap(plugin, (result, options) => { | 
					
						
							| 
									
										
										
										
											2019-10-09 04:29:46 +08:00
										 |  |  | 					const { chunkGraph } = compilation; | 
					
						
							| 
									
										
										
										
											2020-07-17 20:57:11 +08:00
										 |  |  | 					const { chunk, codeGenerationResults } = options; | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:20:34 +08:00
										 |  |  | 					const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType( | 
					
						
							| 
									
										
										
										
											2019-10-04 18:24:52 +08:00
										 |  |  | 						chunk, | 
					
						
							| 
									
										
										
										
											2019-11-20 18:20:34 +08:00
										 |  |  | 						"asset", | 
					
						
							| 
									
										
										
										
											2019-10-16 22:38:04 +08:00
										 |  |  | 						compareModulesByIdentifier | 
					
						
							| 
									
										
										
										
											2019-11-20 18:20:34 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 					if (modules) { | 
					
						
							|  |  |  | 						for (const module of modules) { | 
					
						
							| 
									
										
										
										
											2020-10-11 07:17:03 +08:00
										 |  |  | 							const codeGenResult = codeGenerationResults.get( | 
					
						
							|  |  |  | 								module, | 
					
						
							|  |  |  | 								chunk.runtime | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2019-10-04 18:24:52 +08:00
										 |  |  | 							result.push({ | 
					
						
							| 
									
										
										
										
											2020-10-11 07:17:03 +08:00
										 |  |  | 								render: () => codeGenResult.sources.get(type), | 
					
						
							| 
									
										
										
										
											2021-03-11 23:41:19 +08:00
										 |  |  | 								filename: | 
					
						
							|  |  |  | 									module.buildInfo.filename || | 
					
						
							|  |  |  | 									codeGenResult.data.get("filename"), | 
					
						
							|  |  |  | 								info: | 
					
						
							|  |  |  | 									module.buildInfo.assetInfo || | 
					
						
							|  |  |  | 									codeGenResult.data.get("assetInfo"), | 
					
						
							| 
									
										
										
										
											2019-10-04 18:24:52 +08:00
										 |  |  | 								auxiliary: true, | 
					
						
							|  |  |  | 								identifier: `assetModule${chunkGraph.getModuleId(module)}`, | 
					
						
							| 
									
										
										
										
											2021-03-11 23:41:19 +08:00
										 |  |  | 								hash: | 
					
						
							|  |  |  | 									module.buildInfo.fullContentHash || | 
					
						
							|  |  |  | 									codeGenResult.data.get("fullContentHash") | 
					
						
							| 
									
										
										
										
											2019-10-04 18:24:52 +08:00
										 |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-10-04 18:24:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					return result; | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2021-04-09 21:50:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-12 15:17:43 +08:00
										 |  |  | 				compilation.hooks.executeModule.tap( | 
					
						
							| 
									
										
										
										
											2021-04-09 21:50:25 +08:00
										 |  |  | 					"AssetModulesPlugin", | 
					
						
							|  |  |  | 					(options, context) => { | 
					
						
							|  |  |  | 						const { codeGenerationResult } = options; | 
					
						
							|  |  |  | 						const source = codeGenerationResult.sources.get("asset"); | 
					
						
							|  |  |  | 						if (source === undefined) return; | 
					
						
							| 
									
										
										
										
											2021-04-10 02:45:59 +08:00
										 |  |  | 						context.assets.set(codeGenerationResult.data.get("filename"), { | 
					
						
							| 
									
										
										
										
											2021-04-09 21:50:25 +08:00
										 |  |  | 							source, | 
					
						
							| 
									
										
										
										
											2021-04-10 02:45:59 +08:00
										 |  |  | 							info: codeGenerationResult.data.get("assetInfo") | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2021-04-09 21:50:25 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2019-03-31 22:12:19 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 19:16:27 +08:00
										 |  |  | module.exports = AssetModulesPlugin; |