(点击上方公众号,可快速关注)
来源:dwqs
https://github.com/dwqs/blog/issues/60
在 webpack 3 发布 之后, webpack 团队向社区承诺,之后 webpack 主版本的迭代会有一个时间比较长且稳定的开发周期。而在2017年8月份的时候,webpack 团队从 master 分支切出了 next 分支用于 webpack 4 的开发,经历 5 个月的开发周期之后,webpack 4.0-beta 在 2018年1月 已经 Released 了,不仅兑现了之前的承诺,还带来了诸多新特性,在用户使用的体验上也作了诸多改进。
安装
如果需要使用 webpack 4,则需要从 next 分支上安装:
// yarn
yarn add webpack@next webpack-cli --dev
// npm
npm install webpack@next webpack-cli --save-dev
不完全迁移指北
环境
不再支持 Node.js 4。
根据 package.json 配置, Node.js 的最低支持版本为 6.11.5
模块类型
webpack 4之前,js 是 webpack 中的唯一模块类型,因而不能有效地打包其它类型的文件。而 webpack 4 则提供了 5 种模块类型:
javascript/auto: (webpack 3中的默认类型)支持所有的JS模块系统:CommonJS、AMD、ESM
javascript/esm: EcmaScript 模块,在其他的模块系统中不可用(默认 .mjs 文件)
javascript/dynamic: 仅支持 CommonJS & AMD,EcmaScript 模块不可用
json: 可通过 require 和 import 导入的 JSON 格式的数据(默认为 .json 的文件)
webassembly/experimental: WebAssembly 模块(处于试验阶段,默认为 .wasm 的文件)
此外,webpack 4 中会默认解析 .wasm, .mjs, .js 和 .json 为后缀的文件。
在对应文件的 loader 配置,需要增加 type 字段来指定模块类型:
module: {
rules: [{
test: /\.special\.json$/,
type: "javascript/auto",
use: "special-loader"
}]
}
javascript/auto / javascript/esm 都可以处理 ESM, 但后者会更加严格:
导入的名称必须存在于导入的模块中
动态的模块(非 ESM,如 CommonJS)只能通过默认 import 导入,其它方式(包括命名空间)的导入都会报错
对于 WebAssembly 模块:
可以导入其它模块(JS 和 WASM)
试图在 WASM 模块中导入不存在的模块将会得到一个警告或者错误
ESM 可以引入 WASM 模块中导出的模块名
仅可在 async chunks(通过 import() 导入的模块)中使用,在 initial chunks 中是无效的(不利于提升 web 应用的性能)
import(): 动态导入
在 webpack 4 中,import() 会返回一个带命名空间(namespace)的对象,这对 ES Module 不会有影响,但对于遵循 commonjs 规范的模块则会加一层包裹:
// webpack 2/3
import("./commonjs").then(exports => {
...
})
// webpack 4
import("./commonjs").then({default: exports}=> {
...
})
mode: 模式配置
mode 是 webpack 4 中新增加的参数选项,其有两个可选值:production 和 development。mode 不可缺省,需要二选一:
production 模式:
默认提供所有可能的优化,如代码压缩/作用域提升等
不支持 watching
process.env.NODE_ENV 的值不需要再定义,默认是 production
/** webpack.production.config.js **/
// webpack 2/3
module.exports = {
plugins: [
new UglifyJsPlugin(/* ... */),
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.NoEmitOnErrorsPlugin()
]
}
// webpack 4
module.exports = {
mode: 'production'
}
development 模式:
主要优化了增量构建速度和开发体验
process.env.NODE_ENV 的值不需要再定义,默认是 development
开发模式下支持注释和提示,并且支持 eval 下的 source maps
/** webpack.development.config.js **/
// webpack 2/3
module.exports = {
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") })
]
}
// webpack 4
module.exports = {
mode: 'development'
}
此外, webpack 4 还提供一种隐藏(none)模式,这种模式下会禁用一切优化
sideEffects 设置
webpack 4 在 package.json 中引入了对 sideEffects: false 的支持。当模块的 package.json 中添加该字段时,表明该模块没有副作用,也就意味着 webpack 可以安全地清除被用于重复导出(re-exports)的代码。
JSON
webpack 4 不仅支持本地处理 JSON,还支持对 JSON 的 Tree Shaking。当使用 ESM 语法 import json 时,webpack 会消除掉JSON Module 中未使用的导出。
此外,如果要用 loader 转换 json 为 js,需要设置 type 为 javascript/auto:
module.rules: [
{
test: /\.special\.json$/,
type: "javascript/auto",
use: "special-loader"
}
]
配置
删除了一些常用内置插件:
NoEmitOnErrorsPlugin -> optimization.noEmitOnErrors (生产模式默认)
ModuleConcatenationPlugin -> optimization.concatenateModules (生产模式默认)
NamedModulesPlugin -> optimization.namedModules (开发模式默认)。
删除了 CommonsChunkPlugin,取而代之的是 optimization.splitChunks 和 optimization.runtimeChunk,这提供了细粒度的缓存策略控制
可以使用 module.rules[].resolve 来配置解析,它会与全局配置合并。
optimization.minimize 用于控制 minimizing 的开关。 生产模式默认为开,开发模式默认为关。
optimization.minimizer 用于配置 minimizers 和选项。
许多支持占位符(placeholders)的配置选项现也支持函数形式
错误的 options.dependencies 配置将报错
sideEffects 可以通过 module.rules 覆盖
output.hashFunction 可以是一个构造函数,用于自定义 hash 函数。处于性能考虑,也可以提供非加密哈希函数
output.globalObject 可以用于配置运行时的全局对象引用
默认配置
webpack 默认会按照 .wasm, .mjs, .js 和 .json 的扩展名顺序查找模块。
output.pathinfo 在开发模式下默认是打开的
生产环境下,默认关闭内存缓存
entry 的默认值是 ./src,output.path 的默认值是 ./dist
在选择模式选项时,默认值是 production
优化
uglifyjs-webpack-plugin 发布 v1,支持 ES2015
使用 JSONP 数组来代替 JSONP 函数 –> 异步支持
webpack 自身也可以删除无用代码。webpack 2/3 中是在 Uglify 时删除无用代码,webpack 4 中 webpack 也可以(在某些情况下)删除无用代码,避免 import() 引用无用代码时导致的奔溃
作用域提升后的模块将生成更少的代码
性能
默认情况,UglifyJS 会默认缓存和并行化(完全实现缓存和并行化将在 webpack 5 中实现)
多个性能改进,尤其是在增量构建这方面
改进了 RemoveParentModluesPlugin 的性能
未使用模块不再有非必要的作用域提升
添加 ProfilingPlugin,此插件会(在 Chrome 浏览器中)创建一个包含各插件时间消耗的文件
for of 代替 forEach;Map/Set 代替 Objects;includes 代替 indexOf
同一个任务只会进入队列一次
完整的性能改善和优化列表可以参考 Release 4.0-beta.0
移除的功能
移除了 module.loaders
移除了 loaderContext.options
移除了 Compilation.notCacheable
移除了 NoErrorsPlugin
移除了 Dependency.isEqualResource
移除了 NewWatchingPlugin
移除了 CommonsChunkPlugin
相关资源
webpack 4 beta — try it today!
webpack 4-beta.0
官方迁移草案
webpack 4: mode and optimization
觉得本文对你有帮助?请分享给更多人
关注「前端大全」,提升前端技能