随着vue cli
升级到 4 (内置webpack 4
),我们需要手动做的优化就越来越少了。
通过vue-cli 4.x
,也就是@vue/cli
成功构建一个项目的时候,它不仅自动安装好了必要的库和插件,而且做完了针对大部分应用的 webpack 优化配置。
我们可以用 inspect 命令 审查解析好的配置文件 (用了什么 loaders 和 plugins 会比较直观),也可以看@vue/cli-service
这个包,即/node_modules/@vue/cli-service/lib/config/
目录下的文件(逻辑条理更清晰,多看源码也有好处),便可大致清楚它默认帮我们做了什么配置。
审查项目的 webpack 配置
在 shell 执行vue inspect > defaultConfig.js
,就可以把我们现有的webpack配置解析成一个json对象并输出到目标js文件里。
其中用 webpack-chain 方式配置的模块规则,
.rule('vue')
.test(/\.vue$/)
.use('cache-loader')
.loader('cache-loader')
.end()
.use('vue-loader')
.loader('vue-loader')
会被转化成如下的 module.rules 配置。相对而言更容易理解。
module: {
rules: [ /* config.module.rule('vue') */
{
test: /\.vue$/,
use: ['cache-loader','vue-loader']
},
]
}
vue-cli4 的默认 webpack 配置
经过对@vue/cli-service
源码的分析,将 vue-cli4 默认打包配置梳理如下(非面面俱到):
1. config/app.js
在 output 选项配置打包输出的 bundle 文件名为
[name].[contenthash:8].js
的格式,并定义它们的输出目录:打包输出目录/静态资源目录/js
,如dist/static/js
非测试环境下,通过
optimization.splitChunks
自定义代码分割逻辑,先把初始依赖的node_modules
包提取到chunk-vendors.js
文件,再把被不同入口的公共模块提取到chunk-common
文件。配置 wepack 内置的
NamedChunksPlugin
插件,使 chunk id 保持稳定,如此异步 chunks 也能有始终如一的哈希值。通过
@vue/preload-webpack-plugin
插件,将在 index.html 引入的 js、css 的标签上,加上rel='preload'
用
CorsPlugin
给 html 配置 crossorigin 属性(在vue.config.js
自行配置了crossorigin
的值才会生效)用
copy-webpack-plugin
插件把 public 目录的文件复制到定义的outputDir
(打包目录,默认是dist
)下
2. config/base.js
通过 module 模块给不同文件类型配置不同预处理器。
.vue
(单文件组件):vue-loader (为每个语言块(如、
)生成一个模块导入,并将遇到的资源URL都转为 webpack 模块请求。具体 ➡️ vue-cli4 之 vue-loader 工作流程)、cache-loader(一些性能开销较大的 loader (如vue-loader)可以链式添加 cache-loader,等 vue-loader 处理完再由它开启基于文件系统的模板编译缓存,以便于将结果缓存在磁盘中以减少编译时间)
images
(图片类型,png|jpeg等)、media
(媒体类型,mp4|mp3|wav等)、fonts
(字体类型,eot|ttf等):用 url-loader 导出为 内联 base64 URI,超过 limit 值用 file-loader 处理,发送到打包目录下的静态资源相应文件夹并返回访问 URL(具体 ➡️ file-loader 配置详解以及资源相对路径处理)
svg
(svg格式,通常是图标):file-loader
定义它们构建后的文件名格式为[name].[hash:8].[ext]
,以及它们的输出目录:dist/静态资源目录/[js|img|media|fonts]
,如dist/static/img
。通过
resolve
选项修改模块解析配置,*.jsx
、*.vue
等文件引入时不用再加后缀;定义@
为src
目录绝对路径的别名;配置解析模块时搜索的目录为node_modules
;不解析vue|vue-router|vuex|vuex-router-sync
模块用 terser-webpack-plugin (内置uglify-js,可以自定义用
uglify-js
覆盖默认的 minify 函数来进行压缩) 插件对JS进行了压缩和 treeshaking,我们基本可以不用考虑代码混淆的事,也不必额外安装和配置 uglifyjs-webpack-plugin 了。
如果要在生产环境删除console.log的话,我偷懒就直接在terser的配置文件(config/terserOptions.js)的compress
对象里加上了drop_console: process.env.NODE_ENV === 'production' ? true : false,
3. config/css.js
对构建输出的 css 的文件名使用
[name].[contenthash:8].js
的格式,同时设置它们的输出目录:dist/静态资源目录/css
,如dist/static/css
。按引入方式和是否开启 modules,对各种 css 语言配置了预处理规则,并应用相应的 loader 去做处理。包括 postcss、css、scss、sass、less、stylus 。
标签中注入多个
非生产环境会先经过 postcss-loader、css-loader(会把 css 中的资源URL转为模块请求),最后应用 vue-style-loader 往