webpack 配置splitChunk实现代码分割以及代码异步加载
首先,安装一个babel插件
npm install --save-dev @babel/plugin-syntax-dynamic-import
然后在.babelrc中配置
"plugins": ["@babel/plugin-syntax-dynamic-import"]
接着,在webpack.config.js中配置optimization选项
...
// 代码分割功能
optimization: {
splitChunks: {
chunks: 'all', // 配置'all':同步异步代码都做分割,然后看cacheGroups的配置去分组与名字;配置'async'只对异步代码做分割; 默认'initial'同步代码做分割
}
},
最后在代码中异步引入你的模块,比如lodash,要这么写:
import('lodash').then(_ => {console.log('异步加载lodash完毕!')})
webpack打包一个库
module.exports = {
output: {
filename: 'index.js',
library: 'library', // 打包库专用 挂载到全局下
libraryTarget: 'umd' // 打包库专用 支持conmmonjs esModule AMD CMD的引入
}
}
package.json
"src": "dist/index.js"
PWA
workbox-webpack-plugin
// webpack.config.js里面配置
const WorkBoxWebpackPlugin = require('workbox-webpack-plugin')
modlue.exports = {
plugins: [
new WorkBoxWebpackPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true
})
]
}
// 业务代码里面注册service-worker
if('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then().catch()
})
}
typescript配置
- ts-loader
- 根目录配置tsconfig.json
- 如果引入第三方js 需要加对应的提示插件,如lodash 就安装 @types/lodash
eslint
npm install eslint eslint-loader -D
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['eslint-loader']
}
]
}
}
根目录配置 .eslint.js
优化
- 配置resolve参数
module.exports = {
resolve: {
extensions: ['.js', '.jsx'], //
alias: {
'@': path.resolve(__dirname, 'src')
}
}
}
然后在项目中
比如 a.js在第三层目录,b.jsx在第一层目录,那么a引入b这样写:
const b = import('../../b.jsx')
改用resolve extensions 和 alias的写法后:
const b = import('@/b')
省略后缀名和相对路径的寻址
-
配置Dllplugint提升打包速度
目的是把不变的第三方库,先打包成一个dll库 和对应的mainifast.json,然后在项目里面的plugin配置中配置AddAssetPlugin,DllReferencePlugin,把打包流程中的dll相关库提取出来用。这样子每次run dev 或者build的时候就不用去解析打包这些文件了,达到减少构建这些第三方库的时间的目的。 -
减少loader的应用范围
目的:在一些loader里面加上exclude 或者 include配置,确保范围,减少不必要的分析转换,加快打包速度。
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // 不分析node_modules的js
include: path.resolve(__dirname, './src') // 只分析src这个目录下的js
use: [{
loader: 'babel-loader'
}]
}
]
}
- Plugin尽可能精简并确保可靠
只在production环境用
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css'
}) // css提取分割
],
比如上面压缩css用的插件只在production环境用,那么在development环境就不要加上这些配置了;用的插件最好去官方文档找官网推荐用的,因为这些插件是经过官方验证的,性能,测试都没问题,如果你用第三方或者个人编写的插件那就很可能得不到保证。
-
控制包大小
有些包比较大,可以考虑 按需引入 或者引入轻量版的库实现同样的功能,如果有对应轻量版库的话。 -
多进程打包 thread-loader parallel-loader happypack
利用你的电脑的cpu核数进行多线程打包,这主要是提升打包速度的,和代码优化关系不大 -
合理使用sourceMap
在development环境下,我们需要追踪开发时代码详细的信息,所以我们可以用一些显示比较详细信息的sourceMap 如开发环境
devtool: 'cheap-module-eval-source-map', // 开发环境
线上环境
devtool: 'cheap-module-source-map', // 线上打包,或者直接设置 none
-
结合stats.json来分析打包内容
这主要是打包的时候用到一个图形分析工具看引入的各种资源是否是你需要的,从而工具实际情况去优化打包体积,如下图
image.png
-
开发环境剔除无用插件
有些插件是开发用的,线上环境就不要配置了 -
treeshaking
这个是比较实用的功能,起到类似按需引入的作用,如下你只用到一个函数,结果引了一个库,这明显得不偿失的,
业务代码如下面这样子,全部引入,打包会把整个lodash库打包进去
import _ from 'lodash'
console.log(_.join('1','2','3'))
这时候就应该换另外一种写法
// 按需引入
import join from 'lodash.join'
console.log(join ('1','2','3'))
// webpack.config.js
optimization: {
usedExports: true, // 对treeshaking 进行使用,但是要在package.json里面剔除那些不做不是对treeshaking的模块 如css
}
// 如果你的js有直接引入css的话,如
import 'reset.css'
import 'a.scss'
// 还要去package.json配置treeshaking 忽略的资源,就是非模块化的资源。如果你不配置的话,打包的时候,它会剔除掉这些非模块化的css,scss文件
// package.json
"sideEffects": [
"*.css",
"*.scss"
]
这样子配合treeshaking也能有效减少打包体积。
小结
以上是学习webpack的一些笔记吧,略显唠叨,不过总能在项目真正配置的时候有个回忆的思路,如有不对请指出,不胜感激。










网友评论