Babel转码器
babel是一个广泛使用的ES6转码器,可以将ES6代码转换为ES5代码,从而在老版本浏览器执行。
初始化项目
命令行 生成package.json
文件
npm init
@babel/core 这个包主要是对代码进行转换的核心方法
npm install --save-dev @babel/core
@babel/cli这个是内置的cli,可以让我们从命令行来编译我们的文件
npm install --save-dev @babel/cli
@babel/preset-env,最新转码规则,处理ES6+规范语法的插件合集。如果需要转换react的jsx语法,使用@babel/preset-react,这里我们不需要转换jsx语法,下载一个即可。
npm install --save-dev @babel/preset-env
新建配置
在项目根目录下新建一个,babel的配置文件是babel.config.js。基本格式。注意每次修改babel配置后都需要重启编译命令。
// babel.config.js
module.exports = {
// 预设 字段设定转码规则
presets: [
"@babel/preset-env"
],
// 插件
plugins: []
}
在新建一个index.js文件,这里书写ES6语法
//index.js
const foo = () => { };
命令
可以开始转换代码了
//直接回在命令行打印出转换后的代码
npx babel index.js
// 转码结果写入一个文件 --out--file或者 -0 参数指定输入文件
npx babel index.js --out-file index-es5.js
// 或者
npx babel index.js -o index-es5.js
// 加上--watch实现热编译
npx babel index.js --watch --out-file index-es5.js
// 整个目录转码 --out-dir 或者-d 参数指定输出目录
npx babel src --out-dir lib
// 或者
npx babel src -d lib
// -s 参数生成source map文件
npx babel src -d lib -s
我们运行 npx babel index.js --watch --out-file index-es5.js
可以看到
//index.js
const foo = () => { };
//index-es5.js
var foo = function foo() {};
关于preset-env,可以提供一个targets
配置项指定运行环境,就是我们可以配置对应目标浏览器环境,那么babel就会编译出对应目标浏览器环境可以运行的代码。
// babel.config.js
module.exports = {
presets: [
[
"@babel/preset-env", {
'targets': {
// 浏览器
'browsers': ['ie >= 8', 'iOS 7'] // 支持ie8,直接使用iOS浏览器版本7
}
}
]
],
plugins: [
]
}
polyfill
Babel 默认只转换新的 JavaScript 句法,而不转换新的 API,比如Iterator
、Generator
、Set
、Map
、Proxy
、Reflect
、Symbol
、Promise
等全局对象,以及一些定义在全局对象上的方法(比如Object.assign
)都不会转码。这个时候就需要使用 @babel/polyfill (由core-js2和regenerator-runtime组成的一个集成包)了。然后,在脚本头部引入。需要先下载这个包。
npm install --save-dev @babel/polyfill
// index.js
import '@babel/polyfill';
class Test {};
// index-es5.js
"use strict";
require("@babel/polyfill");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Test = function Test() {
_classCallCheck(this, Test);
};
当转换class会引入一些helper辅助函数。如果有好多文件都用到了复杂语法的转换,这些helper函数代码量很大。我们还需要借助一个**@babel/runtime**(依赖@babel/helpers和regenerator-runtime)和插件**@babel/plugin-transform-runtime使用,它可以把helper函数抽离到一个公共的包里,用到的地方引入即可。@babel/plugin-transform-runtime还有一个最重要的作用,当Promise
需要polyfill
去解决时,会污染全局变量。其他项目用到这里时,就会把原有的Promise
一起转换掉。@babel/plugin-transform-runtime**插件为我们提供了一个配置项corejs,他可以给这些polyfill提供一个沙箱环境,这样就不会污染到全局变量。
需要配合 @babel/runtime-corejs2 这个包(稳定版用2就可以),注意如果不配置的话,是不会提供沙箱环境的。然后在 @babel/plugin-transform-runtime 插件配置corejs
npm install --save-dev @babel/polyfill @babel/plugin-transform-runtime @babel/runtime-corejs2
// index-es5.js
"use strict";
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
require("@babel/polyfill");
var Test = function Test() {
(0, _classCallCheck2["default"])(this, Test);
};
// babel.config.js
module.exports = {
presets: [
[
"@babel/preset-env", {
'targets': {
'browsers': ['ie >= 8', 'iOS 7'] // 支持ie8,直接使用iOS浏览器版本7
}
}
]
],
plugins: [
[
"@babel/plugin-transform-runtime",
{
"corejs": 2
}
]
]
}
presets也有一些配置选项
modules:“amd” | “umd” | “systemjs” | “commonjs” | “cjs” | “auto” | false,默认为"auto"。
如果想要编译出来的模块引入规范还是import,则可以在preset-env的配置项中添加"modules": false即可。用amd、umd就是它代表的规范。
useBuiltIns:“usage” | “entry” | false
usage:配置这个会扫描当前项目用到的新api,更进我们配置的浏览器兼容。
entry:按需引入,把所有ie8以上以及ios7不支持的api polyfill引入进来。
false:默认false。
浏览器环境
Babel 也可以用于浏览器环境,使用**@babel/standalone**模块提供的浏览器版本,将其插入网页。但是网页实时将 ES6 代码转为 ES5,对性能会有影响。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//写入ES6的代码
</script>