基本配置
- 拆分配置和merge
- 分别创建webpack.common.js , webpack.dev.js , webpack.prod.js
- common.js 里,
定义entry,
module节点 rules里js的loader, css的loader, less的loader.
plugin节点 Htmlwebpackplugin
- dev.js 里,
定义mode节点为development,
module节点 file-loader.
plugin节点 webpack.DefinePlugin配置 window.ENV=‘development’,
devServer本地服务节点
- prod.js 里,
定义mode节点为production,
module节点 rules里url-loader(base64情况)
plugin节点 webpack.DefinePlugin配置 window.ENV=‘production’
安装webpack-merge, 引入smart
- 启动本地服务
- 安装webpack-dev-server
- 在dev.js定义端口, 就是devServer节点配置项, 有port, progress(显示打包进度条), contentBase(根目录), open(自动打开浏览器), compress(启动gzip压缩). proxy节点配置代理搞定跨域, 比如现在前端接口是8080, 服务端接口是3000, 这样前端直接请求3000的话会产生跨域, 无法请求, 此时就需要配置proxy代理, 将本地 /xx/xx 代理到 localhost:3000/xx/xx
- 处理ES6
- 在common.js里rules节点配置babel-loader. 同时需要配置.babelrc文件
- 处理样式
- 在common.js里rules节点配置style-loader, css-loader, postcss-loader(注意loader执行顺序是从后往前)
- 安装autoprefixer, 然后在postcss.config.js里配置
- 处理图片
- 在prod.js里rules节点配置url-loader, 小于5kb图片用base64方式产出. output节点配置filename: [name].[contentHash:8].js
- 安装autoprefixer, 然后在postcss.config.js里配置
- 模块化
高级配置
- 多入口
common.js 里,
定义entry时建立两或多个入口,
prod.js里
output配置filename: [name].[contentHash:8].js
common.js里
有几个入口就new几个HtmlWebpackPlugin, 其中chunk代表每个html文件要引入哪个js文件
prod.js中plugin里new CleanWebpackPlugin
- CSS
线上环境必须抽离, 压缩css
prod.js 安装mini-css-extract-plugin在loader中配置该loader代替dev环境下的style-loader, 在plguin中加抽离css文件的一个配置, new MiniCssExtractPlugin({ filename: ‘css/main.[contentHash:8].css’}), 此时已抽离css, 然后需要压缩
在与plugin平级的optimization配置minimizer使用TerserJSPlugin, OptimizeCSSAssetsPlugin, 然后就通过link外链引入, 提升性能
- 抽离公共代码
三方模块和不会变得公共部分抽离
在与plugin平级的optimization配置splitChunks
- 懒加载
import(‘路径’).then(res => {}})
import函数返回一个promise,then加载资源
- 处理JSX
babel配置
- 处理Vue
common.js里module节点下rules里配置vue-loader
module chunk bundle的区别
module - 各个源码文件, webpack中一切皆模块, 一切皆源码
chunk - 多模块合并成的, 如 entry import() splitChunk
bundle - 最终输出的文件
webpack性能优化
1. 打包构建优化
-
优化babel-loader
编译ES6语法, 发现没有改的启用缓存, 不用重复编译. 一般只在src下管
-
happyPack
JS是单线程, 开启多进程打包, 提高构建速度
放common或prod.js里require happypack
-
ParalleIUglifyPlugin多进程压缩JS
webpack内置的Uglify工具是单线程压缩JS
和happypack同理.
ParalleIUglifyPlugin多进程压缩JS一般放在prod环境下, 因为开发环境没必要压缩js
-
关于开启多进程
项目大, 打包慢, 开启多进程能提高速度
项目小, 打包很快, 开启多进程反而会降低速度 (进程开销) -
自动刷新
一般用不到
, 因为dev-server默认开启了
-
热更新(自动刷新升级版)
自动刷新: 整个网页全部刷新, 速度较慢, 状态会丢失, 比如在输入框输入东西还没提交, 或者路由嵌套多, 一刷新回到首页了. 这时可以选择热更新
热更新
: 新代码生效, 网页不刷新, 状态, 路由等不丢失 在dev环境下配置 -
DllPlguin动态链接库插件
前端框架如 vue React, 体积大, 构建慢, 较稳定, 不常升级版本
同一个版本只构建一次即可, 不用每次都重新构建
webpack已内置Dllplgin支持
DllPlugin - 打包出 dll 文件 , 最终产出dist下的react.dll.js和react.manifest.json(一个内容一个索引)
DllReferencePlugin - 使用 dll 文件(配置地址) -
可用于生产环境的
优化babel-loader- 缓存. 可以只用于开发环境
- 明确范围.
IgnorePlugin
noParse
happyPack
ParalleIUglifyPlugin 一般都用于生产环境 -
不用于生产环境的
热更新肯定不用于生产环境
DllPlugin 只是为了开发环境上的速度优化
2. 性能优化–产出
- prod.js中url-loader的option, 小图片用base64, 这样小图片就不用网络请求, 节省耗时
- prod.js的output下filename: bundle加hash
- 懒加载
- 提取公共代码. 不用重复打包
- IgnorePlugin 可以减少代码, 比如多语言, 时间的库等
- 使用CDN
方法:
- prod.js中output节点的publicPath: ‘http://cdn.xxx.’ // 修改所有静态文件 url 的前缀.
- 把dist目录下的js和css文件上传到cdn服务器
- 图片地址也可以使用cdn, url-loader下的publicPath: ‘http://cdn.xxx’
- 使用production
为什么使用production?
- 自动开启代码压缩
- Vue React等会自动删掉调试代码 (如开发环境的warning)
- 启动 Tree-Shaking. 但是ES6 Module才能让tree-shaking生效, commonjs不行
补充
ES6 Module和Commonjs的区别:
- 两者都是模块化解决方案, 前端常用ES6 Module, nodejs常用Commonjs, 但是前端也可以通过webpack配置实现Commonjs.
- ES6 Module是静态引用, 编译时引用 import不能写在if判断里
Commonjs是动态引用, 执行时引用 require可以在if判断里写
只有静态引用, 才能实现Tree-shaking
- Scope Hosting
代码体积减小 , 多个函数合并
创建函数作用域更小
代码可读性更好
如何开启: