2020年春节已过,原本打算回郑州,却由于新型冠状病毒感染肺炎的疫情公司推迟了上班的时间,我也推迟了去郑州的时间,在家多陪娃几天。之前都是在书房学习写博客,今天比较特殊,抱着电脑,在楼顶晒着太阳,陪着家人,写着博客。javascript
前面的几篇文章主要告诉你们如何安装、配置webpack、webpack实现样式分离等,今天这篇文章主要跟你们分享若是webpack如何实现代码分片。css
如今工程项目中,实现高性能应用的其中重要的一点就是让用户每次只加载必要的资源,优先级别不过高的资源采用延迟加载等技术渐进地进行加载获取。html
Webpack 做为打包工具所特有的一项技术就是代码分片技术,经过这项技术咱们能够把代码按照特定的形式进行拆分,使用按需加载资源,没必要要所有加载下来。 代码分片能够有效下降首屏加载资源的大小,可是咱们同时又面临着其余问题,好比如何对项目模块进行分片,分片后的资源如何进行管理等等。今天咱们须要对这些问题进行分析解决。java
在Webpack中,配置参数中每一个入口都将生成一个对应的资源文件,经过入口的配置咱们能够进行一些简单有效的代码拆分。node
对于项目中经常会引入一些第三方库和工具,这些通常不会改动的,能够把它们单独放在一个入口中,由该入口的资源不会常常更新,所以能够有效利用客户端缓存这些资源,让用户没必要在每次请求页面时候都从新加载。react
//webpack.config.js
entry: {
index: './index.js',
lib: ['lib-1', 'lib-2']
}
//index.html
<script src="dist/lib.js"></script>
<script src="dist/index.js"></script>
复制代码
这种拆分方法主要适合于那些将接口绑定在全局对象上的库,由于业务代码中的模块没法直接引用库中的模块,两者属于不一样的依赖树。webpack
对于多页面应用来讲,咱们能够利用入口划分的方式拆分代码。好比,为每个页面建立一个入口,并放入只涉及该页面的代码,同时再建立一个入口来包含全部公共模块,并使每一个页面都进行加载。可是这样仍会带来公共模块与业务模块处于不一样依赖树的问题。另外,不少时候不是全部的页面都须要这些公共模块。这就须要咱们利用webpack专用的插件来解决这种问题了。web
CommonsChunkPlugin是webpack4以前内部自带的插件,webpack4以后用的是SplitChunks。CommonsChunkPlugin主要是用来提取第三方库和公共模块,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大,从而致使加载时间过长,是一把优化项目的利器。浏览器
优势:缓存
//webpack.config.js
module.exports = {
entry: {
a: './a.js',
b: './b.js'
},
output: {
filename: '[name].js'
}
}
//a.js
import React from 'React'
... //省略
// b.js
import React from 'React'
... //省略
复制代码
若是打包,从打包的资源体积能够看出,react被分别打包到a.js 和b.js中。
更改webpack.config.js,添加CommonsChunkPlugin配置
const webpack = require('webpack');
module.exports = {
entry: {
a: './a.js',
b: './b.js'
},
output: {
filename: '[name].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: 'commons.js'
})
]
}
复制代码
在配置文件的头部引入Webpack,接着使用其内部CommonsChunkPlugin函数建立了一个插件实例,并传入配置对象,配置参数能够理解为
在提取公共模块方面,CommonsChunkPlugin能够知足不少场景的需求,可是它也有一些欠缺的地方。 1)一个CommonsChunkPlugin只能提取一个vendor,假如咱们想提取多个vendor则须要配置多个插件,这会增长不少重复的配置代码。
2)前面咱们提到的manifest实际上会使浏览器多加载一个资源,这对于页面渲染速度是不友好的。
3)因为内部设计上的一些缺陷,CommonsChunkPlugin在提取公共模块的时候会破坏掉原有Chunk中模块的依赖关系,致使难以进行更多的优化。好比在异步Chunk的场景下CommonsChunkPlugin并不会按照咱们的预期正常工做。
optimization.SplitChunks(简称SplitChunks)是Webpack 4为了改进CommonsChunk-Plugin而从新设计和实现的代码分片特性。它不只比CommonsChunkPlugin功能更增强大,还更简单易用。
配置文件web pack.config.js为:
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
context: path.join(__dirname, './src'),
entry: {
index: './index.js'
},
output: {
// path: path.join(__dirname, 'dist'),
filename: 'index.js',
publicPath: '/dist/'
},
mode: 'development',
optimization: {
splitChunks: {
chunks: 'all'
}
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', {
loader: 'css-loader',
options: {
modules: {
localIdentName: '[path][name]__[local]--[hash:base64:5]',
}
}
}]
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: [
[
'env', {
modules: false
}
]
]
}
}
}
],
}
}
复制代码
须要引入的两个index.js文件和index2.js文件
// index
import index2 from './index2.js';
import React from 'react'
document.write('index.js', React.version);
//index2
import React from 'react'
document.write('index2.js', React.version);
复制代码
使用optimization.splitChunks替代了CommonsChunkPlugin,并指定了chunks的值为all,这个配置项的含义是,SplitChunks将会对全部的chunks生效(默认状况下,SplitChunks只对异步chunks生效,而且不须要配置) 打包结果以下图:
本来咱们打包的结果应该是index.js,可是因为SplitChunks的存在,又生成了一个vendors~index.index.js,而且把react提取到了里面。 运行的效果以下图:
SplitChunks 默认的提取方式是异步提取,当咱们在chunks上配置参数为all的时候,不是异步资源也能够提取。
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
minRemainingSize: 0,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 6,
maxInitialRequests: 4,
automaticNameDelimiter: '~',
name: true,
automaticNameMaxLength: 30,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
复制代码
(1)匹配模式经过chunks咱们能够配置SplitChunks的工做模式。它有3个可选值,分别为async(默认)、initial和all。async即只提取异步chunk,initial则只对入口chunk生效(若是配置了initial则上面异步的例子将失效),all则是两种模式同时开启。
(2)匹配条件minSize、minChunks、maxAsyncRequests、maxInitialRequests都属于匹配条件,
(3)命名配置项name默认为true,它意味着SplitChunks能够根据cacheGroups和做用范围自动为新生成的chunk命名,并以automaticNameDelimiter分隔。如vendors~a~b~c.js意思是cacheGroups为vendors,而且该chunk是由a、b、c三个入口chunk所产生的。
(4)cacheGroups能够理解成分离chunks时的规则。默认状况下有两种规则——defaultVendors和default。defaultVendors用于提取全部node_modules中符合条件的模块,default则做用于被屡次引用的模块。咱们能够对这些规则进行增长或者修改,若是想要禁用某种规则,也能够直接将其置为false。当一个模块同时符合多个cacheGroups时,则根据其中的priority配置项肯定优先级。
有关webpack实现代码分片的几种方法:合理地规划入口,使用Commons-ChunkPlugin或SplitChunks就暂时分享到这里,这仅表明我的的观点,如想了解更多请扫描二维码