webpack 之 babel 使用
babel 前端开发环境必备工具
环境搭建 & 基本配置
- 环境搭建
- .babelrc 配置 presets 和 pluins
1、环境配置文件 package.json
{
"name": "09-babel-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.7.5",
"@babel/core": "^7.7.5",
"@babel/plugin-transform-runtime": "^7.7.5",
"@babel/preset-env": "^7.7.5"
},
"dependencies": {
"@babel/polyfill": "^7.7.0",
"@babel/runtime": "^7.7.5"
}
}
babel 配置文件 .babelrc
- presets - 可以作为 Babel 插件的组合
- pluins
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
测试 index.js 中的 ES6 代码
const sum = (a, b) => a + b;
执行命令 npx babel src/index.js
,输出 ES5 语法
var sum = function sum(a, b) {
return a + b;
};
2、babel-polyfill
1)polyfill 意为补丁,比如
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (Object, max, min) {};
}
通过这种方式实现 polyfill
2)core-js 和 regenerator
core-js 是 ES6+ 转 ES5 标准版,github 地址:https://github.com/zloirock/core-js,但 core-js 无法满足 ES6 中 generator,如
// ES6 generator 函数(处理异步),被 async/await 代替
function* tell() {
console.log('执行 a 处理');
yield 'a';
console.log('执行 b 处理');
yield 'b';
console.log('执行 c 处理');
yield 'c';
}
let k = tell();
console.log(k.next());
console.log(k.next());
console.log(k.next());
console.log(k.next());
所以还需要 regenerator 的支持,github 地址:https://github.com/facebook/regenerator
3) babel-polyfill 即是 core-js 和 regenerator 的集合
- Babel 7.4 之后弃用 babel-polyfill
- 推荐直接使用 core-js 和 regenerator,但是 babel-polyfill 还是很多人用
babel 只将 ES6+ 语法转 ES5 语法,但不能处理新的 API (新的 API 语法符合 ES5 规范,但浏览器是否兼容,babel 不关心),所以在代码中引入 babel-polyfill
import '@babel/polyfill';
// 新的 API
Promise.resolve(100).then((data) => data);
// 新的 API
[10, 20, 30].includes(20);
以上被解析为
require('@babel/polyfill')
// 新的 API
Promise.resolve(100).then(data => data);
// 新的 API
[10, 20, 30].includes(20)
babel 把 import 引入的解析为 require 的模块化,但 babel 不处理模块化,所以还是需要 webpack 配合,然而 babel-polyfill 文件较大,所以应配置 .babelrc 按需引入
注,import '@babel/polyfill' 就不需要手动引入了
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
]
],
}
3、babel-runtime
babel-polyfill 的问题
// 污染全局环境
window.Promise = function () {};
Array.prototype.includes = function () {};
// 使用方
window.Promise = 'abc';
Array.prototype.includes = 100;
- 污染全局环境
- 做独立的 web 系统没关系;如果做第三方 lib 就会有问题
那怎么解决勒,可以换一个名字,如
window.Promise2 = function () {};
Array.prototype.includes2 = function () {};
使用 babel-runtime 就是解决污染环境问题,安装 @babel/plugin-transform-runtime 和 @babel/runtime,参考最上的 package.json 文件,然后默认配置 .babelrc 即可
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
执行命令 npx babel src/index.js
查看
'use strict';
var _interopRequireDefault = require('@babel/runtime-corejs3/helpers/interopRequireDefault');
require('core-js/modules/es.object.to-string.js');
require('core-js/modules/es.promise.js');
var _includes = _interopRequireDefault(
require('@babel/runtime-corejs3/core-js-stable/instance/includes'),
);
var _promise = _interopRequireDefault(
require('@babel/runtime-corejs3/core-js-stable/promise'),
);
var _context;
var sum = function sum(a, b) {
return a + b;
}; // 新的 API
_promise['default'].resolve(100).then(function (data) {
return data;
}); // 新的 API
(0, _includes['default'])((_context = [10, 20, 30])).call(_context, 20);
以上解析后,不会污染全局环境