| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const path = require("path");const OptionsDefaulter = require("./OptionsDefaulter");const Template = require("./Template");const isProductionLikeMode = options => {	return options.mode === "production" || !options.mode;};const isWebLikeTarget = options => {	return options.target === "web" || options.target === "webworker";};const getDevtoolNamespace = library => {	// if options.output.library is a string	if (Array.isArray(library)) {		return library.join(".");	} else if (typeof library === "object") {		return getDevtoolNamespace(library.root);	}	return library || "";};class WebpackOptionsDefaulter extends OptionsDefaulter {	constructor() {		super();		this.set("entry", "./src");		this.set("devtool", "make", options =>			options.mode === "development" ? "eval" : false		);		this.set("cache", "make", options => options.mode === "development");		this.set("context", process.cwd());		this.set("target", "web");		this.set("module", "call", value => Object.assign({}, value));		this.set("module.unknownContextRequest", ".");		this.set("module.unknownContextRegExp", false);		this.set("module.unknownContextRecursive", true);		this.set("module.unknownContextCritical", true);		this.set("module.exprContextRequest", ".");		this.set("module.exprContextRegExp", false);		this.set("module.exprContextRecursive", true);		this.set("module.exprContextCritical", true);		this.set("module.wrappedContextRegExp", /.*/);		this.set("module.wrappedContextRecursive", true);		this.set("module.wrappedContextCritical", false);		this.set("module.strictExportPresence", false);		this.set("module.strictThisContextOnImports", false);		this.set("module.unsafeCache", "make", options => !!options.cache);		this.set("module.rules", []);		this.set("module.defaultRules", "make", options => [			{				type: "javascript/auto",				resolve: {}			},			{				test: /\.mjs$/i,				type: "javascript/esm",				resolve: {					mainFields:						options.target === "web" ||						options.target === "webworker" ||						options.target === "electron-renderer"							? ["browser", "main"]							: ["main"]				}			},			{				test: /\.json$/i,				type: "json"			},			{				test: /\.wasm$/i,				type: "webassembly/experimental"			}		]);		this.set("output", "call", (value, options) => {			if (typeof value === "string") {				return {					filename: value				};			} else if (typeof value !== "object") {				return {};			} else {				return Object.assign({}, value);			}		});		this.set("output.filename", "[name].js");		this.set("output.chunkFilename", "make", options => {			const filename = options.output.filename;			if (typeof filename !== "function") {				const hasName = filename.includes("[name]");				const hasId = filename.includes("[id]");				const hasChunkHash = filename.includes("[chunkhash]");				// Anything changing depending on chunk is fine				if (hasChunkHash || hasName || hasId) return filename;				// Elsewise prefix "[id]." in front of the basename to make it changing				return filename.replace(/(^|\/)([^/]*(?:\?|$))/, "$1[id].$2");			}			return "[id].js";		});		this.set("output.webassemblyModuleFilename", "[modulehash].module.wasm");		this.set("output.library", "");		this.set("output.hotUpdateFunction", "make", options => {			return Template.toIdentifier(				"webpackHotUpdate" + Template.toIdentifier(options.output.library)			);		});		this.set("output.jsonpFunction", "make", options => {			return Template.toIdentifier(				"webpackJsonp" + Template.toIdentifier(options.output.library)			);		});		this.set("output.chunkCallbackName", "make", options => {			return Template.toIdentifier(				"webpackChunk" + Template.toIdentifier(options.output.library)			);		});		this.set("output.globalObject", "make", options => {			switch (options.target) {				case "web":				case "electron-renderer":				case "node-webkit":					return "window";				case "webworker":					return "self";				case "node":				case "async-node":				case "electron-main":					return "global";				default:					return "self";			}		});		this.set("output.devtoolNamespace", "make", options => {			return getDevtoolNamespace(options.output.library);		});		this.set("output.libraryTarget", "var");		this.set("output.path", path.join(process.cwd(), "dist"));		this.set(			"output.pathinfo",			"make",			options => options.mode === "development"		);		this.set("output.sourceMapFilename", "[file].map[query]");		this.set("output.hotUpdateChunkFilename", "[id].[hash].hot-update.js");		this.set("output.hotUpdateMainFilename", "[hash].hot-update.json");		this.set("output.crossOriginLoading", false);		this.set("output.jsonpScriptType", false);		this.set("output.chunkLoadTimeout", 120000);		this.set("output.hashFunction", "md4");		this.set("output.hashDigest", "hex");		this.set("output.hashDigestLength", 20);		this.set("output.devtoolLineToLine", false);		this.set("output.strictModuleExceptionHandling", false);		this.set("node", "call", value => {			if (typeof value === "boolean") {				return value;			} else {				return Object.assign({}, value);			}		});		this.set("node.console", false);		this.set("node.process", true);		this.set("node.global", true);		this.set("node.Buffer", true);		this.set("node.setImmediate", true);		this.set("node.__filename", "mock");		this.set("node.__dirname", "mock");		this.set("performance", "call", (value, options) => {			if (value === false) return false;			if (				value === undefined &&				(!isProductionLikeMode(options) || !isWebLikeTarget(options))			)				return false;			return Object.assign({}, value);		});		this.set("performance.maxAssetSize", 250000);		this.set("performance.maxEntrypointSize", 250000);		this.set("performance.hints", "make", options =>			isProductionLikeMode(options) ? "warning" : false		);		this.set("optimization", "call", value => Object.assign({}, value));		// TODO webpack 5: Disable by default in a modes		this.set(			"optimization.removeAvailableModules",			"make",			options => options.mode !== "development"		);		this.set("optimization.removeEmptyChunks", true);		this.set("optimization.mergeDuplicateChunks", true);		this.set("optimization.flagIncludedChunks", "make", options =>			isProductionLikeMode(options)		);		// TODO webpack 5 add `moduleIds: "named"` default for development		// TODO webpack 5 add `moduleIds: "size"` default for production		// TODO webpack 5 remove optimization.occurrenceOrder		this.set("optimization.occurrenceOrder", "make", options =>			isProductionLikeMode(options)		);		this.set("optimization.sideEffects", "make", options =>			isProductionLikeMode(options)		);		this.set("optimization.providedExports", true);		this.set("optimization.usedExports", "make", options =>			isProductionLikeMode(options)		);		this.set("optimization.concatenateModules", "make", options =>			isProductionLikeMode(options)		);		this.set("optimization.splitChunks", {});		this.set("optimization.splitChunks.hidePathInfo", "make", options => {			return isProductionLikeMode(options);		});		this.set("optimization.splitChunks.chunks", "async");		this.set("optimization.splitChunks.minSize", "make", options => {			return isProductionLikeMode(options) ? 30000 : 10000;		});		this.set("optimization.splitChunks.minChunks", 1);		this.set("optimization.splitChunks.maxAsyncRequests", "make", options => {			return isProductionLikeMode(options) ? 5 : Infinity;		});		this.set("optimization.splitChunks.automaticNameDelimiter", "~");		this.set("optimization.splitChunks.automaticNameMaxLength", 109);		this.set("optimization.splitChunks.maxInitialRequests", "make", options => {			return isProductionLikeMode(options) ? 3 : Infinity;		});		this.set("optimization.splitChunks.name", true);		this.set("optimization.splitChunks.cacheGroups", {});		this.set("optimization.splitChunks.cacheGroups.default", {			automaticNamePrefix: "",			reuseExistingChunk: true,			minChunks: 2,			priority: -20		});		this.set("optimization.splitChunks.cacheGroups.vendors", {			automaticNamePrefix: "vendors",			test: /[\\/]node_modules[\\/]/,			priority: -10		});		this.set("optimization.runtimeChunk", "call", value => {			if (value === "single") {				return {					name: "runtime"				};			}			if (value === true || value === "multiple") {				return {					name: entrypoint => `runtime~${entrypoint.name}`				};			}			return value;		});		this.set("optimization.noEmitOnErrors", "make", options =>			isProductionLikeMode(options)		);		this.set("optimization.checkWasmTypes", "make", options =>			isProductionLikeMode(options)		);		this.set("optimization.mangleWasmImports", false);		// TODO webpack 5 remove optimization.namedModules		this.set(			"optimization.namedModules",			"make",			options => options.mode === "development"		);		this.set("optimization.hashedModuleIds", false);		// TODO webpack 5 add `chunkIds: "named"` default for development		// TODO webpack 5 add `chunkIds: "size"` default for production		// TODO webpack 5 remove optimization.namedChunks		this.set(			"optimization.namedChunks",			"make",			options => options.mode === "development"		);		this.set(			"optimization.portableRecords",			"make",			options =>				!!(					options.recordsInputPath ||					options.recordsOutputPath ||					options.recordsPath				)		);		this.set("optimization.minimize", "make", options =>			isProductionLikeMode(options)		);		this.set("optimization.minimizer", "make", options => [			{				apply: compiler => {					// Lazy load the Terser plugin					const TerserPlugin = require("terser-webpack-plugin");					const SourceMapDevToolPlugin = require("./SourceMapDevToolPlugin");					new TerserPlugin({						cache: true,						parallel: true,						sourceMap:							(options.devtool && /source-?map/.test(options.devtool)) ||							(options.plugins &&								options.plugins.some(p => p instanceof SourceMapDevToolPlugin))					}).apply(compiler);				}			}		]);		this.set("optimization.nodeEnv", "make", options => {			// TODO: In webpack 5, it should return `false` when mode is `none`			return options.mode || "production";		});		this.set("resolve", "call", value => Object.assign({}, value));		this.set("resolve.unsafeCache", true);		this.set("resolve.modules", ["node_modules"]);		this.set("resolve.extensions", [".wasm", ".mjs", ".js", ".json"]);		this.set("resolve.mainFiles", ["index"]);		this.set("resolve.aliasFields", "make", options => {			if (				options.target === "web" ||				options.target === "webworker" ||				options.target === "electron-renderer"			) {				return ["browser"];			} else {				return [];			}		});		this.set("resolve.mainFields", "make", options => {			if (				options.target === "web" ||				options.target === "webworker" ||				options.target === "electron-renderer"			) {				return ["browser", "module", "main"];			} else {				return ["module", "main"];			}		});		this.set("resolve.cacheWithContext", "make", options => {			return (				Array.isArray(options.resolve.plugins) &&				options.resolve.plugins.length > 0			);		});		this.set(			"resolve.preferAbsolute",			"make",			options => !options.resolve.roots || options.resolve.roots.length === 0		);		this.set(			"resolve.ignoreRootsErrors",			"make",			options => !options.resolve.roots || options.resolve.roots.length === 0		);		this.set("resolve.roots", "make", options => [options.context]);		this.set("resolveLoader", "call", value => Object.assign({}, value));		this.set("resolveLoader.unsafeCache", true);		this.set("resolveLoader.mainFields", ["loader", "main"]);		this.set("resolveLoader.extensions", [".js", ".json"]);		this.set("resolveLoader.mainFiles", ["index"]);		this.set("resolveLoader.cacheWithContext", "make", options => {			return (				Array.isArray(options.resolveLoader.plugins) &&				options.resolveLoader.plugins.length > 0			);		});		this.set("infrastructureLogging", "call", value =>			Object.assign({}, value)		);		this.set("infrastructureLogging.level", "info");		this.set("infrastructureLogging.debug", false);	}}module.exports = WebpackOptionsDefaulter;
 |