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" ) ;
2023-04-01 01:56:32 +08:00
const {
JAVASCRIPT _MODULE _TYPE _AUTO ,
JSON _MODULE _TYPE ,
WEBASSEMBLY _MODULE _TYPE _ASYNC ,
JAVASCRIPT _MODULE _TYPE _ESM ,
JAVASCRIPT _MODULE _TYPE _DYNAMIC ,
WEBASSEMBLY _MODULE _TYPE _SYNC
} = require ( "../ModuleTypeConstants" ) ;
2020-02-17 17:27:46 +08:00
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 */
2022-01-19 01:14:50 +08:00
/** @typedef {import("../../declarations/WebpackOptions").CssExperimentOptions} CssExperimentOptions */
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 */
2021-10-19 01:23:29 +08:00
/** @typedef {import("../../declarations/WebpackOptions").ExperimentsNormalized} ExperimentsNormalized */
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 ) ;
2022-01-19 01:14:50 +08:00
applyExperimentsDefaults ( options . experiments , {
production ,
development ,
targetProperties
} ) ;
2021-09-24 17:35:28 +08:00
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 ,
2021-11-05 23:13:49 +08:00
asyncWebAssembly : options . experiments . asyncWebAssembly ,
2021-11-30 19:55:51 +08:00
css : options . experiments . css ,
2022-03-28 22:16:31 +08:00
futureDefaults ,
isNode : targetProperties && targetProperties . node === true
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 ,
2021-11-30 19:55:51 +08:00
css : options . experiments . css ,
2020-02-17 17:27:46 +08:00
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
} ;
/ * *
2021-10-19 01:23:29 +08:00
* @ param { ExperimentsNormalized } 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
2022-01-19 01:14:50 +08:00
* @ param { TargetProperties | false } options . targetProperties target properties
2020-02-17 17:27:46 +08:00
* @ returns { void }
* /
2022-01-19 01:14:50 +08:00
const applyExperimentsDefaults = (
experiments ,
{ production , development , targetProperties }
) => {
2021-11-05 16:53:32 +08:00
D ( experiments , "futureDefaults" , false ) ;
D ( experiments , "backCompat" , ! experiments . futureDefaults ) ;
D ( experiments , "topLevelAwait" , experiments . futureDefaults ) ;
2020-02-17 17:27:46 +08:00
D ( experiments , "syncWebAssembly" , false ) ;
2021-11-05 16:53:32 +08:00
D ( experiments , "asyncWebAssembly" , experiments . futureDefaults ) ;
2020-02-17 17:27:46 +08:00
D ( experiments , "outputModule" , false ) ;
2021-08-04 21:55:58 +08:00
D ( experiments , "layers" , false ) ;
2021-10-19 01:23:29 +08:00
D ( experiments , "lazyCompilation" , undefined ) ;
D ( experiments , "buildHttp" , undefined ) ;
2021-09-24 17:35:28 +08:00
D ( experiments , "cacheUnaffected" , experiments . futureDefaults ) ;
2022-01-19 01:14:50 +08:00
F ( experiments , "css" , ( ) => ( experiments . futureDefaults ? { } : undefined ) ) ;
2021-08-04 21:55:58 +08:00
if ( typeof experiments . buildHttp === "object" ) {
D ( experiments . buildHttp , "frozen" , production ) ;
2021-10-19 01:23:29 +08:00
D ( experiments . buildHttp , "upgrade" , false ) ;
2021-08-04 21:55:58 +08:00
}
2022-01-19 01:14:50 +08:00
if ( typeof experiments . css === "object" ) {
D (
experiments . css ,
"exportsOnly" ,
! targetProperties || ! targetProperties . document
) ;
}
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 {
2021-11-12 20:32:29 +08:00
const match = /^(.+?[\\/]node_modules[\\/])/ . exec (
2021-10-18 22:07:41 +08:00
// 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-11-05 23:13:49 +08:00
* @ param { Object } options options
* @ param { boolean } options . futureDefaults is future defaults enabled
2022-03-28 22:16:31 +08:00
* @ param { boolean } options . isNode is node target platform
2021-01-05 18:11:02 +08:00
* @ returns { void }
* /
2021-11-05 23:13:49 +08:00
const applyJavascriptParserOptionsDefaults = (
parserOptions ,
2022-03-28 22:16:31 +08:00
{ futureDefaults , isNode }
2021-11-05 23:13:49 +08:00
) => {
2021-01-20 22:08:58 +08:00
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 , "strictThisContextOnImports" , false ) ;
2022-01-28 16:52:30 +08:00
D ( parserOptions , "importMeta" , true ) ;
2022-03-15 21:42:52 +08:00
D ( parserOptions , "dynamicImportMode" , "lazy" ) ;
2022-03-09 15:27:02 +08:00
D ( parserOptions , "dynamicImportPrefetch" , false ) ;
D ( parserOptions , "dynamicImportPreload" , false ) ;
2022-03-28 22:16:31 +08:00
D ( parserOptions , "createRequire" , isNode ) ;
2021-11-06 08:01:21 +08:00
if ( futureDefaults ) D ( parserOptions , "exportsPresence" , "error" ) ;
2021-01-20 22:08:58 +08:00
} ;
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
2022-05-04 00:08:14 +08:00
* @ param { CssExperimentOptions | false } options . css is css enabled
2021-11-05 23:13:49 +08:00
* @ param { boolean } options . futureDefaults is future defaults enabled
2022-03-28 22:16:31 +08:00
* @ param { boolean } options . isNode is node target platform
2020-02-17 17:27:46 +08:00
* @ returns { void }
* /
const applyModuleDefaults = (
module ,
2022-03-28 22:16:31 +08:00
{ cache , syncWebAssembly , asyncWebAssembly , css , futureDefaults , isNode }
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 ) ;
}
2022-01-28 16:52:30 +08:00
F ( module . parser , "javascript" , ( ) => ( { } ) ) ;
2021-11-05 23:13:49 +08:00
applyJavascriptParserOptionsDefaults ( module . parser . javascript , {
2022-03-28 22:16:31 +08:00
futureDefaults ,
isNode
2021-11-05 23:13:49 +08:00
} ) ;
2021-01-05 18:11:02 +08:00
2020-07-11 16:30:18 +08:00
A ( module , "defaultRules" , ( ) => {
2020-09-02 20:41:04 +08:00
const esm = {
2023-04-01 01:56:32 +08:00
type : JAVASCRIPT _MODULE _TYPE _ESM ,
2020-09-02 20:41:04 +08:00
resolve : {
byDependency : {
esm : {
fullySpecified : true
}
}
}
} ;
const commonjs = {
2023-04-01 01:56:32 +08:00
type : JAVASCRIPT _MODULE _TYPE _DYNAMIC
2020-09-02 20:41:04 +08:00
} ;
2020-02-17 17:27:46 +08:00
/** @type {RuleSetRules} */
const rules = [
2020-07-17 16:27:48 +08:00
{
mimetype : "application/node" ,
2023-04-01 01:56:32 +08:00
type : JAVASCRIPT _MODULE _TYPE _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 ,
2023-04-01 01:56:32 +08:00
type : JSON _MODULE _TYPE
2020-05-18 15:00:28 +08:00
} ,
{
mimetype : "application/json" ,
2023-04-01 01:56:32 +08:00
type : JSON _MODULE _TYPE
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 = {
2023-04-01 01:56:32 +08:00
type : WEBASSEMBLY _MODULE _TYPE _ASYNC ,
2020-09-02 20:41:04 +08:00
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 = {
2023-04-01 01:56:32 +08:00
type : WEBASSEMBLY _MODULE _TYPE _SYNC ,
2020-09-02 20:41:04 +08:00
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-11-30 19:55:51 +08:00
if ( css ) {
const cssRule = {
type : "css" ,
resolve : {
fullySpecified : true ,
preferRelative : true
}
} ;
2021-12-14 23:02:26 +08:00
const cssModulesRule = {
type : "css/module" ,
resolve : {
fullySpecified : true
}
} ;
2021-11-30 19:55:51 +08:00
rules . push ( {
test : /\.css$/i ,
2021-12-14 23:02:26 +08:00
oneOf : [
{
test : /\.module\.css$/i ,
... cssModulesRule
} ,
{
... cssRule
}
]
} ) ;
rules . push ( {
mimetype : "text/css+module" ,
... cssModulesRule
2021-11-30 19:55:51 +08:00
} ) ;
rules . push ( {
mimetype : "text/css" ,
... cssRule
} ) ;
}
2021-07-17 04:16:06 +08:00
rules . push (
{
dependency : "url" ,
oneOf : [
{
scheme : /^data$/ ,
type : "asset/inline"
} ,
{
type : "asset/resource"
}
]
} ,
{
assert : { type : "json" } ,
2023-04-01 01:56:32 +08:00
type : JSON _MODULE _TYPE
2021-07-17 04:16:06 +08:00
}
) ;
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" , ( ) => {
2022-02-10 19:58:37 +08:00
const libraryName = getLibraryName ( output . library ) . replace (
/^\[(\\*[\w:]+\\*)\](\.)|(\.)\[(\\*[\w:]+\\*)\](?=\.|$)|\[(\\*[\w:]+\\*)\]/g ,
( m , a , d1 , d2 , b , c ) => {
const content = a || b || c ;
return content . startsWith ( "\\" ) && content . endsWith ( "\\" )
? ` ${ d2 || "" } [ ${ content . slice ( 1 , - 1 ) } ] ${ d1 || "" } `
: "" ;
}
) ;
2020-02-26 22:50:38 +08:00
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
} ) ;
2021-11-30 19:55:51 +08:00
F ( output , "cssFilename" , ( ) => {
2021-12-17 19:18:01 +08:00
const filename = output . filename ;
if ( typeof filename !== "function" ) {
return filename . replace ( /\.[mc]?js(\?|$)/ , ".css$1" ) ;
}
return "[id].css" ;
} ) ;
F ( output , "cssChunkFilename" , ( ) => {
2021-11-30 19:55:51 +08:00
const chunkFilename = output . chunkFilename ;
if ( typeof chunkFilename !== "function" ) {
return chunkFilename . replace ( /\.[mc]?js(\?|$)/ , ".css$1" ) ;
}
return "[id].css" ;
} ) ;
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
} ) ;
2021-11-10 21:23:03 +08:00
D ( output , "asyncChunks" , true ) ;
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"
: ""
) ;
2022-10-22 07:30:43 +08:00
D ( output , "workerPublicPath" , "" ) ;
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" ) ;
2021-11-30 03:12:02 +08:00
D ( output , "hashDigestLength" , futureDefaults ? 16 : 20 ) ;
2020-02-17 17:27:46 +08:00
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 ;
2022-02-02 15:13:20 +08:00
const conditionallyOptimistic = ( v , c ) => ( v === undefined && c ) || v ;
2020-09-10 16:42:29 +08:00
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 ) ;
2022-02-04 22:56:47 +08:00
F ( output . environment , "dynamicImport" , ( ) =>
conditionallyOptimistic ( tp && tp . dynamicImport , output . module )
2022-02-03 20:11:12 +08:00
) ;
2022-02-04 22:56:47 +08:00
F ( output . environment , "module" , ( ) =>
conditionallyOptimistic ( tp && tp . module , output . module )
2022-02-02 15:13:20 +08:00
) ;
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"
) ;
Add option to continue on trusted-types policy-creation failure
Webpack already allows for specifying a trusted-types policy name. However, its current implementation is such that if a call to trustedTypes.createPolicy fails, the code will immediately stop executing. This isn't necessarily desirable, as an application could be in the early phases of rolling out trusted types, and thus have the CSP rule for trusted-types LibraryA LibraryB etc, BUT have require-trusted-types-for 'script' be in "report only" mode (Content-Security-Policy-Report-Only). In such a configuration, and when the webpacked code is dynamically-loaded into an application, adding the policy name to the webpack config will break old versions.
This PR keeps the original behavior, but introduces a new option for onPolicyCreationFailure: "continue" | "stop" (with "stop" remaining the default). If a developer chooses the "continue" option, the policy-creation will be wrapped in a try/catch. There is no security risk to this, since for host applications that DO have strict enforcement of trusted-types, the code will simply fail when the dangerous sink is used (e.g., when doing parseFromString). And likewise, wrapping in try/catch and doing nothing on catch is OK, because the code already deals with the possibility of the trustedTypes API not being available on the browser.
2023-04-20 05:53:22 +08:00
D ( trustedTypes , "onPolicyCreationFailure" , "stop" ) ;
2021-05-10 16:34:21 +08:00
}
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
2022-05-04 00:08:14 +08:00
* @ param { CssExperimentOptions | false } options . css is css enabled
2020-02-17 17:27:46 +08:00
* @ param { boolean } options . records using records
* @ returns { void }
* /
const applyOptimizationDefaults = (
optimization ,
2021-11-30 19:55:51 +08:00
{ production , development , css , records }
2020-02-17 17:27:46 +08:00
) => {
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 ) {
2021-11-30 19:55:51 +08:00
A ( splitChunks , "defaultSizeTypes" , ( ) =>
css ? [ "javascript" , "css" , "unknown" ] : [ "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 ;