| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 20:39:23 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 12:27:09 +08:00
										 |  |  | const asyncLib = require("neo-async"); | 
					
						
							| 
									
										
										
										
											2018-08-14 22:40:37 +08:00
										 |  |  | const EntryDependency = require("./dependencies/EntryDependency"); | 
					
						
							| 
									
										
										
										
											2021-02-04 21:10:27 +08:00
										 |  |  | const { someInIterable } = require("./util/IterableHelpers"); | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | const { compareModulesById } = require("./util/comparators"); | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | const { dirname, mkdirp } = require("./util/fs"); | 
					
						
							| 
									
										
										
										
											2017-04-05 20:39:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ | 
					
						
							| 
									
										
										
										
											2018-08-23 01:23:48 +08:00
										 |  |  | /** @typedef {import("./Compiler")} Compiler */ | 
					
						
							| 
									
										
										
										
											2024-03-05 22:40:46 +08:00
										 |  |  | /** @typedef {import("./Compiler").IntermediateFileSystem} IntermediateFileSystem */ | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | /** @typedef {import("./Module").BuildMeta} BuildMeta */ | 
					
						
							| 
									
										
										
										
											2018-08-23 01:23:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-30 20:21:55 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} ManifestModuleData | 
					
						
							| 
									
										
										
										
											2018-12-30 20:21:55 +08:00
										 |  |  |  * @property {string | number} id | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  |  * @property {BuildMeta} buildMeta | 
					
						
							|  |  |  |  * @property {boolean | string[] | undefined} exports | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} LibManifestPluginOptions | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  |  * @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'). | 
					
						
							| 
									
										
										
										
											2018-12-30 20:21:55 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 20:39:23 +08:00
										 |  |  | class LibManifestPlugin { | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {LibManifestPluginOptions} options the options | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-04-05 20:39:23 +08:00
										 |  |  | 	constructor(options) { | 
					
						
							|  |  |  | 		this.options = options; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-23 01:23:48 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2020-04-23 16:48:36 +08:00
										 |  |  | 	 * Apply the plugin | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler the compiler instance | 
					
						
							| 
									
										
										
										
											2018-08-23 01:23:48 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-04-05 20:39:23 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.emit.tapAsync( | 
					
						
							| 
									
										
										
										
											2023-12-29 23:17:27 +08:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				name: "LibManifestPlugin", | 
					
						
							|  |  |  | 				stage: 110 | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			(compilation, callback) => { | 
					
						
							| 
									
										
										
										
											2018-08-16 22:11:20 +08:00
										 |  |  | 				const moduleGraph = compilation.moduleGraph; | 
					
						
							| 
									
										
										
										
											2024-03-16 01:23:24 +08:00
										 |  |  | 				// store used paths to detect issue and output an error. #18200
 | 
					
						
							|  |  |  | 				const usedPaths = new Set(); | 
					
						
							| 
									
										
										
										
											2024-08-02 23:42:44 +08:00
										 |  |  | 				asyncLib.each( | 
					
						
							| 
									
										
										
										
											2018-09-06 22:59:11 +08:00
										 |  |  | 					Array.from(compilation.chunks), | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					(chunk, callback) => { | 
					
						
							| 
									
										
										
										
											2020-09-08 00:02:14 +08:00
										 |  |  | 						if (!chunk.canBeInitial()) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							callback(); | 
					
						
							|  |  |  | 							return; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 						const chunkGraph = compilation.chunkGraph; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						const targetPath = compilation.getPath(this.options.path, { | 
					
						
							|  |  |  | 							chunk | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2024-03-16 01:23:24 +08:00
										 |  |  | 						if (usedPaths.has(targetPath)) { | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 							callback(new Error("each chunk must have a unique path")); | 
					
						
							| 
									
										
										
										
											2024-03-16 01:23:24 +08:00
										 |  |  | 							return; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						usedPaths.add(targetPath); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						const name = | 
					
						
							|  |  |  | 							this.options.name && | 
					
						
							|  |  |  | 							compilation.getPath(this.options.name, { | 
					
						
							| 
									
										
										
										
											2023-04-07 18:21:05 +08:00
										 |  |  | 								chunk, | 
					
						
							|  |  |  | 								contentHashType: "javascript" | 
					
						
							| 
									
										
										
										
											2017-04-05 20:39:23 +08:00
										 |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2020-01-17 04:22:05 +08:00
										 |  |  | 						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({ | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 								context: | 
					
						
							|  |  |  | 									this.options.context || | 
					
						
							|  |  |  | 									/** @type {string} */ (compiler.options.context), | 
					
						
							| 
									
										
										
										
											2020-01-17 04:22:05 +08:00
										 |  |  | 								associatedObjectForCache: compiler.root | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 							if (ident) { | 
					
						
							|  |  |  | 								const exportsInfo = moduleGraph.getExportsInfo(module); | 
					
						
							|  |  |  | 								const providedExports = exportsInfo.getProvidedExports(); | 
					
						
							|  |  |  | 								/** @type {ManifestModuleData} */ | 
					
						
							|  |  |  | 								const data = { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									id: /** @type {ModuleId} */ (chunkGraph.getModuleId(module)), | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 									buildMeta: /** @type {BuildMeta} */ (module.buildMeta), | 
					
						
							| 
									
										
										
										
											2020-01-17 04:22:05 +08:00
										 |  |  | 									exports: Array.isArray(providedExports) | 
					
						
							|  |  |  | 										? providedExports | 
					
						
							|  |  |  | 										: undefined | 
					
						
							|  |  |  | 								}; | 
					
						
							|  |  |  | 								content[ident] = data; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						const manifest = { | 
					
						
							|  |  |  | 							name, | 
					
						
							|  |  |  | 							type: this.options.type, | 
					
						
							| 
									
										
										
										
											2020-01-17 04:22:05 +08:00
										 |  |  | 							content | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						}; | 
					
						
							| 
									
										
										
										
											2018-10-03 23:48:29 +08:00
										 |  |  | 						// Apply formatting to content if format flag is true;
 | 
					
						
							|  |  |  | 						const manifestContent = this.options.format | 
					
						
							|  |  |  | 							? JSON.stringify(manifest, null, 2) | 
					
						
							|  |  |  | 							: JSON.stringify(manifest); | 
					
						
							| 
									
										
										
										
											2020-01-17 04:22:05 +08:00
										 |  |  | 						const buffer = Buffer.from(manifestContent, "utf8"); | 
					
						
							| 
									
										
										
										
											2024-03-05 22:40:46 +08:00
										 |  |  | 						const intermediateFileSystem = | 
					
						
							|  |  |  | 							/** @type {IntermediateFileSystem} */ ( | 
					
						
							|  |  |  | 								compiler.intermediateFileSystem | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 						mkdirp( | 
					
						
							| 
									
										
										
										
											2024-03-05 22:40:46 +08:00
										 |  |  | 							intermediateFileSystem, | 
					
						
							|  |  |  | 							dirname(intermediateFileSystem, targetPath), | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 							err => { | 
					
						
							|  |  |  | 								if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-03-05 22:40:46 +08:00
										 |  |  | 								intermediateFileSystem.writeFile(targetPath, buffer, callback); | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					}, | 
					
						
							|  |  |  | 					callback | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2017-04-05 20:39:23 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | } | 
					
						
							|  |  |  | module.exports = LibManifestPlugin; |