You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			133 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			133 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | /* | ||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||
|  | 	Author Tobias Koppers @sokra | ||
|  | */ | ||
|  | 
 | ||
|  | "use strict"; | ||
|  | 
 | ||
|  | const asyncLib = require("neo-async"); | ||
|  | const EntryDependency = require("./dependencies/EntryDependency"); | ||
|  | const { someInIterable } = require("./util/IterableHelpers"); | ||
|  | const { compareModulesById } = require("./util/comparators"); | ||
|  | const { dirname, mkdirp } = require("./util/fs"); | ||
|  | 
 | ||
|  | /** @typedef {import("./Compiler")} Compiler */ | ||
|  | /** @typedef {import("./Module").BuildMeta} BuildMeta */ | ||
|  | 
 | ||
|  | /** | ||
|  |  * @typedef {Object} ManifestModuleData | ||
|  |  * @property {string | number} id | ||
|  |  * @property {BuildMeta} buildMeta | ||
|  |  * @property {boolean | string[] | undefined} exports | ||
|  |  */ | ||
|  | 
 | ||
|  | /** | ||
|  |  * @typedef {Object} LibManifestPluginOptions | ||
|  |  * @property {string=} context Context of requests in the manifest file (defaults to the webpack context). | ||
|  |  * @property {boolean=} entryOnly If true, only entry points will be exposed (default: true). | ||
|  |  * @property {boolean=} format If true, manifest json file (output) will be formatted. | ||
|  |  * @property {string=} name Name of the exposed dll function (external name, use value of 'output.library'). | ||
|  |  * @property {string} path Absolute path to the manifest json file (output). | ||
|  |  * @property {string=} type Type of the dll bundle (external type, use value of 'output.libraryTarget'). | ||
|  |  */ | ||
|  | 
 | ||
|  | class LibManifestPlugin { | ||
|  | 	/** | ||
|  | 	 * @param {LibManifestPluginOptions} options the options | ||
|  | 	 */ | ||
|  | 	constructor(options) { | ||
|  | 		this.options = options; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Apply the plugin | ||
|  | 	 * @param {Compiler} compiler the compiler instance | ||
|  | 	 * @returns {void} | ||
|  | 	 */ | ||
|  | 	apply(compiler) { | ||
|  | 		compiler.hooks.emit.tapAsync( | ||
|  | 			"LibManifestPlugin", | ||
|  | 			(compilation, callback) => { | ||
|  | 				const moduleGraph = compilation.moduleGraph; | ||
|  | 				asyncLib.forEach( | ||
|  | 					Array.from(compilation.chunks), | ||
|  | 					(chunk, callback) => { | ||
|  | 						if (!chunk.canBeInitial()) { | ||
|  | 							callback(); | ||
|  | 							return; | ||
|  | 						} | ||
|  | 						const chunkGraph = compilation.chunkGraph; | ||
|  | 						const targetPath = compilation.getPath(this.options.path, { | ||
|  | 							chunk | ||
|  | 						}); | ||
|  | 						const name = | ||
|  | 							this.options.name && | ||
|  | 							compilation.getPath(this.options.name, { | ||
|  | 								chunk, | ||
|  | 								contentHashType: "javascript" | ||
|  | 							}); | ||
|  | 						const content = Object.create(null); | ||
|  | 						for (const module of chunkGraph.getOrderedChunkModulesIterable( | ||
|  | 							chunk, | ||
|  | 							compareModulesById(chunkGraph) | ||
|  | 						)) { | ||
|  | 							if ( | ||
|  | 								this.options.entryOnly && | ||
|  | 								!someInIterable( | ||
|  | 									moduleGraph.getIncomingConnections(module), | ||
|  | 									c => c.dependency instanceof EntryDependency | ||
|  | 								) | ||
|  | 							) { | ||
|  | 								continue; | ||
|  | 							} | ||
|  | 							const ident = module.libIdent({ | ||
|  | 								context: | ||
|  | 									this.options.context || | ||
|  | 									/** @type {string} */ (compiler.options.context), | ||
|  | 								associatedObjectForCache: compiler.root | ||
|  | 							}); | ||
|  | 							if (ident) { | ||
|  | 								const exportsInfo = moduleGraph.getExportsInfo(module); | ||
|  | 								const providedExports = exportsInfo.getProvidedExports(); | ||
|  | 								/** @type {ManifestModuleData} */ | ||
|  | 								const data = { | ||
|  | 									id: chunkGraph.getModuleId(module), | ||
|  | 									buildMeta: /** @type {BuildMeta} */ (module.buildMeta), | ||
|  | 									exports: Array.isArray(providedExports) | ||
|  | 										? providedExports | ||
|  | 										: undefined | ||
|  | 								}; | ||
|  | 								content[ident] = data; | ||
|  | 							} | ||
|  | 						} | ||
|  | 						const manifest = { | ||
|  | 							name, | ||
|  | 							type: this.options.type, | ||
|  | 							content | ||
|  | 						}; | ||
|  | 						// Apply formatting to content if format flag is true;
 | ||
|  | 						const manifestContent = this.options.format | ||
|  | 							? JSON.stringify(manifest, null, 2) | ||
|  | 							: JSON.stringify(manifest); | ||
|  | 						const buffer = Buffer.from(manifestContent, "utf8"); | ||
|  | 						mkdirp( | ||
|  | 							compiler.intermediateFileSystem, | ||
|  | 							dirname(compiler.intermediateFileSystem, targetPath), | ||
|  | 							err => { | ||
|  | 								if (err) return callback(err); | ||
|  | 								compiler.intermediateFileSystem.writeFile( | ||
|  | 									targetPath, | ||
|  | 									buffer, | ||
|  | 									callback | ||
|  | 								); | ||
|  | 							} | ||
|  | 						); | ||
|  | 					}, | ||
|  | 					callback | ||
|  | 				); | ||
|  | 			} | ||
|  | 		); | ||
|  | 	} | ||
|  | } | ||
|  | module.exports = LibManifestPlugin; |