-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecation warning on CommonChunksPlugin. Add SplitChunksPlugin page #1863
Conversation
This moves some of the content from `compiler.md` and brings it into the main node api documentation in order to allow `compiler.md` to become `compiler-hooks.md` which fits better in the context of plugins.
…le.md` This moves some of the `Tapable` discussion to the lead-in `plugins.md` to prevent doc duplication. Instead of redocumenting the `tapable` package, we should focus on improving the README and simply link to there throughout our docs. As I've mentioned before, we can also create a "Utilities" section for things other than "Loaders" and "Plugins" that we want to dynamically pull in.
These guides were full of todos and probably lead to more confusion than clarity. We can discuss more and add them back in once there's a clear flow for how to incorporate and document them.
This page now focuses specifically on the `hooks` as all the non-plugin related content was moved to `node.md`. I updated the hooks to the new syntax, added all undocumented hooks, reformatted each hook as a section to allow more breathing room, and clarified exactly which `tapable` hook is used for each section. Still need to get more info on some of the new hooks before we can ship this...
This page now uses the same section setup as `compiler-hooks.md` and is up to date with the latest hooks available in the webpack 4 alpha release.
Improve lead-in to give a little more context on what the parser does. Add the latest hooks and use the same layout as the other pages in the section.
Great initial work! |
@skipjack I want to bother you as less as possible, but tagging you here since it's a whole new page that would love to have a look from you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, don't worry about pinging me. Happy to come back and do reviews here and there.
The `CommonsChunkPlugin` is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points. By separating common modules from bundles, the resulting chunked file can be loaded once initially, and stored in cache for later use. This results in pagespeed optimizations as the browser can quickly serve the shared code from cache, rather than being forced to load a larger bundle whenever a new page is visited. | ||
The `CommonsChunkPlugin` is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points. | ||
|
||
W> CommonsChunkPlugin has been deprecated in webpack v4 legato. If you want to know how chunks are treated in the newest version checkout [SplitChunksPlugin](/plugins/split-chunks-plugin/). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rephrase this slightly:
The
CommonsChunkPlugin
has been deprecated in webpack v4 legato.. To learn how chunks are treated in the latest version, check out theSplitChunksPlugin
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/legato../legato.
|
||
Originally in webpack, chunks (and modules import inside them) were connected by a parent-child relationship in the internal webpack graph. | ||
|
||
This connection didn't allow to further optimizations and reluted into more coded downloaded. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/reluted/resulted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/more coded downloaded/more downloaded code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/allow to/allow for/
cacheGroups: { | ||
default: { | ||
minChunks: 2, | ||
priority: -20 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comma is missing
splitChunks: { | ||
cacheGroups: { | ||
commons: { | ||
test: /[\\/]node_modules[\\/] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a slash-comma: test: /[\\/]node_modules[\\/]/,
|
||
Out of the box `SplitChunksPlugin` should work great for most users. | ||
|
||
By default the plugin only affect on-demand chunks, because changing initial chunks would affect the script tags that the HTML file should include to run the project. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
affect
should be affects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@blowery I don't agree, affect is correct grammar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@audiolion, are you sure? I think if "plugin" were plural, then I agree "affect" should be used (ie "the plugins only affect on-demand chunks"), however given it's singular, "affects" seems more correct to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha, I was reading the wrong "affect", initial chunks would affect(s) the script tags...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol, same happened to me. Thanks.
|
||
For these people that like to have more control over this functionality, webpack provides a set of options to better fit your needs. | ||
|
||
W> If you are manually changing the split configuration, measure the impact of the changes to see and make sure there's a real benefit. The defaults are choosen to fit best practices of web performance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/choosen/chosen
(change below my opinion, not related to grammar):
s/fit best practices of web performance/fit web performance best practices
|
||
### Configuring cache groups | ||
|
||
The defaults assigns all modules from `node_modules` to a cache group called `vendors` and all modules duplicated in at least 2 chunks to a change group `default`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/change group/cache group
I notice these docs don't include any information about the
Please correct me if I am mistaken: The |
|
||
## `optimization.runtimeChunk` | ||
|
||
Setting `optimization.runtimeChunk` to `true` adds an additonal chunk to each entrypoint containing only the runtime. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
include the different things that you can pass to runtimeChunk. It can be a boolean, 'single'
, 'multiple'
or an object that has property name
whose value can be either a string or a function of signature (entrypoint: Chunk) => string
e.g.
{
name: entrypoint => `runtime~${entrypoint.name}`
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @sokra can you fill in some technical gap here? Should we add enforce
details in this piece, I would need your help with it 😓
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is its default value? In this blog post it says it's true
, but from trying it out it's not.
* Maximum number of parallel request when loading chunks on demand would be lower or equal to 5 | ||
* Maximum number of parallel request at initial page load would be lower or equal to 3 | ||
|
||
When trying to fullfill the last two conditions, bigger chunks are preferred. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fullfill
-> fulfill
webpack will automatically split chunks based on these conditions: | ||
|
||
* New chunk can be shared OR modules are from the `node_modules` folder | ||
* New chunk would be bigger than 30kb (before min+gz) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kb -> KiB (here and elsewhere)
|
||
W> When assigning equal names to different split chunks they are merged together. This can be used to put all vendor modules into a single shared chunk, but it's not recommend since it can result in more code downloaded. | ||
|
||
The magic value `true` automatically chooses a name based on chunks and cache group key. Elsewise a string or function can be passed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Elsewise/Otherwise
Thanks everyone for all your feedback. Working on updates and getting changes pushed soon. |
|
||
W> CommonsChunkPlugin has been deprecated in webpack v4 legato. If you want to know how chunks are treated in the newest version checkout [SplitChunksPlugin](/plugins/split-chunks-plugin/). | ||
|
||
By separating common modules from bundles, the resulting chunked file can be loaded once initially, and stored in cache for later use. This results in pagespeed optimizations as the browser can quickly serve the shared code from cache, rather than being forced to load a larger bundle whenever a new page is visited. | ||
|
||
```javascript | ||
new webpack.optimize.CommonsChunkPlugin(options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be removed? or replaced with:
optimization: {
splitChunks: {
name: 'all',
},
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the old CommonsChunkPlugin page. We are keeping the old documentaiton for teams that are already using it and haven't migrated to v4. We are adding a warning on top talking about the deprecation of it from now on.
|
||
`cacheGroups` is an object where keys are the cache group names. All options from the ones listed above are possible: `chunks`, `minSize`, `minChunks`, `maxAsyncRequests`, `maxInitialRequests`, `name`. | ||
|
||
You can set `optimization.splitChunks.cacheGroups.default` to `false` to disable the default cache group. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for optimization.splitChunks.cacheGroups.vendors
.
|
||
Here are some examples and their effect: | ||
|
||
### Example 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add another example:
Enable the default optimizations for all chunks instead of only async chunks. This is the recommended configuration.
splitChunks: {
chunks: "all"
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a specific section for chunks: "all"
so we highlight this configuration set as recommended, pushing in a bit.
} | ||
} | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default this configuration will only create a commons chunk when the minimum size and maximum number of requests are valid. Adding enforce: true
, will disable any not configured condition and enforce creating the chunk.
|
||
You can set `optimization.splitChunks.cacheGroups.default` to `false` to disable the default cache group. | ||
|
||
The priority of the default groups are negative to allow any custom cache group to take higher priority (the default value is `0`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The priority
controls the order in which cache groups are executed. Higher priorities will execute before lower priorities.
url: https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366 | ||
--- | ||
|
||
Originally in webpack, chunks (and modules import inside them) were connected by a parent-child relationship in the internal webpack graph. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/modules import/modules imported/
|
||
Originally in webpack, chunks (and modules import inside them) were connected by a parent-child relationship in the internal webpack graph. | ||
|
||
This connection didn't allow to further optimizations and reluted into more coded downloaded. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/allow to/allow for/
|
||
This connection didn't allow to further optimizations and reluted into more coded downloaded. | ||
|
||
webpack v4 removes the `CommonsChunkPlugin` in favor of `optimization.splitChunks` and `optimization.runtimeChunk` options. Here is how the new flow works. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/favor of/favor of the/
|
||
Out of the box `SplitChunksPlugin` should work great for most users. | ||
|
||
By default the plugin only affect on-demand chunks, because changing initial chunks would affect the script tags that the HTML file should include to run the project. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@audiolion, are you sure? I think if "plugin" were plural, then I agree "affect" should be used (ie "the plugins only affect on-demand chunks"), however given it's singular, "affects" seems more correct to me.
* New chunk can be shared OR modules are from the `node_modules` folder | ||
* New chunk would be bigger than 30kb (before min+gz) | ||
* Maximum number of parallel request when loading chunks on demand would be lower or equal to 5 | ||
* Maximum number of parallel request at initial page load would be lower or equal to 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/parallel request/parallel requests/ (x2)
|
||
## Configuration | ||
|
||
For these people that like to have more control over this functionality, webpack provides a set of options to better fit your needs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/For these people/For people/
|
||
### Select modules | ||
|
||
The `test` option controls which modules are selected by this cache group. Omitting it selects all modules. It can be a RegExp, string or function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if this section went more into details about the function version of this option, e.g. what the args to the function are, how to use them, and what the function should return.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, it looks like test
fn is called with 2 args. module
and chunks
.
I think module
is an object that describes the chunk being considered for placement, and chunks
seems to be an array of objects with metadata about each chunk. I'm not sure where these are documented or defined in code yet.
It seems that test
functions should return a boolean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each chunk object seems to have these keys:
id
ids
debugId
name
entryModule
_modules
_groups
files
rendered
hash
renderedHash
chunkReason
extraAsync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I imagine that boolean decides if the current module goes to a chunk or not.
|
||
By default cache groups inherit options from `splitChunks.*`, but `test`, `priority` and `reuseExistingChunk` can only be configured on cache group level. | ||
|
||
`cacheGroups` is an object where keys are the cache group names. All options from the ones listed above are possible: `chunks`, `minSize`, `minChunks`, `maxAsyncRequests`, `maxInitialRequests`, `name`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like cacheGroups
can also be a function? Should this be documented here? https://github.com/webpack/webpack/blob/66ff412f7e2409ee535c2dc79abf4068015b2e22/lib/optimize/SplitChunksPlugin.js#L132
|
||
Putting the content of `helpers` 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. | ||
|
||
T> With the new `optimizations.splitChunks.chunks: "all"` option the same would happend for initial chunks. Chunks can even be shared between entrypoints and on-demand loading. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/optimizations/optimization/
Thanks everyone for the comments, I'm creating a new pull request since the @sokra I will create an issue with some stuff that needs to be revisited or cover in the split chunks article. Thanks for the comments. |
Adding Tobias as a reviewer since I used his gist as a base for the SplitChunksPlugin page. I've also added a deprecation warning on CommonChunksPlugin one (not deleting it for now since developers and teams who can immediately migrate might need it).