1、 Modular development of JS
javascript
The reason why we need to package and merge is because of the existence of modular development. In the development phase, we need tojs
The files are written separately in many fragmentary files, which is convenient for debugging and modification. However, if you go online in this way, the first page will behttp
The number of requests will explode directly. For the same project, other people will get the required documents after 2-3 requests, while yours may need 20-30, so the results need not be mentioned.
But merge scripts are not“Copy all the fragmented files into one filejs
“In the file”In this way, we can not only solve the problem of namespace conflicts, but also need to be compatible with different modular solutions, not to mention manually determining the loading order of modules according to the complex dependency relationship between modules. Therefore, we use automation tools to integrate the modules in the development phasejs
It is necessary to merge and optimize script fragments.
2、 General packaging requirements of JS files
- Code compilation(
TS
orES6
Code compilation) - Script merge
- Common module identification
- Code segmentation
- Code compression confusion
3、 Using webpack to process JS file
3.1 using Babel to transform ES6 + syntax
babel
yesES6
Syntax conversion tool, rightbabel
Readers who don’t know can read it firstBabel, the automation factory of big front end (3)We need to know more about it,babel
Andwebpack
The combination method is also introduced here. Only the basic configuration is provided here
webpack.config.js
:
...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
]
}
]
},
...
.babelrc
:
{
"presets":[
["env",{
"targets":{
"browsers":"last 2 versions"
}
}
]],
"plugins": [
"babel-plugin-transform-runtime"
]
}
3.2 script merging
usewebpack
Merging scripts is very convenient, after allModule managementandFile mergeThese two functions arewebpack
The main purpose of the original design is not complicated until it comes to the topic of subcontracting and lazy loading.webpack
It’s very convenient to use because it implements the compatibility of different module specifications. For front-end developers, it’s better to understand the compatibility implementation than to learn how to configurewebpack
More important.webpack
The default support isCommonJs
But at the same time, in order to expand its use scenarios,webpack
In the subsequent version iteration, we also add theES harmony
And other specifications define the compatibility of the module, the specific processing method will be in the next chapterWebpack 4.0: moduleDetailed analysis.
3.3 common module identification
webpack
You can see the following parts in the output file of
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
above__webpack_require__( )
The way iswebpack
Module loader, it is easy to see that there is a unified for the loaded moduleinstalledModules
Object to manage, so as to avoid the problem of repeated module loading. The common module also needs to start from thebundle.js
File, which refers to the content of “code segmentation” in the next section.
3.4 code segmentation
1. Why code segmentation?
The basic task of code segmentation is to separate the third-party dependency library. Because the content of the third-party dependency library may not change for a long time, it is used to mark the change summary hashcontentHash
This means that we can use the local cache to avoid unnecessary duplicate packaging, and use the browser cache to avoid redundant client loading. In addition, when the project releases a new version, if the third party relies oncontentHash
No change, you can use the client’s original cache file (the general practice is to set a large cache for static resource requests)max-age
), improve access speed. In other scenarios, code segmentation can also provide the ability to control the loading time of the script in the whole loading cycle.
2. Use scenarios of code segmentation
Take a very common example, for example, you are doing a data visualization type website, which refers to BaiduEcharts
As a third-party library to render charts, if you put your own code andEcharts
Package them together to create amain.bundle.js
The result is that when you open your website in an environment with poor network speed, users may have to face a long time of white screen, and you will soon think of the futureEcharts
Separate from the main file, let the smaller main file render some animation or prompt information on the interface, and then load itEcharts
And separated outEcharts
You can also start from fasterCDN
Node acquisition: if a huge library is loaded, you can also choose to use the lazy loading scheme to delay the script download time until the user actually uses the corresponding function. This is a kind of manual code segmentation.
From the whole life cycle of the above example, we split the script that can be loaded at one time into two times, which will undoubtedly increase the performance overhead of the server. After all, establishing a TCP connection is a very expensive operation, but it can be exchangedControl of rendering rhythm and improvement of user experience,Asynchronous moduleandLazy loading moduleFrom a macro point of view, they all belong toCode segmentationThe scope of the study.code splitting
The most extreme situation is actually to split it into its original appearance before packaging, that isSource code directly online。
3. The nature of code segmentation
The essence of code segmentation is to“Source code directly online”and“Package as a unique script main.bundle.js “Between these two extreme solutions, we need to find an intermediate state which is more in line with the actual situation, and exchange the acceptable server performance pressure for a better user experience.
4. Configure code segmentation
code-splitting
The configuration and usage of the technology will be described in detail in the next section.
5. More detailed code segmentation
Interested readers can refer to articles from Google developer community 《Reduce JavaScript Payloads with Code Splitting》 Self study.
3.5 code obfuscation compression
webpack4
It’s built inUglifyJs
Plug in, when packing mode parametersmode
Set toproduction
It’s not the only option, of course,babel
The plug-in can also provide code compression processing, the specific effect and principle of the author has not been studied, interested readers can study on their own.
4、 On split chunks Technology
4.1 parameter description
webpack4
AbandonedCommonsChunkPlugin
Plug in, usingoptimization.splitChunks
andoptimization.runtimeChunk
Instead, the reason can be referred toWebpack 4: evolution in the ensembleOne article. aboutruntimeChunk
Parameters. Some articles say that the runtime part of the import and export chunk is extracted to form a separate file. Because this part does not change often, you can use the cache. The blog post of Google developer community is described as follows:
The
runtimeChunk
option is also specified to move webpack’s runtime into thevendors
chunk to avoid duplication of it in our app code.
splitChunks
The default requirement for automatic code segmentation in is as follows:
- node_ Modules in modules or other repeatedly referenced modules
That is, if the referenced module comes from
node_modules
As long as it is referenced, it can be automatically segmented when other conditions are met. Otherwise, the module needs to be repeatedly referenced to judge other conditions. (corresponding to the configuration options belowminChunks
1 or 2) - Minimum volume limit of module before separation (default 30K, modifiable)
30K is the default value given by the government. It can be modified. As mentioned in the previous section, each subcontract corresponds to an increase in the performance cost of the server, so the cost performance of the subcontract must be considered.
- For asynchronous modules, the number of generated common module files cannot exceed 5 (modifiable)
When the download of lazy loading module is triggered, the number of concurrent requests should not exceed 5. For developers who have a little knowledge of server technology,[high concurrency]and[stress test]Such keywords should not be strange.
- For the entry module, the number of public module files to extract cannot exceed 3 (modifiable)
That is to say, the maximum number of parallel requests for an entry file cannot exceed 3 by default. The reason is the same as above.
4.2 parameter configuration
splitChunks
Yes, it iswebpack
The usage above 4.0 is as follows:
module.exports = {
//...
optimization: {
splitChunks: {
Chunks: 'async' // only works on asynchronous modules by default. When it is' all ', it works on all modules, and' initial 'works on synchronous modules
Minsize: 30000, // volume of module file before merging
Minchunks: 1, // minimum number of references
maxAsyncRequests: 5,
maxInitialRequests: 3,
Automaticnamedelimiter: '~' // automatically name the connector
cacheGroups: {
vendors: {
test: /[\/]node_modules[\/]/,
minChunks:1 , // knock on the blackboard
Priority: - 10 // higher priority
},
default: {
test: /[\/]src[\/]js[\/]/
Minchunks: 2, // it is generally a non third party public module
priority: -20,
reuseExistingChunk: true
}
},
runtimeChunk:{
name:'manifest'
}
}
}
4.3 code segmentation examples
Note: the demo and configuration file used in the example have been attached.
- Single page application
A single page application has only one entry file,
splitChunks
The main function of is to split the referenced third-party library. As can be seen from the following subcontracting results,node_modules
Third party references in are separated and placed in thevendors-main.[hash].js
In the middle.
-
Multi page application
The situation of multi page application is a little more complicatedWebpack 4: evolution in the ensembleThe example in this article is code segmentation. The source code dependency is as follows:
entryA.js: vue vuex component10k entryB.js: vue axios component10k entryC.js: vue vuex axios component10k
The package after code segmentation is shown in the following figure:
splitChunks
It provides a more accurate segmentation strategy, but it seems that it can not be directly passedhtml-webpack-plugin
Configure parameters to dynamically solve the problem of code injection after segmentation, because the subcontract name is uncertain. This scene is in usechunks:'async'
The default configuration does not exist because the asynchronous module reference code does not need to be<script>
Label injectionhtml
The number of documents.
Whenchunks
Configuration item set toall
orinitial
For example, in the above example, thehtml-webpack-plugin
Medium configurationexcludeChunks
Can be removedpageandaboutThese two chunks, however, cannot be excluded in advancevendors-about-pageThis is because it is impossible to know whether such a chunk will be generated before packaging. The author has not found a ready-made solution for this scenario. Readers who need this scenario may use ithtml-webpack-plugin
OfEvent extensionTo deal with this kind of scenario, you can also use a compromise scheme, that is, after the first packaging, record the newly generated chunk name, and fill in thehtml-webpack-plugin
Ofchunks
Configuration item.
4.4 result analysis
adoptBundle Buddy
Analysis tools orwebpack-bundle-analyser
The plug-in can see the impact on the extraction of public code before and after subcontracting (the picture is from the blog post of the reference)
5、 Reference and appendix description
【1】 Description of attached documents:
webpack.spa.config.js
——Single page application code segmentation configuration examplemain.js
——Single page application entry filewebpack.multi.config.js
——Multi page application code segmentation configuration exampleentryA.js
,entryB.js
,entryC.js
——Three entrances of multi page application
【2】 References:《Reduce JavaScript Payloads with Code Splitting》