mirror of https://github.com/webpack/webpack.git
				
				
				
			
		
			
				
	
	
		
			168 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Yuta Hiroto @hiroppy
 | |
| */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const { validate } = require("schema-utils");
 | |
| const { cleverMerge } = require("../util/cleverMerge");
 | |
| const { compareModulesByIdentifier } = require("../util/comparators");
 | |
| const memoize = require("../util/memoize");
 | |
| 
 | |
| /** @typedef {import("webpack-sources").Source} Source */
 | |
| /** @typedef {import("../Chunk")} Chunk */
 | |
| /** @typedef {import("../Compiler")} Compiler */
 | |
| /** @typedef {import("../Module")} Module */
 | |
| 
 | |
| const getSchema = name => {
 | |
| 	const { definitions } = require("../../schemas/WebpackOptions.json");
 | |
| 	return {
 | |
| 		definitions,
 | |
| 		oneOf: [{ $ref: `#/definitions/${name}` }]
 | |
| 	};
 | |
| };
 | |
| const getGeneratorSchemaMap = {
 | |
| 	asset: memoize(() => getSchema("AssetGeneratorOptions")),
 | |
| 	"asset/resource": memoize(() => getSchema("AssetResourceGeneratorOptions")),
 | |
| 	"asset/inline": memoize(() => getSchema("AssetInlineGeneratorOptions"))
 | |
| };
 | |
| 
 | |
| const getParserSchema = memoize(() => getSchema("AssetParserOptions"));
 | |
| const getAssetGenerator = memoize(() => require("./AssetGenerator"));
 | |
| const getAssetParser = memoize(() => require("./AssetParser"));
 | |
| const getAssetSourceGenerator = memoize(() =>
 | |
| 	require("./AssetSourceGenerator")
 | |
| );
 | |
| 
 | |
| const type = "asset";
 | |
| const plugin = "AssetModulesPlugin";
 | |
| 
 | |
| class AssetModulesPlugin {
 | |
| 	/**
 | |
| 	 * Apply the plugin
 | |
| 	 * @param {Compiler} compiler the compiler instance
 | |
| 	 * @returns {void}
 | |
| 	 */
 | |
| 	apply(compiler) {
 | |
| 		compiler.hooks.compilation.tap(
 | |
| 			plugin,
 | |
| 			(compilation, { normalModuleFactory }) => {
 | |
| 				normalModuleFactory.hooks.createParser
 | |
| 					.for("asset")
 | |
| 					.tap(plugin, parserOptions => {
 | |
| 						validate(getParserSchema(), parserOptions, {
 | |
| 							name: "Asset Modules Plugin",
 | |
| 							baseDataPath: "parser"
 | |
| 						});
 | |
| 						parserOptions = cleverMerge(
 | |
| 							compiler.options.module.parser.asset,
 | |
| 							parserOptions
 | |
| 						);
 | |
| 
 | |
| 						let dataUrlCondition = parserOptions.dataUrlCondition;
 | |
| 						if (!dataUrlCondition || typeof dataUrlCondition === "object") {
 | |
| 							dataUrlCondition = {
 | |
| 								maxSize: 8096,
 | |
| 								...dataUrlCondition
 | |
| 							};
 | |
| 						}
 | |
| 
 | |
| 						const AssetParser = getAssetParser();
 | |
| 
 | |
| 						return new AssetParser(dataUrlCondition);
 | |
| 					});
 | |
| 				normalModuleFactory.hooks.createParser
 | |
| 					.for("asset/inline")
 | |
| 					.tap(plugin, parserOptions => {
 | |
| 						const AssetParser = getAssetParser();
 | |
| 
 | |
| 						return new AssetParser(true);
 | |
| 					});
 | |
| 				normalModuleFactory.hooks.createParser
 | |
| 					.for("asset/resource")
 | |
| 					.tap(plugin, parserOptions => {
 | |
| 						const AssetParser = getAssetParser();
 | |
| 
 | |
| 						return new AssetParser(false);
 | |
| 					});
 | |
| 				normalModuleFactory.hooks.createParser
 | |
| 					.for("asset/source")
 | |
| 					.tap(plugin, parserOptions => {
 | |
| 						const AssetParser = getAssetParser();
 | |
| 
 | |
| 						return new AssetParser(false);
 | |
| 					});
 | |
| 
 | |
| 				for (const type of ["asset", "asset/inline", "asset/resource"]) {
 | |
| 					normalModuleFactory.hooks.createGenerator
 | |
| 						.for(type)
 | |
| 						// eslint-disable-next-line no-loop-func
 | |
| 						.tap(plugin, generatorOptions => {
 | |
| 							validate(getGeneratorSchemaMap[type](), generatorOptions, {
 | |
| 								name: "Asset Modules Plugin",
 | |
| 								baseDataPath: "generator"
 | |
| 							});
 | |
| 
 | |
| 							let dataUrl = undefined;
 | |
| 							if (type !== "asset/resource") {
 | |
| 								dataUrl = generatorOptions.dataUrl;
 | |
| 								if (!dataUrl || typeof dataUrl === "object") {
 | |
| 									dataUrl = {
 | |
| 										encoding: "base64",
 | |
| 										mimetype: undefined,
 | |
| 										...dataUrl
 | |
| 									};
 | |
| 								}
 | |
| 							}
 | |
| 
 | |
| 							let filename = undefined;
 | |
| 							if (type !== "asset/inline") {
 | |
| 								filename = generatorOptions.filename;
 | |
| 							}
 | |
| 
 | |
| 							const AssetGenerator = getAssetGenerator();
 | |
| 
 | |
| 							return new AssetGenerator(compilation, dataUrl, filename);
 | |
| 						});
 | |
| 				}
 | |
| 				normalModuleFactory.hooks.createGenerator
 | |
| 					.for("asset/source")
 | |
| 					.tap(plugin, () => {
 | |
| 						const AssetSourceGenerator = getAssetSourceGenerator();
 | |
| 
 | |
| 						return new AssetSourceGenerator();
 | |
| 					});
 | |
| 
 | |
| 				compilation.hooks.renderManifest.tap(plugin, (result, options) => {
 | |
| 					const { chunkGraph } = compilation;
 | |
| 					const { chunk, codeGenerationResults } = options;
 | |
| 
 | |
| 					const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
 | |
| 						chunk,
 | |
| 						"asset",
 | |
| 						compareModulesByIdentifier
 | |
| 					);
 | |
| 					if (modules) {
 | |
| 						for (const module of modules) {
 | |
| 							result.push({
 | |
| 								render: () =>
 | |
| 									codeGenerationResults.getSource(module, chunk.runtime, type),
 | |
| 								filename: module.buildInfo.filename,
 | |
| 								info: module.buildInfo.assetInfo,
 | |
| 								auxiliary: true,
 | |
| 								identifier: `assetModule${chunkGraph.getModuleId(module)}`,
 | |
| 								hash: module.buildInfo.fullContentHash
 | |
| 							});
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					return result;
 | |
| 				});
 | |
| 			}
 | |
| 		);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| module.exports = AssetModulesPlugin;
 |