前面的话
本文将详细介绍从 webpack3 到 webpack4 的升级过程
概述
相比于 webpack3,webpack4 可以零配置运行, 打包速度比之前提高了 90%, 可以直接到 ES6 的代码进行无用代码剔除, 新增的 optimization 使用简单
[0 配置]
webpack4 设置了默认值, 以便无配置启动项目
entry 默认值是 ./src/
output.path 默认值是 ./dist
mode 默认值是 production
[模块类型]
webpack4 提供了 5 种模块类型
json: 可通过 require 和 import 导入的 JSON 格式的数据 (默认为 .json 的文件)
webassembly: WebAssembly 模块,(目前是 .wasm 文件的默认类型)
javascript/auto: (webpack 3 中的默认类型) 支持所有的 JS 模块系统: CommonJS,AMD.
javascript/esm: EcmaScript 模块 (默认 .mjs 文件).
javascript/dynamic: 仅支持 CommonJS & AMD.
webpack 4 不仅支持本地处理 JSON, 还支持对 JSON 的 Tree Shaking. 当使用 ESM 语法 import json 时, webpack 会消除掉 JSON Module 中未使用的导出. 此外, 如果要用 loader 转换 json 为 js, 需要设置 type 为 javascript/auto
模式 mode
相比于 webpack3,webpack4 新增了一个 mode 配置选择, 用来表示配置模式的选择情况
- module.exports = {
- mode: 'production'
- }
包括生产环境 production, 开发环境 devolopment 和自定义 none 这三个选择可选
[开发模式]
浏览器调试工具
注释, 开发阶段的详细错误日志和提示
快速和优化的增量构建机制
开启 output.pathinfo 在 bundle 中显示模块信息
开启 NamedModulesPlugin
开启 NoEmitOnErrorsPlugin
[生产模式]
启用所有优化代码的功能
更小的 bundle 大小
去除只在开发阶段运行的代码
关闭内存缓存
Scope hoisting 和 Tree-shaking
开启 NoEmitOnErrorsPlugin
开启 ModuleConcatenationPlugin
开启 optimization.minimize
[none]
禁用所有的默认设置
optimization
从 webpack4 开始官方移除了 commonchunk 插件, 改用了 optimization 属性进行更加灵活的配置, 下面来介绍 optimization 下的一些常用配置项
[minimize]
利用 unglifyjsWebpackPlugin 插件来压缩模块, 生产环境下该值默认为 true
- optimization: {
- minimize: false
- }
- [minimier]
可以使用其他插件来执行压缩功能
- const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
- module.exports = {
- //...
- optimization: {
- minimizer: [
- new UglifyJsPlugin({ /* your config */ })
- ]
- }
- };
- [splitChunks]
webpack4 默认使用 splitChunksPlugin 插件来实现代码分割功能, 来替代 webpack3 中的 commonChunksPlugin 插件
- module.exports = {
- //...
- optimization: {
- splitChunks: {
- chunks: 'async',
- minSize: 30000,
- minChunks: 1,
- maxAsyncRequests: 5,
- maxInitialRequests: 3,
- automaticNameDelimiter: '~',
- name: true,
- cacheGroups: {
- vendors: {
- test: /[\\/]node_modules[\\/]/,
- priority: -10
- },
- default: {
- minChunks: 2,
- priority: -20,
- reuseExistingChunk: true
- }
- }
- }
- }
- [runtimeChunk]
通过设置 runtimeChunk: true 来为每一个入口默认添加一个只包含 runtime 的 chunk
通过提供字符串值, 可以使用插件的预设模式
signal: 创建一个被所有生成的块共享的 runtime 文件
multiple: 为共同的块创建多个 runtime 文件
缺省值为 false, 表示每个入口块默认内嵌 runtime 代码
- runtimeChunk {
- name: "runtime"
- }
- [noEmitOnErrors]
只要在编译时出现错误, 就使用 noEmitOnErrors 属性来跳过 emit 阶段, 用来替代
NoEmitOnErrorsPlugin
插件
[nameModules]
使用可读的模块标识, 方便更好的调试. webpack 在开发模式下默认开启, 生产模式下默认关闭, 用来替代 NamedModulesPlugin 插件
- module.exports = {
- //...
- optimization: {
- namedModules: true
- }
- };
升级
下面就基于 vue-cli 的项目对 webpack 配置进行升级
1, 升级 nodejs
使用 webpack4 时, 必须保证 Node.js 版本 >= 8.9.4, 因为 webpack4 使用了大量的 ES6 语法, 这些语法在 nodejs 新版 v8 中得到了原生支持
2, 升级 webpack 主要部件, 包括 webpack,webpack-bundle-analyzer,webpack-dev-server,webpack-merge
升级的操作很简单, 先删除, 再安装即可. 但要注意的是 webpack4 版本中 cli 工具分离成了 webpack 核心库 与 webpack-cli 命令行工具两个模块, 需要使用 CLI, 必安装 webpack-cli 至项目中
cnpm uninstall -D webpack webpack-bundle-analyzer webpack-dev-server webpack-merge
cnpm install -D webpack webpack-cli webpack-bundle-analyzer webpack-dev-server webpack-merge
3, 升级 webpack 相关插件, 包括 copy-webpack-plugin,css-loader,eslint-loader,file-loader,html-webpack-plugin,url-loader,friendly-errors-webpack-plugin,optimize-css-assets-webpack-plugin,uglifyjs-webpack-plugin
cnpm uninstall -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin
cnpm install -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin
4, 升级 vue-loader
由于 vue-loader 升级到版本 15 后, 配置有较多的变化, 稳妥起见, 可以只将 vue-loader 升级到 14.4.2
cnpm uninstall -D vue-loader
cnpm uninstall -D vue-loader@14.4.2
5, 替换 webpack 相关插件, extract-text-webpack-plugin 替换为 mini-css-extract-plugin
- cnpm uninstall -D extract-text-webpack-plugin
- cnpm install -D mini-css-extract-plugin
配置
下面对配置文件的修改进行详细说明:
1,webpack.base.conf.js 文件
增加 node:process.env.NODE_ENV 即可
- module.exports = {
- + mode: process.env.NODE_ENV,
- ...
2,webpack.prop.conf.js 文件
该文件的配置项较为复杂
(1) 将 ExtractTextPlugin 替换为 MiniCssExtraPlugin
- + const MiniCssExtractPlugin = require("mini-css-extract-plugin")
- - const ExtractTextPlugin = require('extract-text-webpack-plugin')
- ...
- - new ExtractTextPlugin({
- + new MiniCssExtractPlugin({
- filename: utils.assetsPath('css/[name].[contenthash].css'),
- allChunks: true,
- }),
- ...
(2) 删除 UglifyJsPlugin 配置项
- - const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
- ...
- - new UglifyJsPlugin({
- - uglifyOptions: {
- - compress: {
- - warnings: false
- - }
- - },
- - sourceMap: config.build.productionSourceMap,
- - parallel: true
- - })
(3) 删除 CommonsChunkPlugin 配置项
- - new webpack.optimize.CommonsChunkPlugin({
- - name: 'vendor',
- - minChunks (module) {
- - return (
- - module.resource &&
- - /\.js$/.test(module.resource) &&
- - module.resource.indexOf(
- - path.join(__dirname, '../node_modules')
- - ) === 0
- - )
- - }
- - }),
- - new webpack.optimize.CommonsChunkPlugin({
- - name: 'manifest',
- - minChunks: Infinity
- - }),
- - new webpack.optimize.CommonsChunkPlugin({
- - name: 'app',
- - async: 'vendor-async',
- - children: true,
- - minChunks: 3
- - }),
- ...
(4) 添加 optimization 配置项
- + optimization: {
- + splitChunks: {
- + chunks: 'async',
- + minSize: 30000,
- + minChunks: 1,
- + maxAsyncRequests: 5,
- + maxInitialRequests: 3,
- + automaticNameDelimiter: '~',
- + name: true,
- + cacheGroups: {
- + vendors: {
- + test: /[\\/]node_modules[\\/]/,
- + priority: -10
- + },
- + default: {
- + minChunks: 2,
- + priority: -20,
- + reuseExistingChunk: true
- + }
- + }
- + },
- + runtimeChunk: { name: 'runtime' }
- + },
详细配置移步前端小站源码 https://github.com/littlematch0123/blog-client
来源: https://www.cnblogs.com/xiaohuochai/p/9196906.html