2020-02-17 17:27:46 +08:00
/ *
MIT License http : //www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @ sokra
* /
"use strict" ;
2021-02-02 21:01:20 +08:00
const fs = require ( "fs" ) ;
2020-02-17 17:27:46 +08:00
const path = require ( "path" ) ;
const Template = require ( "../Template" ) ;
2020-07-11 16:30:18 +08:00
const { cleverMerge } = require ( "../util/cleverMerge" ) ;
2020-09-28 19:42:55 +08:00
const {
getTargetsProperties ,
getTargetProperties ,
getDefaultTarget
} = require ( "./target" ) ;
2020-02-17 17:27:46 +08:00
2020-03-21 21:01:38 +08:00
/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */
2021-01-05 18:11:02 +08:00
/** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */
2020-09-09 21:16:53 +08:00
/** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */
2020-02-17 17:27:46 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */
2020-09-09 21:16:53 +08:00
/** @typedef {import("../../declarations/WebpackOptions").ExternalsPresets} ExternalsPresets */
2020-08-26 03:45:56 +08:00
/** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */
2020-02-17 17:27:46 +08:00
/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
2021-01-05 18:11:02 +08:00
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
2020-02-20 03:25:49 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Library} Library */
/** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
2020-09-09 21:54:13 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Loader} Loader */
2020-05-25 18:58:59 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Mode} Mode */
2021-01-20 22:08:58 +08:00
/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
2020-02-17 17:27:46 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Node} WebpackNode */
/** @typedef {import("../../declarations/WebpackOptions").Optimization} Optimization */
2020-09-09 21:16:53 +08:00
/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */
2020-02-17 17:27:46 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Performance} Performance */
/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */
2020-08-26 06:36:16 +08:00
/** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
2020-02-17 17:27:46 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Target} Target */
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
2020-09-10 16:42:29 +08:00
/** @typedef {import("./target").TargetProperties} TargetProperties */
2020-02-17 17:27:46 +08:00
const NODE _MODULES _REGEXP = /[\\/]node_modules[\\/]/i ;
/ * *
* Sets a constant default value when undefined
* @ template T
* @ template { keyof T } P
* @ param { T } obj an object
* @ param { P } prop a property of this object
* @ param { T [ P ] } value a default value of the property
* @ returns { void }
* /
const D = ( obj , prop , value ) => {
if ( obj [ prop ] === undefined ) {
obj [ prop ] = value ;
}
} ;
/ * *
* Sets a dynamic default value when undefined , by calling the factory function
* @ template T
* @ template { keyof T } P
* @ param { T } obj an object
* @ param { P } prop a property of this object
* @ param { function ( ) : T [ P ] } factory a default value factory for the property
* @ returns { void }
* /
const F = ( obj , prop , factory ) => {
if ( obj [ prop ] === undefined ) {
obj [ prop ] = factory ( ) ;
}
} ;
2020-07-11 16:30:18 +08:00
/ * *
* Sets a dynamic default value when undefined , by calling the factory function .
* factory must return an array or undefined
* When the current value is already an array an contains "..." it ' s replaced with
* the result of the factory function
* @ template T
* @ template { keyof T } P
* @ param { T } obj an object
* @ param { P } prop a property of this object
* @ param { function ( ) : T [ P ] } factory a default value factory for the property
* @ returns { void }
* /
const A = ( obj , prop , factory ) => {
const value = obj [ prop ] ;
if ( value === undefined ) {
obj [ prop ] = factory ( ) ;
2020-07-13 20:28:55 +08:00
} else if ( Array . isArray ( value ) ) {
/** @type {any[]} */
let newArray = undefined ;
for ( let i = 0 ; i < value . length ; i ++ ) {
const item = value [ i ] ;
2020-07-11 16:30:18 +08:00
if ( item === "..." ) {
2020-07-13 20:28:55 +08:00
if ( newArray === undefined ) {
2021-02-22 16:03:12 +08:00
newArray = value . slice ( 0 , i ) ;
2020-07-13 20:28:55 +08:00
obj [ prop ] = /** @type {T[P]} */ ( /** @type {unknown} */ ( newArray ) ) ;
}
2020-07-11 16:30:18 +08:00
const items = /** @type {any[]} */ ( /** @type {unknown} */ ( factory ( ) ) ) ;
if ( items !== undefined ) {
for ( const item of items ) {
newArray . push ( item ) ;
}
}
2020-07-13 20:28:55 +08:00
} else if ( newArray !== undefined ) {
2020-07-11 16:30:18 +08:00
newArray . push ( item ) ;
}
}
}
} ;
2020-02-17 17:27:46 +08:00
/ * *
* @ param { WebpackOptions } options options to be modified
* @ returns { void }
* /
const applyWebpackOptionsBaseDefaults = options => {
F ( options , "context" , ( ) => process . cwd ( ) ) ;
2021-04-06 21:20:27 +08:00
applyInfrastructureLoggingDefaults ( options . infrastructureLogging ) ;
2020-02-17 17:27:46 +08:00
} ;
/ * *
* @ param { WebpackOptions } options options to be modified
* @ returns { void }
* /
const applyWebpackOptionsDefaults = options => {
F ( options , "context" , ( ) => process . cwd ( ) ) ;
2020-09-28 19:42:55 +08:00
F ( options , "target" , ( ) => {
return getDefaultTarget ( options . context ) ;
} ) ;
2020-02-17 17:27:46 +08:00
const { mode , name , target } = options ;
2020-09-10 16:42:29 +08:00
let targetProperties =
target === false
? /** @type {false} */ ( false )
: typeof target === "string"
2020-09-28 16:52:52 +08:00
? getTargetProperties ( target , options . context )
: getTargetsProperties ( target , options . context ) ;
2020-09-10 16:42:29 +08:00
2020-02-17 17:27:46 +08:00
const development = mode === "development" ;
const production = mode === "production" || ! mode ;
2020-06-04 08:06:57 +08:00
if ( typeof options . entry !== "function" ) {
for ( const key of Object . keys ( options . entry ) ) {
F (
options . entry [ key ] ,
"import" ,
( ) => /** @type {[string]} */ ( [ "./src" ] )
) ;
}
2020-02-17 17:27:46 +08:00
}
F ( options , "devtool" , ( ) => ( development ? "eval" : false ) ) ;
D ( options , "watch" , false ) ;
D ( options , "profile" , false ) ;
D ( options , "parallelism" , 100 ) ;
D ( options , "recordsInputPath" , false ) ;
D ( options , "recordsOutputPath" , false ) ;
2021-09-24 17:35:28 +08:00
applyExperimentsDefaults ( options . experiments , { production , development } ) ;
2021-10-18 22:07:41 +08:00
const futureDefaults = options . experiments . futureDefaults ;
2020-02-17 17:27:46 +08:00
F ( options , "cache" , ( ) =>
development ? { type : /** @type {"memory"} */ ( "memory" ) } : false
) ;
applyCacheDefaults ( options . cache , {
name : name || "default" ,
2021-04-01 22:59:00 +08:00
mode : mode || "production" ,
2021-09-24 17:35:28 +08:00
development ,
cacheUnaffected : options . experiments . cacheUnaffected
2020-02-17 17:27:46 +08:00
} ) ;
const cache = ! ! options . cache ;
2021-10-18 22:07:41 +08:00
applySnapshotDefaults ( options . snapshot , {
production ,
futureDefaults
} ) ;
2020-08-26 06:36:16 +08:00
2020-02-17 17:27:46 +08:00
applyModuleDefaults ( options . module , {
cache ,
syncWebAssembly : options . experiments . syncWebAssembly ,
2020-09-10 16:42:29 +08:00
asyncWebAssembly : options . experiments . asyncWebAssembly
2020-02-17 17:27:46 +08:00
} ) ;
applyOutputDefaults ( options . output , {
2020-02-26 22:50:38 +08:00
context : options . context ,
2020-09-10 16:42:29 +08:00
targetProperties ,
2021-06-23 19:58:40 +08:00
isAffectedByBrowserslist :
target === undefined ||
( typeof target === "string" && target . startsWith ( "browserslist" ) ) ||
( Array . isArray ( target ) &&
target . some ( target => target . startsWith ( "browserslist" ) ) ) ,
2020-02-17 17:27:46 +08:00
outputModule : options . experiments . outputModule ,
2020-09-09 21:16:53 +08:00
development ,
2021-01-05 18:11:02 +08:00
entry : options . entry ,
2021-09-23 21:04:22 +08:00
module : options . module ,
2021-10-18 22:07:41 +08:00
futureDefaults
2020-09-09 15:23:01 +08:00
} ) ;
2021-08-04 21:55:58 +08:00
applyExternalsPresetsDefaults ( options . externalsPresets , {
targetProperties ,
buildHttp : ! ! options . experiments . buildHttp
} ) ;
2020-02-20 03:25:49 +08:00
2020-09-10 16:42:29 +08:00
applyLoaderDefaults ( options . loader , { targetProperties } ) ;
2020-09-09 21:54:13 +08:00
2020-08-26 03:45:56 +08:00
F ( options , "externalsType" , ( ) => {
const validExternalTypes = require ( "../../schemas/WebpackOptions.json" )
. definitions . ExternalsType . enum ;
return options . output . library &&
validExternalTypes . includes ( options . output . library . type )
? /** @type {ExternalsType} */ ( options . output . library . type )
2020-02-20 03:25:49 +08:00
: options . output . module
? "module"
2020-08-26 03:45:56 +08:00
: "var" ;
} ) ;
2020-02-18 17:44:55 +08:00
2021-09-12 00:15:27 +08:00
applyNodeDefaults ( options . node , {
futureDefaults : options . experiments . futureDefaults ,
targetProperties
} ) ;
2020-02-17 17:27:46 +08:00
2020-09-10 16:42:29 +08:00
F ( options , "performance" , ( ) =>
production &&
targetProperties &&
( targetProperties . browser || targetProperties . browser === null )
? { }
: false
) ;
2020-02-17 17:27:46 +08:00
applyPerformanceDefaults ( options . performance , {
production
} ) ;
applyOptimizationDefaults ( options . optimization , {
development ,
production ,
records : ! ! ( options . recordsInputPath || options . recordsOutputPath )
} ) ;
2020-07-11 16:30:18 +08:00
options . resolve = cleverMerge (
getResolveDefaults ( {
cache ,
context : options . context ,
2020-09-10 16:42:29 +08:00
targetProperties ,
2020-07-11 16:30:18 +08:00
mode : options . mode
} ) ,
options . resolve
) ;
options . resolveLoader = cleverMerge (
2020-07-13 23:15:20 +08:00
getResolveLoaderDefaults ( { cache } ) ,
2020-07-11 16:30:18 +08:00
options . resolveLoader
) ;
2020-02-17 17:27:46 +08:00
} ;
/ * *
* @ param { Experiments } experiments options
2021-08-04 21:55:58 +08:00
* @ param { Object } options options
* @ param { boolean } options . production is production
* @ param { boolean } options . development is development mode
2020-02-17 17:27:46 +08:00
* @ returns { void }
* /
2021-08-04 21:55:58 +08:00
const applyExperimentsDefaults = ( experiments , { production , development } ) => {
2020-02-17 17:27:46 +08:00
D ( experiments , "topLevelAwait" , false ) ;
D ( experiments , "syncWebAssembly" , false ) ;
D ( experiments , "asyncWebAssembly" , false ) ;
D ( experiments , "outputModule" , false ) ;
2021-08-04 21:55:58 +08:00
D ( experiments , "asset" , false ) ;
D ( experiments , "layers" , false ) ;
D ( experiments , "lazyCompilation" , false ) ;
D ( experiments , "buildHttp" , false ) ;
2021-09-12 00:15:27 +08:00
D ( experiments , "futureDefaults" , false ) ;
2021-09-24 17:35:28 +08:00
D ( experiments , "cacheUnaffected" , experiments . futureDefaults ) ;
2021-08-04 21:55:58 +08:00
if ( typeof experiments . buildHttp === "object" ) {
D ( experiments . buildHttp , "frozen" , production ) ;
D ( experiments . buildHttp , "upgrade" , development ) ;
}
2020-02-17 17:27:46 +08:00
} ;
/ * *
2020-03-21 21:01:38 +08:00
* @ param { CacheOptions } cache options
2020-02-17 17:27:46 +08:00
* @ param { Object } options options
* @ param { string } options . name name
* @ param { string } options . mode mode
2021-04-01 22:59:00 +08:00
* @ param { boolean } options . development is development mode
2021-09-24 17:35:28 +08:00
* @ param { boolean } options . cacheUnaffected the cacheUnaffected experiment is enabled
2020-02-17 17:27:46 +08:00
* @ returns { void }
* /
2021-09-24 17:35:28 +08:00
const applyCacheDefaults = (
cache ,
{ name , mode , development , cacheUnaffected }
) => {
2020-02-17 17:27:46 +08:00
if ( cache === false ) return ;
switch ( cache . type ) {
case "filesystem" :
F ( cache , "name" , ( ) => name + "-" + mode ) ;
D ( cache , "version" , "" ) ;
F ( cache , "cacheDirectory" , ( ) => {
const cwd = process . cwd ( ) ;
2021-02-02 21:01:20 +08:00
let dir = cwd ;
for ( ; ; ) {
try {
2021-02-02 21:22:36 +08:00
if ( fs . statSync ( path . join ( dir , "package.json" ) ) . isFile ( ) ) break ;
2021-02-02 21:01:20 +08:00
// eslint-disable-next-line no-empty
} catch ( e ) { }
const parent = path . dirname ( dir ) ;
if ( dir === parent ) {
dir = undefined ;
break ;
2021-01-31 00:05:46 +08:00
}
2021-02-06 03:02:01 +08:00
dir = parent ;
2021-02-02 21:01:20 +08:00
}
2020-02-17 17:27:46 +08:00
if ( ! dir ) {
return path . resolve ( cwd , ".cache/webpack" ) ;
} else if ( process . versions . pnp === "1" ) {
return path . resolve ( dir , ".pnp/.cache/webpack" ) ;
2020-02-17 22:48:43 +08:00
} else if ( process . versions . pnp === "3" ) {
return path . resolve ( dir , ".yarn/.cache/webpack" ) ;
2020-02-17 17:27:46 +08:00
} else {
return path . resolve ( dir , "node_modules/.cache/webpack" ) ;
}
} ) ;
F ( cache , "cacheLocation" , ( ) =>
path . resolve ( cache . cacheDirectory , cache . name )
) ;
D ( cache , "hashAlgorithm" , "md4" ) ;
D ( cache , "store" , "pack" ) ;
2021-08-10 19:02:34 +08:00
D ( cache , "compression" , false ) ;
2021-04-27 17:06:01 +08:00
D ( cache , "profile" , false ) ;
2020-02-17 17:27:46 +08:00
D ( cache , "idleTimeout" , 60000 ) ;
2021-06-28 17:35:14 +08:00
D ( cache , "idleTimeoutForInitialStore" , 5000 ) ;
D ( cache , "idleTimeoutAfterLargeChanges" , 1000 ) ;
2021-04-20 21:22:41 +08:00
D ( cache , "maxMemoryGenerations" , development ? 5 : Infinity ) ;
2021-04-01 22:59:00 +08:00
D ( cache , "maxAge" , 1000 * 60 * 60 * 24 * 60 ) ; // 1 month
2021-04-20 21:22:16 +08:00
D ( cache , "allowCollectingMemory" , development ) ;
2021-09-24 17:35:28 +08:00
D ( cache , "memoryCacheUnaffected" , development && cacheUnaffected ) ;
2020-02-17 17:27:46 +08:00
D ( cache . buildDependencies , "defaultWebpack" , [
path . resolve ( _ _dirname , ".." ) + path . sep
] ) ;
break ;
2021-04-01 22:59:00 +08:00
case "memory" :
D ( cache , "maxGenerations" , Infinity ) ;
2021-09-24 17:35:28 +08:00
D ( cache , "cacheUnaffected" , development && cacheUnaffected ) ;
2021-04-01 22:59:00 +08:00
break ;
2020-02-17 17:27:46 +08:00
}
2020-08-26 06:36:16 +08:00
} ;
/ * *
* @ param { SnapshotOptions } snapshot options
* @ param { Object } options options
* @ param { boolean } options . production is production
2021-10-18 22:07:41 +08:00
* @ param { boolean } options . futureDefaults is future defaults enabled
2020-08-26 06:36:16 +08:00
* @ returns { void }
* /
2021-10-18 22:07:41 +08:00
const applySnapshotDefaults = ( snapshot , { production , futureDefaults } ) => {
if ( futureDefaults ) {
F ( snapshot , "managedPaths" , ( ) =>
process . versions . pnp === "3"
? [
/^(.+?(?:[\\/]\.yarn[\\/]unplugged[\\/][^\\/]+)?[\\/]node_modules[\\/])/
]
: [ /^(.+?[\\/]node_modules[\\/])/ ]
) ;
F ( snapshot , "immutablePaths" , ( ) =>
process . versions . pnp === "3"
? [ /^(.+?[\\/]cache[\\/][^\\/]+\.zip[\\/]node_modules[\\/])/ ]
: [ ]
) ;
} else {
A ( snapshot , "managedPaths" , ( ) => {
if ( process . versions . pnp === "3" ) {
const match =
/^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/ . exec (
require . resolve ( "watchpack" )
) ;
if ( match ) {
return [ path . resolve ( match [ 1 ] , "unplugged" ) ] ;
}
} else {
const match = /^(.+?[\\/]node_modules)[\\/]/ . exec (
// eslint-disable-next-line node/no-extraneous-require
2021-05-11 15:31:46 +08:00
require . resolve ( "watchpack" )
) ;
2021-10-18 22:07:41 +08:00
if ( match ) {
return [ match [ 1 ] ] ;
}
2020-02-17 17:27:46 +08:00
}
2021-10-18 22:07:41 +08:00
return [ ] ;
} ) ;
A ( snapshot , "immutablePaths" , ( ) => {
if ( process . versions . pnp === "1" ) {
const match =
/^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/ . exec (
require . resolve ( "watchpack" )
) ;
if ( match ) {
return [ match [ 1 ] ] ;
}
} else if ( process . versions . pnp === "3" ) {
const match =
/^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/ . exec (
require . resolve ( "watchpack" )
) ;
if ( match ) {
return [ match [ 1 ] ] ;
}
2020-02-17 22:48:43 +08:00
}
2021-10-18 22:07:41 +08:00
return [ ] ;
} ) ;
}
2020-08-26 06:36:16 +08:00
F ( snapshot , "resolveBuildDependencies" , ( ) => ( {
timestamp : true ,
hash : true
} ) ) ;
F ( snapshot , "buildDependencies" , ( ) => ( { timestamp : true , hash : true } ) ) ;
F ( snapshot , "module" , ( ) =>
production ? { timestamp : true , hash : true } : { timestamp : true }
) ;
F ( snapshot , "resolve" , ( ) =>
production ? { timestamp : true , hash : true } : { timestamp : true }
) ;
2020-02-17 17:27:46 +08:00
} ;
2021-01-05 18:11:02 +08:00
/ * *
2021-01-20 22:08:58 +08:00
* @ param { JavascriptParserOptions } parserOptions parser options
2021-01-05 18:11:02 +08:00
* @ returns { void }
* /
2021-01-20 22:08:58 +08:00
const applyJavascriptParserOptionsDefaults = parserOptions => {
D ( parserOptions , "unknownContextRequest" , "." ) ;
D ( parserOptions , "unknownContextRegExp" , false ) ;
D ( parserOptions , "unknownContextRecursive" , true ) ;
D ( parserOptions , "unknownContextCritical" , true ) ;
D ( parserOptions , "exprContextRequest" , "." ) ;
D ( parserOptions , "exprContextRegExp" , false ) ;
D ( parserOptions , "exprContextRecursive" , true ) ;
D ( parserOptions , "exprContextCritical" , true ) ;
D ( parserOptions , "wrappedContextRegExp" , /.*/ ) ;
D ( parserOptions , "wrappedContextRecursive" , true ) ;
D ( parserOptions , "wrappedContextCritical" , false ) ;
D ( parserOptions , "strictExportPresence" , false ) ;
D ( parserOptions , "strictThisContextOnImports" , false ) ;
} ;
2021-01-05 18:11:02 +08:00
2020-02-17 17:27:46 +08:00
/ * *
2020-03-21 21:01:38 +08:00
* @ param { ModuleOptions } module options
2020-02-17 17:27:46 +08:00
* @ param { Object } options options
* @ param { boolean } options . cache is caching enabled
* @ param { boolean } options . syncWebAssembly is syncWebAssembly enabled
* @ param { boolean } options . asyncWebAssembly is asyncWebAssembly enabled
* @ returns { void }
* /
const applyModuleDefaults = (
module ,
2020-09-10 16:42:29 +08:00
{ cache , syncWebAssembly , asyncWebAssembly }
2020-02-17 17:27:46 +08:00
) => {
if ( cache ) {
D ( module , "unsafeCache" , module => {
const name = module . nameForCondition ( ) ;
return name && NODE _MODULES _REGEXP . test ( name ) ;
} ) ;
} else {
D ( module , "unsafeCache" , false ) ;
}
2021-01-05 18:11:02 +08:00
F ( module . parser , "asset" , ( ) => ( { } ) ) ;
F ( module . parser . asset , "dataUrlCondition" , ( ) => ( { } ) ) ;
if ( typeof module . parser . asset . dataUrlCondition === "object" ) {
D ( module . parser . asset . dataUrlCondition , "maxSize" , 8096 ) ;
}
F ( module . parser , "javascript" , ( ) => ( { } ) ) ;
applyJavascriptParserOptionsDefaults ( module . parser . javascript ) ;
2020-07-11 16:30:18 +08:00
A ( module , "defaultRules" , ( ) => {
2020-09-02 20:41:04 +08:00
const esm = {
type : "javascript/esm" ,
resolve : {
byDependency : {
esm : {
fullySpecified : true
}
}
}
} ;
const commonjs = {
type : "javascript/dynamic"
} ;
2020-02-17 17:27:46 +08:00
/** @type {RuleSetRules} */
const rules = [
2020-07-17 16:27:48 +08:00
{
mimetype : "application/node" ,
type : "javascript/auto"
2020-02-17 17:27:46 +08:00
} ,
2020-08-05 05:42:29 +08:00
{
2020-02-17 17:27:46 +08:00
test : /\.json$/i ,
2021-06-17 18:20:39 +08:00
type : "json"
2020-05-18 15:00:28 +08:00
} ,
{
mimetype : "application/json" ,
2021-06-17 18:20:39 +08:00
type : "json"
2020-09-02 21:07:15 +08:00
} ,
{
2020-09-02 20:41:04 +08:00
test : /\.mjs$/i ,
... esm
} ,
{
test : /\.js$/i ,
descriptionData : {
type : "module"
2020-07-17 16:27:48 +08:00
} ,
2020-09-02 20:41:04 +08:00
... esm
} ,
{
test : /\.cjs$/i ,
... commonjs
} ,
{
test : /\.js$/i ,
descriptionData : {
type : "commonjs"
2020-07-17 16:27:48 +08:00
} ,
2020-09-02 20:41:04 +08:00
... commonjs
} ,
{
2020-06-05 19:41:25 +08:00
mimetype : {
2020-07-17 16:27:48 +08:00
or : [ "text/javascript" , "application/javascript" ]
2020-06-05 19:41:25 +08:00
} ,
2020-09-02 20:41:04 +08:00
... esm
}
] ;
2020-02-17 17:27:46 +08:00
if ( asyncWebAssembly ) {
2020-07-17 21:57:56 +08:00
const wasm = {
2020-09-02 20:41:04 +08:00
type : "webassembly/async" ,
rules : [
2020-07-17 21:57:56 +08:00
{
descriptionData : {
type : "module"
} ,
resolve : {
fullySpecified : true
}
}
2020-09-02 20:41:04 +08:00
]
} ;
2020-02-17 17:27:46 +08:00
rules . push ( {
test : /\.wasm$/i ,
2020-07-17 21:57:56 +08:00
... wasm
2020-02-17 17:27:46 +08:00
} ) ;
2020-05-18 15:00:28 +08:00
rules . push ( {
mimetype : "application/wasm" ,
2020-07-17 21:57:56 +08:00
... wasm
2020-05-18 15:00:28 +08:00
} ) ;
2020-02-17 17:27:46 +08:00
} else if ( syncWebAssembly ) {
2020-07-17 21:57:56 +08:00
const wasm = {
2020-09-02 20:41:04 +08:00
type : "webassembly/sync" ,
rules : [
2020-07-17 21:57:56 +08:00
{
descriptionData : {
type : "module"
} ,
resolve : {
fullySpecified : true
}
}
2020-09-02 20:41:04 +08:00
]
} ;
2020-02-17 17:27:46 +08:00
rules . push ( {
test : /\.wasm$/i ,
2020-07-17 21:57:56 +08:00
... wasm
2020-02-17 17:27:46 +08:00
} ) ;
2020-05-18 15:00:28 +08:00
rules . push ( {
mimetype : "application/wasm" ,
2020-07-17 21:57:56 +08:00
... wasm
2020-05-18 15:00:28 +08:00
} ) ;
2020-02-17 17:27:46 +08:00
}
2021-07-17 04:16:06 +08:00
rules . push (
{
dependency : "url" ,
oneOf : [
{
scheme : /^data$/ ,
type : "asset/inline"
} ,
{
type : "asset/resource"
}
]
} ,
{
assert : { type : "json" } ,
type : "json"
}
) ;
2020-02-17 17:27:46 +08:00
return rules ;
} ) ;
} ;
/ * *
* @ param { Output } output options
* @ param { Object } options options
2020-02-26 22:50:38 +08:00
* @ param { string } options . context context
2020-09-10 16:42:29 +08:00
* @ param { TargetProperties | false } options . targetProperties target properties
2021-06-23 19:58:40 +08:00
* @ param { boolean } options . isAffectedByBrowserslist is affected by browserslist
2020-02-17 17:27:46 +08:00
* @ param { boolean } options . outputModule is outputModule experiment enabled
* @ param { boolean } options . development is development mode
2020-09-09 21:16:53 +08:00
* @ param { Entry } options . entry entry option
2021-01-05 18:11:02 +08:00
* @ param { ModuleOptions } options . module module option
2021-09-23 21:04:22 +08:00
* @ param { boolean } options . futureDefaults is future defaults enabled
2020-02-17 17:27:46 +08:00
* @ returns { void }
* /
2020-02-26 22:50:38 +08:00
const applyOutputDefaults = (
output ,
2021-06-23 19:58:40 +08:00
{
context ,
targetProperties : tp ,
isAffectedByBrowserslist ,
outputModule ,
development ,
entry ,
2021-09-23 21:04:22 +08:00
module ,
futureDefaults
2021-06-23 19:58:40 +08:00
}
2020-02-26 22:50:38 +08:00
) => {
2020-02-20 03:25:49 +08:00
/ * *
* @ param { Library = } library the library option
* @ returns { string } a readable library name
* /
2020-02-17 17:27:46 +08:00
const getLibraryName = library => {
2020-02-20 03:25:49 +08:00
const libraryName =
typeof library === "object" &&
library &&
! Array . isArray ( library ) &&
"type" in library
? library . name
: /** @type {LibraryName=} */ ( library ) ;
if ( Array . isArray ( libraryName ) ) {
return libraryName . join ( "." ) ;
} else if ( typeof libraryName === "object" ) {
return getLibraryName ( libraryName . root ) ;
} else if ( typeof libraryName === "string" ) {
return libraryName ;
2020-02-17 17:27:46 +08:00
}
2020-02-20 03:25:49 +08:00
return "" ;
2020-02-17 17:27:46 +08:00
} ;
2020-02-26 22:50:38 +08:00
F ( output , "uniqueName" , ( ) => {
const libraryName = getLibraryName ( output . library ) ;
if ( libraryName ) return libraryName ;
2021-03-06 19:07:57 +08:00
const pkgPath = path . resolve ( context , "package.json" ) ;
2020-02-26 22:50:38 +08:00
try {
2021-03-06 19:07:57 +08:00
const packageInfo = JSON . parse ( fs . readFileSync ( pkgPath , "utf-8" ) ) ;
2020-02-26 22:50:38 +08:00
return packageInfo . name || "" ;
} catch ( e ) {
2021-03-06 19:07:57 +08:00
if ( e . code !== "ENOENT" ) {
e . message += ` \n while determining default 'output.uniqueName' from 'name' in ${ pkgPath } ` ;
throw e ;
}
2020-02-26 22:50:38 +08:00
return "" ;
}
} ) ;
2020-02-17 17:27:46 +08:00
F ( output , "module" , ( ) => ! ! outputModule ) ;
2021-06-23 19:58:40 +08:00
D ( output , "filename" , output . module ? "[name].mjs" : "[name].js" ) ;
2020-02-17 17:27:46 +08:00
F ( output , "iife" , ( ) => ! output . module ) ;
2020-05-15 22:24:11 +08:00
D ( output , "importFunctionName" , "import" ) ;
2020-09-18 16:55:37 +08:00
D ( output , "importMetaName" , "import.meta" ) ;
2020-02-17 17:27:46 +08:00
F ( output , "chunkFilename" , ( ) => {
const filename = output . filename ;
if ( typeof filename !== "function" ) {
const hasName = filename . includes ( "[name]" ) ;
const hasId = filename . includes ( "[id]" ) ;
const hasChunkHash = filename . includes ( "[chunkhash]" ) ;
const hasContentHash = filename . includes ( "[contenthash]" ) ;
// Anything changing depending on chunk is fine
if ( hasChunkHash || hasContentHash || hasName || hasId ) return filename ;
2020-03-13 00:51:26 +08:00
// Otherwise prefix "[id]." in front of the basename to make it changing
2020-02-17 17:27:46 +08:00
return filename . replace ( /(^|\/)([^/]*(?:\?|$))/ , "$1[id].$2" ) ;
}
2021-06-23 19:58:40 +08:00
return output . module ? "[id].mjs" : "[id].js" ;
2020-02-17 17:27:46 +08:00
} ) ;
2020-02-28 00:49:47 +08:00
D ( output , "assetModuleFilename" , "[hash][ext][query]" ) ;
2020-02-17 17:27:46 +08:00
D ( output , "webassemblyModuleFilename" , "[hash].module.wasm" ) ;
D ( output , "compareBeforeEmit" , true ) ;
2020-08-17 20:25:27 +08:00
D ( output , "charset" , true ) ;
2020-08-25 15:16:49 +08:00
F ( output , "hotUpdateGlobal" , ( ) =>
2020-02-17 17:27:46 +08:00
Template . toIdentifier (
2020-02-26 22:50:38 +08:00
"webpackHotUpdate" + Template . toIdentifier ( output . uniqueName )
2020-02-17 17:27:46 +08:00
)
) ;
2020-08-25 15:16:49 +08:00
F ( output , "chunkLoadingGlobal" , ( ) =>
2020-02-26 22:50:38 +08:00
Template . toIdentifier (
"webpackChunk" + Template . toIdentifier ( output . uniqueName )
)
2020-02-17 17:27:46 +08:00
) ;
F ( output , "globalObject" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( tp ) {
if ( tp . global ) return "global" ;
if ( tp . globalThis ) return "globalThis" ;
2020-02-17 17:27:46 +08:00
}
2020-09-10 16:42:29 +08:00
return "self" ;
2020-02-17 17:27:46 +08:00
} ) ;
2020-08-26 03:45:56 +08:00
F ( output , "chunkFormat" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( tp ) {
2021-06-23 19:58:40 +08:00
const helpMessage = isAffectedByBrowserslist
? "Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly."
: "Select an appropriate 'target' to allow selecting one by default, or specify the 'output.chunkFormat' directly." ;
if ( output . module ) {
if ( tp . dynamicImport ) return "module" ;
if ( tp . document ) return "array-push" ;
throw new Error (
"For the selected environment is no default ESM chunk format available:\n" +
"ESM exports can be chosen when 'import()' is available.\n" +
"JSONP Array push can be chosen when 'document' is available.\n" +
helpMessage
) ;
} else {
if ( tp . document ) return "array-push" ;
if ( tp . require ) return "commonjs" ;
if ( tp . nodeBuiltins ) return "commonjs" ;
if ( tp . importScripts ) return "array-push" ;
throw new Error (
"For the selected environment is no default script chunk format available:\n" +
"JSONP Array push can be chosen when 'document' or 'importScripts' is available.\n" +
"CommonJs exports can be chosen when 'require' or node builtins are available.\n" +
helpMessage
) ;
}
2020-08-26 03:45:56 +08:00
}
2021-06-23 19:58:40 +08:00
throw new Error (
"Chunk format can't be selected by default when no target is specified"
) ;
2020-08-26 03:45:56 +08:00
} ) ;
F ( output , "chunkLoading" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( tp ) {
2021-02-16 00:15:09 +08:00
switch ( output . chunkFormat ) {
case "array-push" :
if ( tp . document ) return "jsonp" ;
if ( tp . importScripts ) return "import-scripts" ;
break ;
case "commonjs" :
if ( tp . require ) return "require" ;
if ( tp . nodeBuiltins ) return "async-node" ;
break ;
case "module" :
if ( tp . dynamicImport ) return "import" ;
break ;
}
2020-09-10 16:42:29 +08:00
if (
tp . require === null ||
tp . nodeBuiltins === null ||
tp . document === null ||
tp . importScripts === null
) {
return "universal" ;
}
2020-08-26 03:45:56 +08:00
}
2020-09-10 16:42:29 +08:00
return false ;
2020-08-26 03:45:56 +08:00
} ) ;
2020-09-08 00:02:14 +08:00
F ( output , "workerChunkLoading" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( tp ) {
2021-02-16 00:15:09 +08:00
switch ( output . chunkFormat ) {
case "array-push" :
if ( tp . importScriptsInWorker ) return "import-scripts" ;
break ;
case "commonjs" :
if ( tp . require ) return "require" ;
if ( tp . nodeBuiltins ) return "async-node" ;
break ;
case "module" :
if ( tp . dynamicImportInWorker ) return "import" ;
break ;
}
2020-09-10 16:42:29 +08:00
if (
tp . require === null ||
tp . nodeBuiltins === null ||
tp . importScriptsInWorker === null
) {
return "universal" ;
}
2020-09-08 00:02:14 +08:00
}
2020-09-10 16:42:29 +08:00
return false ;
2020-09-08 00:02:14 +08:00
} ) ;
2020-09-09 15:23:01 +08:00
F ( output , "wasmLoading" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( tp ) {
if ( tp . fetchWasm ) return "fetch" ;
2021-06-24 16:05:37 +08:00
if ( tp . nodeBuiltins )
return output . module ? "async-node-module" : "async-node" ;
2020-09-10 16:42:29 +08:00
if ( tp . nodeBuiltins === null || tp . fetchWasm === null ) {
return "universal" ;
}
2020-09-09 15:23:01 +08:00
}
2020-09-10 16:42:29 +08:00
return false ;
2020-09-09 15:23:01 +08:00
} ) ;
F ( output , "workerWasmLoading" , ( ) => output . wasmLoading ) ;
2020-02-26 22:50:38 +08:00
F ( output , "devtoolNamespace" , ( ) => output . uniqueName ) ;
2020-09-09 21:16:53 +08:00
if ( output . library ) {
F ( output . library , "type" , ( ) => ( output . module ? "module" : "var" ) ) ;
}
2020-02-17 17:27:46 +08:00
F ( output , "path" , ( ) => path . join ( process . cwd ( ) , "dist" ) ) ;
F ( output , "pathinfo" , ( ) => development ) ;
D ( output , "sourceMapFilename" , "[file].map[query]" ) ;
2021-06-23 19:58:40 +08:00
D (
output ,
"hotUpdateChunkFilename" ,
` [id].[fullhash].hot-update. ${ output . module ? "mjs" : "js" } `
) ;
2020-11-28 19:42:03 +08:00
D ( output , "hotUpdateMainFilename" , "[runtime].[fullhash].hot-update.json" ) ;
2020-02-17 17:27:46 +08:00
D ( output , "crossOriginLoading" , false ) ;
2020-06-25 04:05:21 +08:00
F ( output , "scriptType" , ( ) => ( output . module ? "module" : false ) ) ;
2020-09-18 16:26:29 +08:00
D (
output ,
"publicPath" ,
( tp && ( tp . document || tp . importScripts ) ) || output . scriptType === "module"
? "auto"
: ""
) ;
2020-02-17 17:27:46 +08:00
D ( output , "chunkLoadTimeout" , 120000 ) ;
2021-09-23 21:04:22 +08:00
D ( output , "hashFunction" , futureDefaults ? "xxhash64" : "md4" ) ;
2020-02-17 17:27:46 +08:00
D ( output , "hashDigest" , "hex" ) ;
D ( output , "hashDigestLength" , 20 ) ;
D ( output , "strictModuleExceptionHandling" , false ) ;
2020-09-09 21:16:53 +08:00
2020-09-10 16:42:29 +08:00
const optimistic = v => v || v === undefined ;
F (
output . environment ,
"arrowFunction" ,
( ) => tp && optimistic ( tp . arrowFunction )
) ;
F ( output . environment , "const" , ( ) => tp && optimistic ( tp . const ) ) ;
F (
output . environment ,
"destructuring" ,
( ) => tp && optimistic ( tp . destructuring )
) ;
F ( output . environment , "forOf" , ( ) => tp && optimistic ( tp . forOf ) ) ;
F ( output . environment , "bigIntLiteral" , ( ) => tp && tp . bigIntLiteral ) ;
2020-09-12 04:43:01 +08:00
F ( output . environment , "dynamicImport" , ( ) => tp && tp . dynamicImport ) ;
2020-09-10 16:42:29 +08:00
F ( output . environment , "module" , ( ) => tp && tp . module ) ;
2020-09-09 22:37:53 +08:00
2021-05-10 16:34:21 +08:00
const { trustedTypes } = output ;
if ( trustedTypes ) {
F (
trustedTypes ,
"policyName" ,
( ) =>
output . uniqueName . replace ( /[^a-zA-Z0-9\-#=_/@.%]+/g , "_" ) || "webpack"
) ;
}
2021-01-05 18:11:02 +08:00
/ * *
* @ param { function ( EntryDescription ) : void } fn iterator
* @ returns { void }
* /
const forEachEntry = fn => {
for ( const name of Object . keys ( entry ) ) {
fn ( entry [ name ] ) ;
}
} ;
2020-09-09 21:16:53 +08:00
A ( output , "enabledLibraryTypes" , ( ) => {
const enabledLibraryTypes = [ ] ;
if ( output . library ) {
enabledLibraryTypes . push ( output . library . type ) ;
}
2021-01-05 18:11:02 +08:00
forEachEntry ( desc => {
2020-09-09 21:16:53 +08:00
if ( desc . library ) {
enabledLibraryTypes . push ( desc . library . type ) ;
}
2021-01-05 18:11:02 +08:00
} ) ;
2020-09-09 21:16:53 +08:00
return enabledLibraryTypes ;
} ) ;
A ( output , "enabledChunkLoadingTypes" , ( ) => {
const enabledChunkLoadingTypes = new Set ( ) ;
if ( output . chunkLoading ) {
enabledChunkLoadingTypes . add ( output . chunkLoading ) ;
}
if ( output . workerChunkLoading ) {
enabledChunkLoadingTypes . add ( output . workerChunkLoading ) ;
}
2021-01-05 18:11:02 +08:00
forEachEntry ( desc => {
2020-09-09 21:16:53 +08:00
if ( desc . chunkLoading ) {
enabledChunkLoadingTypes . add ( desc . chunkLoading ) ;
}
2021-01-05 18:11:02 +08:00
} ) ;
2020-09-09 21:16:53 +08:00
return Array . from ( enabledChunkLoadingTypes ) ;
} ) ;
A ( output , "enabledWasmLoadingTypes" , ( ) => {
const enabledWasmLoadingTypes = new Set ( ) ;
if ( output . wasmLoading ) {
enabledWasmLoadingTypes . add ( output . wasmLoading ) ;
}
if ( output . workerWasmLoading ) {
enabledWasmLoadingTypes . add ( output . workerWasmLoading ) ;
}
2021-01-05 18:11:02 +08:00
forEachEntry ( desc => {
2020-09-09 21:16:53 +08:00
if ( desc . wasmLoading ) {
enabledWasmLoadingTypes . add ( desc . wasmLoading ) ;
}
2021-01-05 18:11:02 +08:00
} ) ;
2020-09-09 21:16:53 +08:00
return Array . from ( enabledWasmLoadingTypes ) ;
} ) ;
} ;
/ * *
* @ param { ExternalsPresets } externalsPresets options
* @ param { Object } options options
2020-09-10 16:42:29 +08:00
* @ param { TargetProperties | false } options . targetProperties target properties
2021-08-04 21:55:58 +08:00
* @ param { boolean } options . buildHttp buildHttp experiment enabled
2020-09-09 21:16:53 +08:00
* @ returns { void }
* /
2020-09-10 16:42:29 +08:00
const applyExternalsPresetsDefaults = (
externalsPresets ,
2021-08-04 21:55:58 +08:00
{ targetProperties , buildHttp }
2020-09-10 16:42:29 +08:00
) => {
2021-08-04 21:55:58 +08:00
D (
externalsPresets ,
"web" ,
! buildHttp && targetProperties && targetProperties . web
) ;
2020-09-10 16:42:29 +08:00
D ( externalsPresets , "node" , targetProperties && targetProperties . node ) ;
D ( externalsPresets , "nwjs" , targetProperties && targetProperties . nwjs ) ;
D (
externalsPresets ,
"electron" ,
targetProperties && targetProperties . electron
) ;
D (
externalsPresets ,
"electronMain" ,
targetProperties &&
targetProperties . electron &&
targetProperties . electronMain
) ;
D (
externalsPresets ,
"electronPreload" ,
targetProperties &&
targetProperties . electron &&
targetProperties . electronPreload
) ;
D (
externalsPresets ,
"electronRenderer" ,
targetProperties &&
targetProperties . electron &&
targetProperties . electronRenderer
) ;
2020-02-17 17:27:46 +08:00
} ;
2020-09-09 21:54:13 +08:00
/ * *
* @ param { Loader } loader options
* @ param { Object } options options
2020-09-10 16:42:29 +08:00
* @ param { TargetProperties | false } options . targetProperties target properties
2020-09-09 21:54:13 +08:00
* @ returns { void }
* /
2020-09-10 16:42:29 +08:00
const applyLoaderDefaults = ( loader , { targetProperties } ) => {
2020-09-09 21:54:13 +08:00
F ( loader , "target" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( targetProperties ) {
if ( targetProperties . electron ) {
if ( targetProperties . electronMain ) return "electron-main" ;
if ( targetProperties . electronPreload ) return "electron-preload" ;
if ( targetProperties . electronRenderer ) return "electron-renderer" ;
return "electron" ;
}
if ( targetProperties . nwjs ) return "nwjs" ;
if ( targetProperties . node ) return "node" ;
if ( targetProperties . web ) return "web" ;
2020-09-09 21:54:13 +08:00
}
} ) ;
} ;
2020-02-17 17:27:46 +08:00
/ * *
* @ param { WebpackNode } node options
* @ param { Object } options options
2020-09-10 16:42:29 +08:00
* @ param { TargetProperties | false } options . targetProperties target properties
2021-09-12 00:15:27 +08:00
* @ param { boolean } options . futureDefaults is future defaults enabled
2020-02-17 17:27:46 +08:00
* @ returns { void }
* /
2021-09-12 00:15:27 +08:00
const applyNodeDefaults = ( node , { futureDefaults , targetProperties } ) => {
2020-02-17 17:27:46 +08:00
if ( node === false ) return ;
2021-09-12 00:15:27 +08:00
2020-02-17 17:27:46 +08:00
F ( node , "global" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( targetProperties && targetProperties . global ) return false ;
2021-09-12 00:15:27 +08:00
// TODO webpack 6 should always default to false
return futureDefaults ? "warn" : true ;
2020-02-17 17:27:46 +08:00
} ) ;
F ( node , "__filename" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( targetProperties && targetProperties . node ) return "eval-only" ;
2021-09-12 00:15:27 +08:00
// TODO webpack 6 should always default to false
return futureDefaults ? "warn-mock" : "mock" ;
2020-02-17 17:27:46 +08:00
} ) ;
F ( node , "__dirname" , ( ) => {
2020-09-10 16:42:29 +08:00
if ( targetProperties && targetProperties . node ) return "eval-only" ;
2021-09-12 00:15:27 +08:00
// TODO webpack 6 should always default to false
return futureDefaults ? "warn-mock" : "mock" ;
2020-02-17 17:27:46 +08:00
} ) ;
} ;
/ * *
* @ param { Performance } performance options
* @ param { Object } options options
* @ param { boolean } options . production is production
* @ returns { void }
* /
const applyPerformanceDefaults = ( performance , { production } ) => {
if ( performance === false ) return ;
D ( performance , "maxAssetSize" , 250000 ) ;
D ( performance , "maxEntrypointSize" , 250000 ) ;
F ( performance , "hints" , ( ) => ( production ? "warning" : false ) ) ;
} ;
/ * *
* @ param { Optimization } optimization options
* @ param { Object } options options
* @ param { boolean } options . production is production
* @ param { boolean } options . development is development
* @ param { boolean } options . records using records
* @ returns { void }
* /
const applyOptimizationDefaults = (
optimization ,
{ production , development , records }
) => {
D ( optimization , "removeAvailableModules" , false ) ;
D ( optimization , "removeEmptyChunks" , true ) ;
D ( optimization , "mergeDuplicateChunks" , true ) ;
D ( optimization , "flagIncludedChunks" , production ) ;
F ( optimization , "moduleIds" , ( ) => {
if ( production ) return "deterministic" ;
if ( development ) return "named" ;
return "natural" ;
} ) ;
F ( optimization , "chunkIds" , ( ) => {
if ( production ) return "deterministic" ;
if ( development ) return "named" ;
return "natural" ;
} ) ;
2020-10-26 22:32:34 +08:00
F ( optimization , "sideEffects" , ( ) => ( production ? true : "flag" ) ) ;
2020-02-17 17:27:46 +08:00
D ( optimization , "providedExports" , true ) ;
2020-07-08 18:22:55 +08:00
D ( optimization , "usedExports" , production ) ;
D ( optimization , "innerGraph" , production ) ;
2020-02-17 17:27:46 +08:00
D ( optimization , "mangleExports" , production ) ;
D ( optimization , "concatenateModules" , production ) ;
D ( optimization , "runtimeChunk" , false ) ;
2020-07-17 21:39:16 +08:00
D ( optimization , "emitOnErrors" , ! production ) ;
2020-02-17 17:27:46 +08:00
D ( optimization , "checkWasmTypes" , production ) ;
D ( optimization , "mangleWasmImports" , false ) ;
D ( optimization , "portableRecords" , records ) ;
2020-08-19 03:14:43 +08:00
D ( optimization , "realContentHash" , production ) ;
2020-02-17 17:27:46 +08:00
D ( optimization , "minimize" , production ) ;
2020-07-11 16:30:18 +08:00
A ( optimization , "minimizer" , ( ) => [
2020-02-17 17:27:46 +08:00
{
apply : compiler => {
// Lazy load the Terser plugin
const TerserPlugin = require ( "terser-webpack-plugin" ) ;
2020-08-18 03:32:47 +08:00
new TerserPlugin ( {
terserOptions : {
compress : {
passes : 2
}
}
} ) . apply ( compiler ) ;
2020-02-17 17:27:46 +08:00
}
}
] ) ;
F ( optimization , "nodeEnv" , ( ) => {
if ( production ) return "production" ;
if ( development ) return "development" ;
return false ;
} ) ;
const { splitChunks } = optimization ;
if ( splitChunks ) {
2020-09-29 17:16:24 +08:00
A ( splitChunks , "defaultSizeTypes" , ( ) => [ "javascript" , "unknown" ] ) ;
2020-02-17 17:27:46 +08:00
D ( splitChunks , "hidePathInfo" , production ) ;
D ( splitChunks , "chunks" , "async" ) ;
2021-04-27 19:55:29 +08:00
D ( splitChunks , "usedExports" , optimization . usedExports === true ) ;
2020-02-17 17:27:46 +08:00
D ( splitChunks , "minChunks" , 1 ) ;
2020-07-13 16:13:27 +08:00
F ( splitChunks , "minSize" , ( ) => ( production ? 20000 : 10000 ) ) ;
2020-02-17 17:27:46 +08:00
F ( splitChunks , "minRemainingSize" , ( ) => ( development ? 0 : undefined ) ) ;
2020-07-13 16:13:27 +08:00
F ( splitChunks , "enforceSizeThreshold" , ( ) => ( production ? 50000 : 30000 ) ) ;
2020-06-16 22:48:12 +08:00
F ( splitChunks , "maxAsyncRequests" , ( ) => ( production ? 30 : Infinity ) ) ;
F ( splitChunks , "maxInitialRequests" , ( ) => ( production ? 30 : Infinity ) ) ;
2020-02-17 17:27:46 +08:00
D ( splitChunks , "automaticNameDelimiter" , "-" ) ;
const { cacheGroups } = splitChunks ;
F ( cacheGroups , "default" , ( ) => ( {
idHint : "" ,
reuseExistingChunk : true ,
minChunks : 2 ,
priority : - 20
} ) ) ;
F ( cacheGroups , "defaultVendors" , ( ) => ( {
idHint : "vendors" ,
reuseExistingChunk : true ,
test : NODE _MODULES _REGEXP ,
priority : - 10
} ) ) ;
}
} ;
/ * *
* @ param { Object } options options
* @ param { boolean } options . cache is cache enable
2020-07-09 05:12:45 +08:00
* @ param { string } options . context build context
2020-09-10 16:42:29 +08:00
* @ param { TargetProperties | false } options . targetProperties target properties
2020-05-25 18:58:59 +08:00
* @ param { Mode } options . mode mode
2020-07-11 16:30:18 +08:00
* @ returns { ResolveOptions } resolve options
2020-02-17 17:27:46 +08:00
* /
2020-09-10 16:42:29 +08:00
const getResolveDefaults = ( { cache , context , targetProperties , mode } ) => {
2020-07-11 16:30:18 +08:00
/** @type {string[]} */
const conditions = [ "webpack" ] ;
conditions . push ( mode === "development" ? "development" : "production" ) ;
2020-09-10 16:42:29 +08:00
if ( targetProperties ) {
if ( targetProperties . webworker ) conditions . push ( "worker" ) ;
if ( targetProperties . node ) conditions . push ( "node" ) ;
if ( targetProperties . web ) conditions . push ( "browser" ) ;
if ( targetProperties . electron ) conditions . push ( "electron" ) ;
if ( targetProperties . nwjs ) conditions . push ( "nwjs" ) ;
2020-07-11 16:30:18 +08:00
}
2020-05-25 18:58:59 +08:00
2020-07-17 21:57:56 +08:00
const jsExtensions = [ ".js" , ".json" , ".wasm" ] ;
2020-05-25 18:58:59 +08:00
2020-09-10 16:42:29 +08:00
const tp = targetProperties ;
const browserField =
tp && tp . web && ( ! tp . node || ( tp . electron && tp . electronRenderer ) ) ;
2020-07-13 20:28:55 +08:00
/** @type {function(): ResolveOptions} */
const cjsDeps = ( ) => ( {
2020-09-10 16:42:29 +08:00
aliasFields : browserField ? [ "browser" ] : [ ] ,
mainFields : browserField ? [ "browser" , "module" , "..." ] : [ "module" , "..." ] ,
conditionNames : [ "require" , "module" , "..." ] ,
2020-07-13 23:46:50 +08:00
extensions : [ ... jsExtensions ]
2020-07-13 20:28:55 +08:00
} ) ;
/** @type {function(): ResolveOptions} */
const esmDeps = ( ) => ( {
2020-09-10 16:42:29 +08:00
aliasFields : browserField ? [ "browser" ] : [ ] ,
mainFields : browserField ? [ "browser" , "module" , "..." ] : [ "module" , "..." ] ,
conditionNames : [ "import" , "module" , "..." ] ,
2020-07-13 23:46:50 +08:00
extensions : [ ... jsExtensions ]
2020-07-13 20:28:55 +08:00
} ) ;
2020-07-11 16:30:18 +08:00
/** @type {ResolveOptions} */
const resolveOptions = {
cache ,
modules : [ "node_modules" ] ,
conditionNames : conditions ,
mainFiles : [ "index" ] ,
2020-07-13 23:46:50 +08:00
extensions : [ ] ,
2020-07-11 16:30:18 +08:00
aliasFields : [ ] ,
exportsFields : [ "exports" ] ,
roots : [ context ] ,
mainFields : [ "main" ] ,
byDependency : {
2020-07-13 20:28:55 +08:00
wasm : esmDeps ( ) ,
esm : esmDeps ( ) ,
2021-04-09 21:40:10 +08:00
loaderImport : esmDeps ( ) ,
2020-09-29 02:43:03 +08:00
url : {
preferRelative : true
} ,
worker : {
... esmDeps ( ) ,
preferRelative : true
} ,
2020-07-13 20:28:55 +08:00
commonjs : cjsDeps ( ) ,
amd : cjsDeps ( ) ,
2020-07-11 16:30:18 +08:00
// for backward-compat: loadModule
2020-07-13 20:28:55 +08:00
loader : cjsDeps ( ) ,
2020-07-11 16:30:18 +08:00
// for backward-compat: Custom Dependency
2020-07-13 20:28:55 +08:00
unknown : cjsDeps ( ) ,
2020-07-11 16:30:18 +08:00
// for backward-compat: getResolve without dependencyType
2020-07-13 20:28:55 +08:00
undefined : cjsDeps ( )
2020-05-25 18:58:59 +08:00
}
2020-07-11 16:30:18 +08:00
} ;
2020-05-25 18:58:59 +08:00
2020-07-11 16:30:18 +08:00
return resolveOptions ;
2020-02-17 17:27:46 +08:00
} ;
/ * *
* @ param { Object } options options
* @ param { boolean } options . cache is cache enable
2020-07-11 16:30:18 +08:00
* @ returns { ResolveOptions } resolve options
2020-02-17 17:27:46 +08:00
* /
2020-07-11 16:30:18 +08:00
const getResolveLoaderDefaults = ( { cache } ) => {
/** @type {ResolveOptions} */
const resolveOptions = {
cache ,
conditionNames : [ "loader" , "require" , "node" ] ,
exportsFields : [ "exports" ] ,
mainFields : [ "loader" , "main" ] ,
extensions : [ ".js" ] ,
mainFiles : [ "index" ]
} ;
return resolveOptions ;
2020-02-17 17:27:46 +08:00
} ;
/ * *
* @ param { InfrastructureLogging } infrastructureLogging options
* @ returns { void }
* /
const applyInfrastructureLoggingDefaults = infrastructureLogging => {
2021-04-06 21:23:22 +08:00
F ( infrastructureLogging , "stream" , ( ) => process . stderr ) ;
const tty =
/** @type {any} */ ( infrastructureLogging . stream ) . isTTY &&
process . env . TERM !== "dumb" ;
2020-02-17 17:27:46 +08:00
D ( infrastructureLogging , "level" , "info" ) ;
D ( infrastructureLogging , "debug" , false ) ;
2021-04-06 21:20:27 +08:00
D ( infrastructureLogging , "colors" , tty ) ;
D ( infrastructureLogging , "appendOnly" , ! tty ) ;
2020-02-17 17:27:46 +08:00
} ;
exports . applyWebpackOptionsBaseDefaults = applyWebpackOptionsBaseDefaults ;
exports . applyWebpackOptionsDefaults = applyWebpackOptionsDefaults ;