共计 3401 个字符,预计需要花费 9 分钟才能阅读完成。
babel
标签(空格分隔):babel
babel
Babel 是一个广泛使用的转码器,可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。
Babel 会在正在被转录的文件的当前目录中查找一个 .babelrc 文件。如果不存在,它会遍历目录树,直到找到一个 .babelrc 文件,或一个 package.json 文件中有 “babel”: {}
babel6 将 babel 全家桶拆分成了许多不同的模块 (rc 是 run command 的缩写)
依赖
babel-loader:使用 es6 或加载模块时,对 es6 代码进行预处理,转为 es5 语法。babel-core:允许我们去调用 babel 的 api,可以将 js 代码分析成 ast(抽象语法树),方便各个插件分析语法进行相应的处理.babel-preset-env:推荐 preset,比如 es2015,es2016,es2017,latest,env(包含前面全部)babel-polyfill:它效仿一个完整的 ES2015+ 环境,使得我们能够使用新的内置对象比如 Promise,比如 Array.prototype.includes 和生成器函数(提供给你使用 regenerator 插件)。为了达到这一点,polyfill 添加到了全局范围,就像原生类型比如 String 一样。babel-runtime babel-plugin-transform-runtime:这个插件能自动为项目引入 polyfill 和 helpers
presets
babel5 会默认转译 ES6 和 jsx 语法,babel6 转译的语法都要在 perset 中配置,preset 简单说就是一系列 plugin 包的使用。
预设就是一系列插件的集合,把之前的参数保存为一个预设,下次就能直接使用。
基础配置如下:(设置转码规则和插件)
{
“presets”: [],
“plugins”: []
}
presets 字段设定转码规则,官方提供以下的规则集,按需安装。
可以看到提案在进入 stage3 阶段时就已经在一些环境被实现,在 stage2 阶段有 babel 的实现。
# ES2015 转码规则
babel-preset-es2015
# react 转码规则
babel-preset-react
# ES7 不同阶段语法提案的转码规则(共有 4 个阶段)
babel-preset-stage-0
babel-preset-stage-1: draft – 必须包含 2 个实验性的具体实现,其中一个可以是用转译器实现的,例如 Babel。
babel-preset-stage-2: candidate – 至少要有 2 个符合规范的具体实现。
babel-preset-stage-3
配置:
{
“presets”: [
“es2015”,
“stage-2”
],
“plugins”: []
}
babel-preset-env
此段内容来自于 babel 到底该如何配置?
上面这些 preset 官方现在都已经不推荐了, 官方唯一推荐 preset:babel-preset-env
这款 preset 能灵活决定加载哪些插件和 polyfill
// cnpm install -D babel-preset -env
{
“presets”: [
[“env”, {
“targets”: {// 指定要转译到哪个环境
// 浏览器环境
“browsers”: [“last 2 versions”, “safari >= 7”],
//node 环境
“node”: “6.10”, //”current” 使用当前版本的 node
},
// 是否将 ES6 的模块化语法转译成其他类型
// 参数:”amd” | “umd” | “systemjs” | “commonjs” | false,默认为 ’commonjs’
“modules”: ‘commonjs’,
// 是否进行 debug 操作,会在控制台打印出所有插件中的 log,已经插件的版本
“debug”: false,
// 强制开启某些模块,默认为 []
“include”: [“transform-es2015-arrow-functions”],
// 禁用某些模块,默认为 []
“exclude”: [“transform-es2015-for-of”],
// 是否自动引入 polyfill,开启此选项必须保证已经安装了 babel-polyfill
// 参数:Boolean,默认为 false.
“useBuiltIns”: false
}]
]
}
{
“presets”: [
[“env”, {
“modules”: false,
“targets”: {
“browsers”: [“> 1%”, “last 2 versions”, “not ie <= 8”]
}
}],
“stage-2”
],
“plugins”: [
“transform-vue-jsx”,
“transform-runtime”,
“syntax-dynamic-import”,
“transform-es2015-modules-commonjs”
]
}
plugins
此段内容来自于 babel 到底该如何配置?
babel 中的插件,通过配置不同的插件才能告诉 babel,我们的代码中有哪些是需要转译的。
插件官网
{
“plugins”: [
[“transform-es2015-arrow-functions”, { “spec”: true}]
]
}
transform-runtime, 这个插件能自动为项目引入 polyfill 和 helpers
polyfill 作用是用已经存在的语法和 api 实现一些浏览器还没有实现的 api,对浏览器的一些缺陷做一些修补。例如 Array 新增了 includes 方法,但是低版本的浏览器上没有,就得做兼容处理
transform-runtime 这个插件依赖于 babel-runtime
babel-runtime 由三个部分组成:
core-jscore-js 极其强悍,通过 ES3 实现了大部分的 ES5、6、7 的 polyfill。regeneratorregenerator 来自 facebook 的一个库,用于实现 generator functions。helpersbabel 的一些工具函数,这个 helpers 和使用 babel-external-helpers 生成的 helpers 是同一个东西
配置 transform-runtime
{
“plugins”: [
[“transform-runtime”, {
“helpers”: false, // 自动引入 helpers
“polyfill”: false, // 自动引入 polyfill(core-js 提供的 polyfill)
“regenerator”: true, // 自动引入 regenerator
}]
]
}
比较 transform-runtime 与 babel-polyfill 引入垫片的差异:
使用 runtime 是按需引入,需要用到哪些 polyfill,runtime 就自动帮你引入哪些,不需要再手动一个个的去配置 plugins,只是引入的 polyfill 不是全局性的,有些局限性。而且 runtime 引入的 polyfill 不会改写一些实例方法,比如 Object 和 Array 原型链上的方法,像前面提到的 Array.protype.includes。babel-polyfill 就能解决 runtime 的那些问题,它的垫片是全局的,而且全能,基本上 ES6 中要用到的 polyfill 在 babel-polyfill 中都有,它提供了一个完整的 ES6+ 的环境。babel 官方建议只要不在意 babel-polyfill 的体积,最好进行全局引入,因为这是最稳妥的方式。一般的建议是开发一些框架或者库的时候使用不会污染全局作用域的 babel-runtime,而开发 web 应用的时候可以全局引入 babel-polyfill 避免一些不必要的错误,而且大型 web 应用中全局引入 babel-polyfill 可能还会减少你打包后的文件体积(相比起各个模块引入重复的 polyfill 来说)。
结合 ESLint
许多工具需要 Babel 进行前置转码,如 ESLint 和 Mocha
在项目根目录下,新建一个配置文件.eslint,在其中加入 parser 字段。
{
“parser”: “babel-eslint”,
“rules”: {
…
}
}
在 package.json 之中,加入相应的 scripts 脚本
“scripts”: {
“lint”: “eslint –ext .js,.vue src”,
},