刚使用webpack4来构建Vue2的项目环境就遇到了一些内置插件失效和环境依赖库的更新的坑。

webpack4中环境及依赖库的部分版本要求

loader 最低版本要求 功能说明
vue-loader 15.0.0 解析、编译vue单文件组件中的样式,需要配合vue-loader/lib/plugin插件使用,并内置css编译器
vue-style-loader 4.1.0 解析、编译vue单文件组件中的样式
babel-loader 7.1.3 对最新的ES语法进行转换
file-loader 1.1.10 批量修改文件路径、或者指定编译后文件储存路径
eslint-loader 2.0.0 代码检查
可能会有遗漏!!

webpack 4.X 相对与webpack 3.X的重大变更,不再支持部分插件,如js压缩,chunk分离及文件分离的一些插件。

失效的插件 类型 功能说明
webpack.optimize.CommonsChunkPlugin 内置插件
分离chunk。将多次出现的代码统一打包到一个文件中,Vue工程中用来打包vendor及manifest
webpack.optimize.UglifyJsPlugin 内置插件 压缩JS
extract-text-webpack-plugin loader
分离文件。将部分代码或文件提出到单独文件中。Vue工程中常用来分离css并合并到一个指定文件中
使用 mini-css-extract-plugin 代替

webpack4.X之前的版本常用extract-text-webpack-plugin
<https://www.npmjs.com/package/extract-text-webpack-plugin>
插件来分离合并css到指定文件中,在webpack4中也提供了@next版本,但这里我并不使用,选择推荐的新的替代插件
mini-css-extract-plugin <https://www.npmjs.com/package/mini-css-extract-plugin>
来替代旧插件。
新插件与旧插件都需要在webpack的loader部分和plugin部分都进行配置,不同的是新插件提供了单独的loader,配置如下:
const MiniCssExtractPlugin=require("mini-css-extract-plugin"); module.exports={
... module:{ rules:[ { test: /\.css$/, use:[ MiniCssExtractPlugin.loader,
"css-loader" ] } ] }, plugins:[ new MiniCssExtractPlugin({ filename:
'css/[name].[contenthash].css' }) ] }
拆分 js 代码


这是webpack配置中很重要的一个环节,如果不对js代码进行拆分,公共库与入口代码将合并在一个js文件中,影响到浏览器缓存的合理性,页面资源的加载速度。所以,对js进行合理拆分,可以有效减小我们每次更新代码影响到的文件范围,保证了长缓存。

使用webpack3时,我们一般会提出manifest.js(webpack运行时,即webpack解析其他bundle代码时)、vendor.js
(node_modules内的库)、main.js(项目业务代码)。在webpack3中使用
webpack.optimize.CommonsChunkPlugin插件进行提取。在webpack4中被完全废除了,官方推荐使用optimization
<https://webpack.js.org/plugins/split-chunks-plugin/#defaults>
配置项进行配置,当然,css拆分也可以使用optimization来配置项。


在optimization中有一个非常重要的一个插件spliltChunkPlugin,刚使用webpack4,我在splitChunk的使用还在摸索阶段,我也查看了很多别人的配置,有很多的疑问,自己记录一些用法,如果大家有更好的建议,欢迎评论区说出来。

先来过一遍参数
optimization:{ splitChunks:{ chunks:async,//表示显示块的范围,三个可选值:
//initial(初始块)、async(按需加载块)、all(默认,全部块) minSize:0,//表示在分离前的最小模块大小,默认为0,最小为30000
minChunks:1,//表示分离前被引用次数,默认为1 maxAsyncRequests:1,//最大按需加载次数,最大异步加载次数,默认1
maxInitialRequests:1,//最大初始化加载次数,一个入口文件可以并行加载的最大文件数量,默认1 automaticNameDelimiter:
'~',//打包分隔符,若改为'-'则分离后的js默认命名规则为[来源]-[入口key].js name: function(){},
//打包后的名称,此选项可接受函数,默认true,,由chunk和hash值自动生成,
//当存在匹配的缓存组时,命名使用缓存组中的name值,若不在则为[来源]~[入口key].js cacheGroups:{//设置缓存chunks
priority:0,//缓存组优先级
//当需要优先匹配缓存组的规则时,priority需要设置为正数,当需要优先匹配默认设置时,缓存组需设置为负数,0为两者分割线 default:{
//设置缓存组默认配置,可通过default:false禁用默认缓存组, //然后就可以自定义缓存组,将初始化加载时被重复引用的模块进行拆分
minChunks:2,//引用两次 priority:-20,//缓存组优先级为-20 reuseExistingChunk:true,
//表示可以使用已经存在的块,即如果满足条件的块已经存在就是用己有的的,不再创建一个新的块 }, [key]:{//自定义缓存组,可以根据需求,自由创建
chunks:'initial', test: /vue/,
//正则规则验证,如符合就提取chunk放入当前缓存组,值可以是function、boolean、string、RegExp,默认为空 enforce:
true//优先处理 } } } }

splitChunks是webpack主模块的一个细分模块,功能上,splitChunksPlugins只能用于如何抽离公用代码,制定抽离公用代码与入口文件的规则,除了这功能外,splitChunksPlugins
再无其他功能

下面是一个抽离公用代码与业务代码的一个可复用配置:
optimization:{ splitChunks:{ //对entry进行拆分 chunks: 'all', minSize: 30000,
cacheGroups:{//比如你要单独把vue等官方库文件打包到一起,可以使用这个缓存组,如果要具体到库文件,可以单独给库文件写一个缓存组
vendor:{ test:/node_modules/, priority: 10, name: "vendor", enforce: true },
//这里定义分离前被引用过两次的文件,将其一同打包到common.js,最小为30kb common:{ name: "common", minChunks:
2, minSize: 20000 } } } }
关于更多配置方法,一步步的了解webpack4的splitChunksPlugin插件
<https://juejin.im/post/5af1677c6fb9a07ab508dabb?utm_medium=hao.caibaojian.com&utm_source=hao.caibaojian.com>
里有详细介绍。


另外还有一个可配套使用的runtimeChunk插件,webpack会添加一个只包含运行时的额外代码块到每一个入口。(看场景使用,它会导致每个入口都加载多一份代码)

压缩js


webpack4的uglifyJsPlugin实际上在不设置任何环境变量的情况下,始终会有压缩代码的行为,导致编译耗时,解决方法就是配置不同的环境变量在开发环境的不要使用uglifyJsPlugin插件,webpack4于是提供了mode这个新增的选项,且默认值为production,在package.json文件中设置–mode=production模式则自动开启。

参阅资料

* webpack4新变化 <https://blog.csdn.net/qq_20334295/article/details/79401231>
* webpack4新特性 <https://segmentfault.com/a/1190000013970017>
* webpack4升级完全指南 <https://www.colabug.com/2646738.html>
* webpack4升级完全指北 <https://segmentfault.com/a/1190000013420383>
* webpack细节 <https://segmentfault.com/a/1190000014685887>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信