1. 在开始本章节前先学习一下必备前置知识
- babel-loader:每一个浏览器对js语法兼容性不同,为了使浏览器对js的解析尽量保持一致,所以就出现了Babel。Babel把
ECMAScript 2015+
代码进行降级,用级别低兼容性好的语法重新实现一遍高级语法。 - @babel/polyfill:Babel默认只转换新的Javascript语法,而不转换新的API,它是通过向全局对象和内置对象的
prototype
上添加方法来实现的。比如运行环境中不支持Array.prototype.find
方法,引入polyfill
, 我们就可以使用ES6
方法来编写了。注:Babel 7.4之后不再推荐使用@babel/polyfill(全局污染问题) - @babel/preset-env: 默认只支持语法转化,需要开启
useBuiltIns
配置才能转化API和实例方法 - babel-runtime: Babel为了解决全局空间污染的问题,提供了单独的包
babel-runtime
用以提供编译模块的工具函数。简单说babel-runtime
更像是一种按需加载的实现。比如你哪里需要使用Promise
,只要在这个文件头部import Promise from 'babel-runtime/core-js/promise'
就行了 - babel-plugin-transform-runtime:为了解决
- 多个文件重复引用 相同helpers(帮助函数)=>提取运行时
- 新API方法全局污染 -> 局部引入
2. 安装依赖
pnpm add @babel/polyfill @babel/preset-env babel-loader core-js@2 core-js@3 babel-runtime @babel/plugin-transform-runtime @babel/runtime-corejs3 -D
3. webpack中使用@babel/polyfill
- useBuiltIns: false
- 表示不对
polyfills
处理,此时不对 polyfill 做操作。如果引入 @babel/polyfill,则无视配置的浏览器兼容,引入所有的 polyfill
- 表示不对
{
test: /\.js?$/, // 匹配后缀为js的文件
exclude: /node_modules/, // 忽略需要操作的文件
use: {
loader: 'babel-loader',
options: {
targets: {
"browsers": ["ie >= 8", "chrome >= 62"], // 表示我们需要支持哪些平台和哪些版本
},
presets: [["@babel/preset-env", { useBuiltIns: false }]]
}
}
}
// js编译后
import '@babel/polyfill';
let sum = (a, b) => a + b;
let promise = Promise.resolve();
console.log([1, 2, 3].find(item => item === 2));
- useBuiltIns: entry
- 根据配置的浏览器兼容,引入浏览器需要兼容处理的 polyfill,不能实现按需加载。
corejs
默认是2,如果配置corejs: 3
, 则import '@babel/polyfill'
需要改成import 'core-js/stable';import 'regenerator-runtime/runtime';
{
test: /\.js?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [["@babel/preset-env", { useBuiltIns: 'entry', corejs: { version: 3 } }]]
}
}
}
// core-js@2
import '@babel/polyfill';
let sum = (a, b) => a + b;
let promise = Promise.resolve();
console.log([1, 2, 3].find(item => item === 2));
// core-js@3
import 'core-js/stable';
import 'regenerator-runtime/runtime';
let sum = (a, b) => a + b;
let promise = Promise.resolve();
console.log([1, 2, 3].find(item => item === 2));
- useBuiltIns: usage
- 会根据配置的浏览器兼容,以及你代码中用到的 API 来进行 polyfill,实现了按需添加
{
test: /\.js?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [["@babel/preset-env", { useBuiltIns: 'usage', corejs: { version: 3 } }]]
}
}
}
4. webpack中使用babel-plugin-transform-runtime
- 启用插件
babel-plugin-transform-runtime
后,Babel就会使用babel-runtime
下的工具函数 babel-plugin-transform-runtime
插件能够将这些工具函数的代码转换成require
语句,指向为对babel-runtime
的引用babel-plugin-transform-runtime
就是可以在我们使用新 API 时自动import babel-runtime
里面的polyfill
- 当我们使用
async/await
时,自动引入babel-runtime/regenerator
- 当我们使用 ES6 的静态事件或内置对象时,自动引入
babel-runtime/core-js
- 移除内联
babel helpers
并替换使用babel-runtime/helpers
来替换
- 当我们使用
{
test: /\.js?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
sourceType: "unambiguous", // Babel 会根据文件上下文推断使用esm语法还是common语法
presets: [["@babel/preset-env", { useBuiltIns: 'usage', corejs: { version: 3 } }]],
plugins: [
[
"@babel/plugin-transform-runtime",
{
corejs: 3, // 当我们使用 ES6 的静态事件或内置对象时自动引入 babel-runtime/core-js
helpers: true,// 避免内联的 helper 代码在多个文件重复出现,使用babel-runtime/helpers 来替换
regenerator: true // 转换成使用regenerator runtime来避免污染全局域
}
],
]
}
}
}
// 转换
// corejs: 3
//var _Promise = __webpack_require__("./node_modules/@babel/runtime-corejs3/core-js-stable/promise.js");
const p = new Promise(() => { });
// regenerator: true
//var _regeneratorRuntime = __webpack_require__(/*! @babel/runtime-corejs3/regenerator */ "./node_modules/@babel/runtime-corejs3/regenerator/index.js");
function* gen() {}
5.最佳实践
- 项目开发
plugin-transform-runtime
只使用其移除内联复用的辅助函数的特性,减小打包体积
{
test: /\.js?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [["@babel/preset-env", { useBuiltIns: 'usage', corejs: { version: 3 } }]]
plugins: [["@babel/plugin-transform-runtime", { "corejs": false }]]
}
}
}
- 类库开发
- 类库开发尽量不使用污染全局环境的
polyfill
,因此@babel/preset-env
只发挥语法转换的功能 - polyfill由
@babel/plugin-transform-runtime
来处理,推荐使用core-js@3
- 类库开发尽量不使用污染全局环境的
{
presets: [["@babel/preset-env"]],
plugins: [["@babel/plugin-transform-runtime", corejs: { version: 3 } }]]
}
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END