Movatterモバイル変換


[0]ホーム

URL:


webpack logo
ag grid
ag charts

SplitChunksPlugin

Originally, chunks (and modules imported inside them) were connected by a parent-child relationship in the internal webpack graph. TheCommonsChunkPlugin was used to avoid duplicated dependencies across them, but further optimizations were not possible.

Since webpack v4, theCommonsChunkPlugin was removed in favor ofoptimization.splitChunks.

Defaults

Out of the boxSplitChunksPlugin should work well for most users.

By default it only affects on-demand chunks, because changing initial chunks would affect the script tags the HTML file should include to run the project.

Webpack will automatically split chunks based on these conditions:

  • New chunk can be shared OR modules are from thenode_modules folder
  • New chunk would be bigger than 20kb (before min+gz)
  • Maximum number of parallel requests when loading chunks on demand would be lower or equal to 30
  • Maximum number of parallel requests at initial page load would be lower or equal to 30

When trying to fulfill the last two conditions, bigger chunks are preferred.

Configuration

Webpack provides a set of options for developers that want more control over this functionality.

warning

The default configuration was chosen to fit web performance best practices, but the optimal strategy for your project might differ. If you're changing the configuration, you should measure the effect of your changes to ensure there's a real benefit.

optimization.splitChunks

This configuration object represents the default behavior of theSplitChunksPlugin.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      chunks:'async',      minSize:20000,      minRemainingSize:0,      minChunks:1,      maxAsyncRequests:30,      maxInitialRequests:30,      enforceSizeThreshold:50000,      cacheGroups:{        defaultVendors:{          test:/[\\/]node_modules[\\/]/,          priority:-10,          reuseExistingChunk:true,},default:{          minChunks:2,          priority:-20,          reuseExistingChunk:true,},},},},};
warning

When files paths are processed by webpack, they always contain/ on Unix systems and\ on Windows. That's why using[\\/] in{cacheGroup}.test fields is necessary to represent a path separator./ or\ in{cacheGroup}.test will cause issues when used cross-platform.

warning

Since webpack 5, passing an entry name to{cacheGroup}.test and using a name of an existing chunk for{cacheGroup}.name is no longer allowed.

splitChunks.automaticNameDelimiter

string = '~'

By default webpack will generate names using origin and name of the chunk (e.g.vendors~main.js). This option lets you specify the delimiter to use for the generated names.

splitChunks.chunks

string = 'async'function (chunk)RegExp

This indicates which chunks will be selected for optimization. When a string is provided, valid values areall,async, andinitial. Providingall can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.

Note that it is applied to the fallback cache group as well (splitChunks.fallbackCacheGroup.chunks).

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{// include all types of chunks      chunks:'all',},},};

Alternatively, you may provide a function for more control. The return value will indicate whether to include each chunk.

module.exports={//...  optimization:{    splitChunks:{chunks(chunk){// exclude `my-excluded-chunk`return chunk.name!=='my-excluded-chunk';},},},};

If you are using webpack version 5.86.0 or later, you can also pass a regular expression:

module.exports={//...  optimization:{    splitChunks:{      chunks:/foo/,},},};
tip

You can combine this configuration with theHtmlWebpackPlugin for Single Page Application orChunksWebpackPlugin for Multiple Page Application. It will inject all the generated vendor chunks for you.

splitChunks.maxAsyncRequests

number = 30

Maximum number of parallel requests when on-demand loading.

splitChunks.maxInitialRequests

number = 30

Maximum number of parallel requests at an entry point.

splitChunks.defaultSizeTypes

[string] = ['javascript', 'unknown']

Sets the size types which are used when a number is used for sizes.

splitChunks.minChunks

number = 1

The minimum times must a module be shared among chunks before splitting.

splitChunks.hidePathInfo

boolean

Prevents exposing path info when creating names for parts splitted by maxSize.

splitChunks.minSize

number = 20000{ [index: string]: number }

Minimum size, in bytes, for a chunk to be generated.

splitChunks.minSizeReduction

number{ [index: string]: number }

Minimum size reduction to the main chunk (bundle), in bytes, needed for a chunk to be generated. Meaning if splitting into a chunk does not reduce the size of the main chunk (bundle) by the given amount of bytes, it won't be split, even if it meets thesplitChunks.minSize value.

tip

BothsplitChunks.minSizeReduction andsplitChunks.minSize need to be fulfilled for a chunk to be generated.

splitChunks.enforceSizeThreshold

splitChunks.cacheGroups.{cacheGroup}.enforceSizeThreshold

number = 50000

Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored.

splitChunks.minRemainingSize

splitChunks.cacheGroups.{cacheGroup}.minRemainingSize

number = 0

splitChunks.minRemainingSize option was introduced in webpack 5 to avoid zero sized modules by ensuring that the minimum size of the chunk which remains after splitting is above a limit. Defaults to0 in'development' mode. For other casessplitChunks.minRemainingSize defaults to the value ofsplitChunks.minSize so it doesn't need to be specified manually except for the rare cases where deep control is required.

warning

splitChunks.minRemainingSize only takes effect when a single chunk is remaining.

splitChunks.layer

splitChunks.cacheGroups.{cacheGroup}.layer

RegExpstringfunction

Assign modules to a cache group by module layer.

splitChunks.maxSize

number = 0

UsingmaxSize (either globallyoptimization.splitChunks.maxSize per cache groupoptimization.splitChunks.cacheGroups[x].maxSize or for the fallback cache groupoptimization.splitChunks.fallbackCacheGroup.maxSize) tells webpack to try to split chunks bigger thanmaxSize bytes into smaller parts. Parts will be at leastminSize (next tomaxSize) in size.The algorithm is deterministic and changes to the modules will only have local effects. So that it is usable when using long term caching and doesn't require records.maxSize is only a hint and could be violated when modules are bigger thanmaxSize or splitting would violateminSize.

When the chunk has a name already, each part will get a new name derived from that name. Depending on the value ofoptimization.splitChunks.hidePathInfo it will add a key derived from the first module name or a hash of it.

maxSize option is intended to be used with HTTP/2 and long term caching. It increases the request count for better caching. It could also be used to decrease the file size for faster rebuilding.

tip

maxInitialRequest/maxAsyncRequests takes higher priority thanmaxSize. Actual priority ismaxSize < maxInitialRequest/maxAsyncRequests < minSize.

tip

Setting the value formaxSize sets the value for bothmaxAsyncSize andmaxInitialSize.

splitChunks.maxAsyncSize

number

LikemaxSize,maxAsyncSize can be applied globally (splitChunks.maxAsyncSize), to cacheGroups (splitChunks.cacheGroups.{cacheGroup}.maxAsyncSize), or to the fallback cache group (splitChunks.fallbackCacheGroup.maxAsyncSize).

The difference betweenmaxAsyncSize andmaxSize is thatmaxAsyncSize will only affect on-demand loading chunks.

splitChunks.maxInitialSize

number

LikemaxSize,maxInitialSize can be applied globally (splitChunks.maxInitialSize), to cacheGroups (splitChunks.cacheGroups.{cacheGroup}.maxInitialSize), or to the fallback cache group (splitChunks.fallbackCacheGroup.maxInitialSize).

The difference betweenmaxInitialSize andmaxSize is thatmaxInitialSize will only affect initial load chunks.

splitChunks.name

boolean = falsefunction (module, chunks, cacheGroupKey) => stringstring

Also available for each cacheGroup:splitChunks.cacheGroups.{cacheGroup}.name.

The name of the split chunk. Providingfalse will keep the same name of the chunks so it doesn't change names unnecessarily. It is the recommended value for production builds.

Providing a string or a function allows you to use a custom name. Specifying either a string or a function that always returns the same string will merge all common modules and vendors into a single chunk. This might lead to bigger initial downloads and slow down page loads.

If you choose to specify a function, you may find thechunk.name property (wherechunk is an element of thechunks array) particularly useful in choosing a name for your chunk.

If thesplitChunks.name matches anentry point name, the entry-point chunk & the cache group will be combined into a single chunk.

tip

splitChunks.cacheGroups.{cacheGroup}.name can be used to move modules into a chunk that is a parent of the source chunk. For example, usename: "entry-name" to move modules into theentry-name chunk. You can also use on demand named chunks, but you must be careful that the selected modules are only used under this chunk.

main.js

import _from'lodash';console.log(_.join(['Hello','webpack'],' '));

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        commons:{          test:/[\\/]node_modules[\\/]/,// cacheGroupKey here is `commons` as the key of the cacheGroupname(module, chunks, cacheGroupKey){const moduleFileName= module.identifier().split('/').reduceRight((item)=> item);const allChunksNames= chunks.map((item)=> item.name).join('~');return`${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;},          chunks:'all',},},},},};

Running webpack with followingsplitChunks configuration would also output a chunk of the group common with next name:commons-main-lodash.js.e7519d2bb8777058fa27.js (hash given as an example of real world output).

warning

When assigning equal names to different split chunks, all vendor modules are placed into a single shared chunk, though it's not recommend since it can result in more code downloaded.

splitChunks.usedExports

splitChunks.cacheGroups{cacheGroup}.usedExports

boolean = true

Figure out which exports are used by modules to mangle export names, omit unused exports and generate more efficient code.When it istrue: analyse used exports for each runtime, when it is"global": analyse exports globally for all runtimes combined).

splitChunks.cacheGroups

Cache groups can inherit and/or override any options fromsplitChunks.*; buttest,priority andreuseExistingChunk can only be configured on cache group level. To disable any of the default cache groups, set them tofalse.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{default:false,},},},};

splitChunks.cacheGroups.{cacheGroup}.priority

number = -20

A module can belong to multiple cache groups. The optimization will prefer the cache group with a higherpriority. The default groups have a negative priority to allow custom groups to take higher priority (default value is0 for custom groups).

splitChunks.cacheGroups.{cacheGroup}.reuseExistingChunk

boolean = true

If the current chunk contains modules already split out from the main bundle, it will be reused instead of a new one being generated. This can affect the resulting file name of the chunk.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        defaultVendors:{          reuseExistingChunk:true,},},},},};

splitChunks.cacheGroups.{cacheGroup}.type

functionRegExpstring

Allows to assign modules to a cache group by module type.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        json:{          type:'json',},},},},};

splitChunks.cacheGroups.test

splitChunks.cacheGroups.{cacheGroup}.test

function (module, { chunkGraph, moduleGraph }) => booleanRegExpstring

Controls which modules are selected by this cache group. Omitting it selects all modules. It can match the absolute module resource path or chunk names. When a chunk name is matched, all modules in the chunk are selected.

Providing a function to{cacheGroup}.test:

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        svgGroup:{test(module){// `module.resource` contains the absolute path of the file on disk.// Note the usage of `path.sep` instead of / or \, for cross-platform compatibility.const path=require('path');return(              module.resource&&              module.resource.endsWith('.svg')&&              module.resource.includes(`${path.sep}cacheable_svgs${path.sep}`));},},        byModuleTypeGroup:{test(module){return module.type==='javascript/auto';},},},},},};

In order to see what information is available inmodule andchunks objects, you can putdebugger; statement in the callback. Thenrun your webpack build in debug mode to inspect the parameters in Chromium DevTools.

Providing aRegExp to{cacheGroup}.test:

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        defaultVendors:{// Note the usage of `[\\/]` as a path separator for cross-platform compatibility.          test:/[\\/]node_modules[\\/]|vendor[\\/]analytics_provider|vendor[\\/]other_lib/,},},},},};

splitChunks.cacheGroups.{cacheGroup}.filename

stringfunction (pathData, assetInfo) => string

Allows to override the filename when and only when it's an initial chunk.All placeholders available inoutput.filename are also available here.

warning

This option can also be set globally insplitChunks.filename, but this isn't recommended and will likely lead to an error ifsplitChunks.chunks is not set to'initial'. Avoid setting it globally.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        defaultVendors:{          filename:'[name].bundle.js',},},},},};

And as a function:

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        defaultVendors:{filename:(pathData)=>{// Use pathData object for generating filename string based on your requirementsreturn`${pathData.chunk.name}-bundle.js`;},},},},},};

It is possible to create a folder structure by providing path prefixing the filename:'js/vendor/bundle.js'.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        defaultVendors:{          filename:'js/[name]/bundle.js',},},},},};

splitChunks.cacheGroups.{cacheGroup}.enforce

boolean = false

Tells webpack to ignoresplitChunks.minSize,splitChunks.minChunks,splitChunks.maxAsyncRequests andsplitChunks.maxInitialRequests options and always create chunks for this cache group.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        defaultVendors:{          enforce:true,},},},},};

splitChunks.cacheGroups.{cacheGroup}.idHint

string

Sets the hint for chunk id. It will be added to chunk's filename.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        defaultVendors:{          idHint:'vendors',},},},},};

Examples

Defaults: Example 1

// index.jsimport('./a');// dynamic import
// a.jsimport'react';//...

Result: A separate chunk would be created containingreact. At the import call this chunk is loaded in parallel to the original chunk containing./a.

Why:

  • Condition 1: The chunk contains modules fromnode_modules
  • Condition 2:react is bigger than 30kb
  • Condition 3: Number of parallel requests at the import call is 2
  • Condition 4: Doesn't affect request at initial page load

What's the reasoning behind this?react probably won't change as often as your application code. By moving it into a separate chunk this chunk can be cached separately from your app code (assuming you are using chunkhash, records, Cache-Control or other long term cache approach).

Defaults: Example 2

// entry.js// dynamic importsimport('./a');import('./b');
// a.jsimport'./helpers';// helpers is 40kb in size//...
// b.jsimport'./helpers';import'./more-helpers';// more-helpers is also 40kb in size//...

Result: A separate chunk would be created containing./helpers and all dependencies of it. At the import calls this chunk is loaded in parallel to the original chunks.

Why:

  • Condition 1: The chunk is shared between both import calls
  • Condition 2:helpers is bigger than 30kb
  • Condition 3: Number of parallel requests at the import calls is 2
  • Condition 4: Doesn't affect request at initial page load

Putting the content ofhelpers into each chunk will result into its code being downloaded twice. By using a separate chunk this will only happen once. We pay the cost of an additional request, which could be considered a tradeoff. That's why there is a minimum size of 30kb.

Split Chunks: Example 1

Create acommons chunk, which includes all code shared between entry points.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        commons:{          name:'commons',          chunks:'initial',          minChunks:2,},},},},};
warning

This configuration can enlarge your initial bundles, it is recommended to use dynamic imports when a module is not immediately needed.

Split Chunks: Example 2

Create avendors chunk, which includes all code fromnode_modules in the whole application.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        commons:{          test:/[\\/]node_modules[\\/]/,          name:'vendors',          chunks:'all',},},},},};
warning

This might result in a large chunk containing all external packages. It is recommended to only include your core frameworks and utilities and dynamically load the rest of the dependencies.

Split Chunks: Example 3

Create acustom vendor chunk, which contains certainnode_modules packages matched byRegExp.

webpack.config.js

module.exports={//...  optimization:{    splitChunks:{      cacheGroups:{        vendor:{          test:/[\\/]node_modules[\\/](react|react-dom)[\\/]/,          name:'vendor',          chunks:'all',},},},},};
tip

This will result in splittingreact andreact-dom into a separate chunk. If you're not sure what packages have been included in a chunk you may refer toBundle Analysis section for details.

17 Contributors

sokrajeremenichelliPriestchchrisdothtmlEugeneHlushkobyzykjacobangelmadhavarshneysakhisheikhsuperburritoryandrew14snitin315chenxsanrohrlafjamesgeorge007anshumanvsnitin315

[8]ページ先頭

©2009-2025 Movatter.jp