基本使用
拆分配置和merge
依赖包:webpack-merge
demo
如下图,webpack.common.js为公共配置,webpack.prod.js为正式环境配置,引入使用方式如下图
处理样式
从后入前,例如下图,先执行postcss-loader再执行css-loader
高级配置
多入口
抽离压缩css
依赖:mini-css-extract-plugin
抽离公共代码和第三方代码
optimization.splitChunks
可以配置名称,大小限制,被引用多少次
异步加载
webpack本来就支持,下图是同步加载和懒加载
module,chunk,bundle的区别
- module:各个源码文件(js,css,.vue,图片),webpack中一切皆模块
- chunk:多模块合成,如entry,import(), splitChunk
- bundle 最终的输出文件
chunk
dynamic-data.js里面也可能引用了其它
index.js里面也可能引用了其它
webpack 性能优化
- 优化打包构建速度--开发体验和效率
- 优化babel-loader
- IgnorePlugin
- noParse
- happyPack
- parallelUglifyPlugin
- 自动刷新
- 热更新
- Dllplugin
- 优化产出代码--产品性能
优化打包构建速度
可以用于生产环境
- 优化babel-loader
- IgnorePlugin
- noParse
- happyPack
- parallelUglifyPlugin
不用于生产环境
- 自动刷新
- 热更新
- Dllplugin
优化babel-loader
- 开启缓存:缓存已经从es6转化为es5的代码
- include:指定哪些文件会转化
happyPack
- js单线程,开启多进程打包
- 多核cpu
- 注意如果项目比较小的话,开启多进程会降低速度(进程开销),可以不开,只有项目比较大时,开启多进程能提高速度,才有显著效果
parallelUglifyPlugin
- js单线程,开启多进程压缩
-
- 注意如果项目比较小的话,开启多进程会降低速度(进程开销),可以不开,只有项目比较大时,开启多进程能提高速度,才有显著效果
除了压缩,还可以去掉注释,console.log
自动刷新,热更新
自动刷新: 整个网页全部刷新,速度较慢,状态会丢失 热更新: 新代码生效,网页不刷新,状态不丢失
热更新
DllPlugin 动态链接库插件
使用背景
- 前端框架如vue react,体积大,构建慢
- 较稳定,不常升级版本
- 同一个版本只构建一次即可,不用每次都重新构建
怎么使用
先用DllPlugin插件,打包出dll文件,再用DllReferencePlugin,使用dll文件
- webpack已内置DllPlugin支持
- DllPlugin--打包出dll文件
- DllReferencePlugin--使用dll文件
优化产出代码
- 体积更小
- 合理分包,不重复加载
- 速度更快,内存使用更少
小图片base64编码
-
base64减少http请求,转为base64小图片可以跟js同时被加载到浏览器,不需要多次对服务器发出图片资源请求
-
如果所有图片均转码为base64,那么很容易造成存储base64的js文件过大,一方面会造成资源加载时间过长的白屏问题,另一方面也会给js解释器带来非常大的负担,这样反而起不到优化的作用,而且会非常影响体验
bundle加hash
bundle为最终打包出来的文件,hash是根据文件内容生成的值,如果内容没有变,则不用请求,直接使用缓存
懒加载
提取公共代码
IngorePlugin
例如多语言
使用CDN加速
打包的时候可以把静态文件打包分离出来,在文件名上加上cdn地址,再配合运维或者手动上传到cdn上
使用production
- 自动开启代码压缩
- vue react 等会自动删除掉调试代码(如开发环境下的warning)
- 启动Tree-shaking
scope hosting
- 代码体积更小
- 创建函数作用更少
- 代码可读性更好
使用背景
怎么使用
Tree-shaning
摇树:摇一下,把不用的东西摇掉
注意:es6 module才能让Tree-shaning生效,commonjs不行
实例
math.js下有sum和mult方法,但是只引入使用了sum,可以看到打包出来的文件只能搜索到+,并没有搜索到*,证明nult并没有被打包进去
ES6 Module和Commonjs的区别
- ES6 Module静态引入,编译时引入
- Commonjs 动态引入,执行时引入
- 只有ES6 Module才能静态分析,实现Tree-shaning
实例
// 不知道isDev变量的情况,apiList可能会被引入,也可能不被引入
if(isDev){
const apiList = require('../config/api_dev.js')
}
//编辑时报错,不允许这种写法
if(isDev){
import apiList from '../config/api_dev.js'
}