webpack 于2018年2月25日正式发布 v4.0.0 版本,代号legato,这将会让 webpack 的配置更加简单,构建速度更快
[TOC]
Nodejs版本
Node.js >= 8.9.4
当使用 webpack4 时,必须保证 Node.js 版本 >= 8.9.4,因为 webpack4 使用了大量的ES6语法,这些语法在 nodejs新版 v8 中得到了原生支持
安装
npm i webpack webpack-cli -D |
webpack4 中 cli 工具分离成了 webpack 核心库 与 webpack-cli 命令行工具两个模块,需要使用 CLI,必安装 webpack-cli 至项目中
零配置 0CJS
webpack4 设置了默认值,以便无配置启动项目
entry默认值是./src/output.path默认值是./distmode默认值是production
模式
mode: development / production / none
开发模式 development
- 浏览器调试工具
- 注释、开发阶段的详细错误日志和提示
- 快速和优化的增量构建机制
- 开启
output.pathinfo在bundle中显示模块信息 - 开启
NamedModulesPlugin - 开启
NoEmitOnErrorsPlugin
生产模式 production
- 启用所有优化代码的功能
- 更小的bundle大小
- 去除只在开发阶段运行的代码
- 关闭内存缓存
Scope hoisting和Tree-shaking- 开启
NoEmitOnErrorsPlugin - 开启
ModuleConcatenationPlugin - 开启
optimization.minimize
none 会禁用所有的默认设置,可以使用 optimization.* 的方式去设定更详细的配置(搭建你的自定义模式)
插件优化
新增 optimization.splitChunks 和 optimization.runtimeChunk 来替代 CommonsChunkPlugin插件,
新增 optimization.noEmitOnErrors 来替代 NoEmitOnErrorsPlugin 插件
新增 optimization.namedModules 来替代 NamedModulesPlugin 插件
内置 optimization.minimize 来压缩代码
loader
默认已支持加载 json 模块,不再需要 json-loader
允许通过ESM语法导入JSON,JSON模块中未使用的部分会被消除
详细升级日志请查看 webpack4.0 升级日志中文版
Webpack配置 基本结构
module.exports = { |
使用 HtmlWebpackPlugin 插件,需要npm安装相应模块
// 安装 |
使用 devServer 同样需要安装相关模块
// 安装 |
常用 Loader 配置
babel-loader
将ES6的代码使用babel转码为浏览器兼容的ES5
{ |
babel 的配置在项目根目录下 .babelrc 文件中,如果没有则新建,根据不同的项目要求配置
npm i babel-core babel-loader babel-preset-env babel-preset-stage-2 --save-dev |
url-loader
将 图片 转成 data:base64,以减少页面中的图片请求
{ |
less-loader
将less文件编译为css
{ |
这里先将 less-loader 转 css, 再经过 css-loader 将css模块化并解析其中的 @import 及 url(),再通过 style-loader 将css嵌入html
常用插件
配置全局变量
webpack.DefinePlugin
用于定义在编译过程中使用的全局变量,常用来定义 process.env 用来区分开发环境和生产环境
const isProduction = process.env.NODE_ENV === 'production' |
模块热替换
webpack.HotModuleReplacementPlugin 内置
模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面
- 保留在完全重新加载页面时丢失的应用程序状态。
- 只更新变更内容,以节省宝贵的开发时间。
- 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。
保证 chunkhash 的稳定
webpack.HashedModuleIdsPlugin 内置
使用 hash 做为模块ID, 避免缓存那些没有变化的模块内容,从而实现更优的缓存策略
提取css为文件
extract-text-webpack-plugin NPM
将所有入口 chunk 中引用的 *.css,提取合并为独立的css,在index.html 中使用 link:src 来引用css文件,一般用于生产模式,提取公共的css
拷贝静态文件
copy-webpack-plugin NPM
应用:将模板 index.html 中引用的静态资源,在构建时复制到 dist 指定目录下
CSS优化
optimize-css-assets-webpack-plugin NPM
压缩css, 同时去除重复的样式,减少CSS打包后的体积
vue-cli 项目开发环境的 plugins 配置
plugins: [ |
vue-cli 项目生产环境的 plugins 配置
plugins: [ |
配置服务代理
在开发过程中和后台连调时,一般需要解决跨域问题,webpack 提供了 proxy 配置用于,代理 api 请求,屏蔽浏览器跨域限制
proxy: { |
当用户访问 /api/getUser 时,代理到 http://192.168.1.12:5000/api/getUser 去请求数据
Vue-cli 升级 Webpack4.x
升级模块
建议在 webpack 构建流程中使用到的 loaders 及 plugins 都升级到最新版本
安装
如果 pakage.json 中有相应的模块配置,可删除之后重新安装
npm i webpack webpack-cli webpack-dev-server --save-dev |
还有以下模块
"copy-webpack-plugin": "^4.0.1", |
修改开发环境
build/webpack.dev.conf.js 中添加 mode 配置
注释掉 webpack.NamedModulesPlugin 及 webpack.NoEmitOnErrorsPlugin 插件,因为 webpack4 开发模式已经内置
module.exports = { |
修改生产环境
build/webpack.production.conf.js 中添加 mode 与 optimization 配置
同时注释掉 webpack.optimize.CommonsChunkPlugin 、 uglifyjs-webpack-plugin、webpack.optimize.ModuleConcatenationPlugin 相关配置及引用
const webpackConfig = merge(baseWebpackConfig, { |
经过上面三步,vue-cli 项目升级 webpack4.x 就完成了
需要注意的是当前项目一定要是较新的 webpack 模板生成的项目,是不是新模板,可以查看 package.json 中 scripts.dev 是否是使用 webpack-dev-server 启动的,如果是,则为新的模板
性能优化
使用happypack
HappyPack就能让Webpack把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程
npm i happypack@5.0.0-beta.3 --save-dev |
配置noparse
忽略对已知文件的解析: 一个模块中没有其它新的依赖 就可以配置这项,webpack 将不再扫描这个文件中的依赖
resolve: { |
webpack检查到entry.js文件对moment的请求- 请求被
alias重定向,转而请求moment/min/moment-with-locales.min.js noParse规则中的/moment-with-locales/一条生效,所以webpack就直接把依赖打包进了bundle.js
生产环境不产生source-map
eval: 生成代码 每个模块都被eval执行,并且存在@sourceURL |
当我们不需要调试时,可以关掉 sourcemap 或降低 sourcemap 的级别来加快打包的速度
使用CDN资源或静态资源
使用CDN
在 webpack.config.js 中配置模块变量为外部依赖externals: {
moment: true
}
在 index.html 中添加资源引用
<script src="//apps.bdimg.com/libs/moment/2.8.3/moment-with-locales.min.js"></script> |
使用静态资源
有时候,由于网络限制,不允许使用CDN资源,又不想经过Webpack打包,则可以将资源直接引入 index.html ,在 webpack build 配合 copy-webpack-plugin 插件,将资源复制到 dist 目录下,例 vue-cli 生成的项目根目录下的 static 目录就是用来放这类静态资源的
为babel-loader设置缓存
cacheDirectory: 指定的目录将用来缓存 loader 的执行结果。之后的 webpack 构建,将会尝试读取缓存,来避免在每次执行时,可能产生的、高性能消耗的 Babel 重新编译过程
{ |
官方文档中表示设置 cacheDirectory 可将 babel-loader 提速至少两倍
参考阅读
深入浅出Webpack
vue cli 平稳升级webapck4
Webpack4 那点儿东西
30分钟快速了解webpack