mirror of https://github.com/webpack/webpack.git
				
				
				
			
		
			
				
	
	
		
			212 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Tobias Koppers @sokra
 | |
| */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const SetVarTemplatePlugin = require("./SetVarTemplatePlugin");
 | |
| 
 | |
| /** @typedef {import("../declarations/WebpackOptions").LibraryCustomUmdCommentObject} LibraryCustomUmdCommentObject */
 | |
| /** @typedef {import("../declarations/WebpackOptions").LibraryCustomUmdObject} LibraryCustomUmdObject */
 | |
| /** @typedef {import("./Compiler")} Compiler */
 | |
| 
 | |
| /**
 | |
|  * @param {string[]} accessor the accessor to convert to path
 | |
|  * @returns {string} the path
 | |
|  */
 | |
| const accessorToObjectAccess = accessor => {
 | |
| 	return accessor.map(a => `[${JSON.stringify(a)}]`).join("");
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * @param {string=} base the path prefix
 | |
|  * @param {string|string[]|LibraryCustomUmdObject} accessor the accessor
 | |
|  * @param {"amd" | "commonjs" | "root"} umdProperty property used when a custom umd object is provided
 | |
|  * @param {string=} joinWith the element separator
 | |
|  * @returns {string} the path
 | |
|  */
 | |
| const accessorAccess = (base, accessor, umdProperty, joinWith = "; ") => {
 | |
| 	const normalizedAccessor =
 | |
| 		typeof accessor === "object" && !Array.isArray(accessor)
 | |
| 			? accessor[umdProperty]
 | |
| 			: accessor;
 | |
| 	const accessors = Array.isArray(normalizedAccessor)
 | |
| 		? normalizedAccessor
 | |
| 		: [normalizedAccessor];
 | |
| 	return accessors
 | |
| 		.map((_, idx) => {
 | |
| 			const a = base
 | |
| 				? base + accessorToObjectAccess(accessors.slice(0, idx + 1))
 | |
| 				: accessors[0] + accessorToObjectAccess(accessors.slice(1, idx + 1));
 | |
| 			if (idx === accessors.length - 1) return a;
 | |
| 			if (idx === 0 && base === undefined) {
 | |
| 				return `${a} = typeof ${a} === "object" ? ${a} : {}`;
 | |
| 			}
 | |
| 			return `${a} = ${a} || {}`;
 | |
| 		})
 | |
| 		.join(joinWith);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * @typedef {Object} LibraryOptions
 | |
|  * @property {string|string[]|LibraryCustomUmdObject=} library name of library
 | |
|  * @property {string=} libraryTarget type of library
 | |
|  * @property {boolean=} umdNamedDefine setting this to true will name the UMD module
 | |
|  * @property {string|LibraryCustomUmdCommentObject=} auxiliaryComment comment in the UMD wrapper
 | |
|  * @property {string|string[]=} libraryExport which export should be exposed as library
 | |
|  * @property {string=} globalObject global object expression
 | |
|  */
 | |
| 
 | |
| class LibraryTemplatePlugin {
 | |
| 	/**
 | |
| 	 * @param {LibraryOptions} options options
 | |
| 	 */
 | |
| 	constructor(options) {
 | |
| 		if (arguments.length > 1) {
 | |
| 			options = {
 | |
| 				library: arguments[0],
 | |
| 				libraryTarget: arguments[1],
 | |
| 				umdNamedDefine: arguments[2],
 | |
| 				auxiliaryComment: arguments[3],
 | |
| 				libraryExport: arguments[4],
 | |
| 				globalObject: null
 | |
| 			};
 | |
| 		}
 | |
| 		this.options = options;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param {Compiler} compiler the compiler instance
 | |
| 	 * @returns {void}
 | |
| 	 */
 | |
| 	apply(compiler) {
 | |
| 		if (this.options.libraryExport) {
 | |
| 			const ExportPropertyTemplatePlugin = require("./ExportPropertyTemplatePlugin");
 | |
| 			new ExportPropertyTemplatePlugin(
 | |
| 				this.options.libraryExport,
 | |
| 				"used a library export"
 | |
| 			).apply(compiler);
 | |
| 		} else {
 | |
| 			const FlagEntryExportAsUsedPlugin = require("./FlagEntryExportAsUsedPlugin");
 | |
| 			new FlagEntryExportAsUsedPlugin(
 | |
| 				this.options.libraryTarget !== "module",
 | |
| 				"used a library export"
 | |
| 			).apply(compiler);
 | |
| 		}
 | |
| 		switch (this.options.libraryTarget) {
 | |
| 			case "umd":
 | |
| 			case "umd2": {
 | |
| 				const UmdTemplatePlugin = require("./UmdTemplatePlugin");
 | |
| 				new UmdTemplatePlugin(this.options.library, {
 | |
| 					optionalAmdExternalAsGlobal: this.options.libraryTarget === "umd2",
 | |
| 					namedDefine: this.options.umdNamedDefine,
 | |
| 					auxiliaryComment: this.options.auxiliaryComment || ""
 | |
| 				}).apply(compiler);
 | |
| 				break;
 | |
| 			}
 | |
| 			case "amd":
 | |
| 			case "amd-require": {
 | |
| 				const AmdTemplatePlugin = require("./AmdTemplatePlugin");
 | |
| 				new AmdTemplatePlugin({
 | |
| 					name: this.options.library,
 | |
| 					requireAsWrapper: this.options.libraryTarget === "amd-require"
 | |
| 				}).apply(compiler);
 | |
| 				break;
 | |
| 			}
 | |
| 			case "var":
 | |
| 				if (
 | |
| 					!this.options.library ||
 | |
| 					(typeof this.options.library === "object" &&
 | |
| 						!Array.isArray(this.options.library))
 | |
| 				) {
 | |
| 					throw new Error(
 | |
| 						"library name must be set and not an UMD custom object for non-UMD target"
 | |
| 					);
 | |
| 				}
 | |
| 				new SetVarTemplatePlugin(
 | |
| 					`var ${accessorAccess(undefined, this.options.library, "root")}`,
 | |
| 					false
 | |
| 				).apply(compiler);
 | |
| 				break;
 | |
| 			case "assign":
 | |
| 				new SetVarTemplatePlugin(
 | |
| 					accessorAccess(undefined, this.options.library, "root"),
 | |
| 					false
 | |
| 				).apply(compiler);
 | |
| 				break;
 | |
| 			case "this":
 | |
| 			case "self":
 | |
| 			case "window":
 | |
| 				if (this.options.library) {
 | |
| 					new SetVarTemplatePlugin(
 | |
| 						accessorAccess(
 | |
| 							this.options.libraryTarget,
 | |
| 							this.options.library,
 | |
| 							"root"
 | |
| 						),
 | |
| 						false
 | |
| 					).apply(compiler);
 | |
| 				} else {
 | |
| 					new SetVarTemplatePlugin(this.options.libraryTarget, true).apply(
 | |
| 						compiler
 | |
| 					);
 | |
| 				}
 | |
| 				break;
 | |
| 			case "global": {
 | |
| 				const globalObject =
 | |
| 					this.options.globalObject || compiler.options.output.globalObject;
 | |
| 				if (this.options.library) {
 | |
| 					new SetVarTemplatePlugin(
 | |
| 						accessorAccess(globalObject, this.options.library, "root"),
 | |
| 						false
 | |
| 					).apply(compiler);
 | |
| 				} else {
 | |
| 					new SetVarTemplatePlugin(globalObject, true).apply(compiler);
 | |
| 				}
 | |
| 				break;
 | |
| 			}
 | |
| 			case "commonjs":
 | |
| 				if (this.options.library) {
 | |
| 					new SetVarTemplatePlugin(
 | |
| 						accessorAccess("exports", this.options.library, "commonjs"),
 | |
| 						false
 | |
| 					).apply(compiler);
 | |
| 				} else {
 | |
| 					new SetVarTemplatePlugin("exports", true).apply(compiler);
 | |
| 				}
 | |
| 				break;
 | |
| 			case "commonjs2":
 | |
| 			case "commonjs-module":
 | |
| 				new SetVarTemplatePlugin("module.exports", false).apply(compiler);
 | |
| 				break;
 | |
| 			case "jsonp": {
 | |
| 				if (!this.options.library || typeof this.options.library === "object") {
 | |
| 					throw new Error(
 | |
| 						"library name must be set and not an array or UMD custom object for non-UMD target"
 | |
| 					);
 | |
| 				}
 | |
| 				const JsonpExportTemplatePlugin = require("./web/JsonpExportTemplatePlugin");
 | |
| 				new JsonpExportTemplatePlugin(this.options.library).apply(compiler);
 | |
| 				break;
 | |
| 			}
 | |
| 			case "system": {
 | |
| 				const SystemTemplatePlugin = require("./SystemTemplatePlugin");
 | |
| 				new SystemTemplatePlugin({
 | |
| 					name: this.options.library
 | |
| 				}).apply(compiler);
 | |
| 				break;
 | |
| 			}
 | |
| 			case "module":
 | |
| 				// TODO
 | |
| 				break;
 | |
| 			default:
 | |
| 				throw new Error(
 | |
| 					`${this.options.libraryTarget} is not a valid Library target`
 | |
| 				);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| module.exports = LibraryTemplatePlugin;
 |