babel能做什么
语法转换
转换和编译esnext的语法,甚至是只属于自己的定制化的语法
在目标环境中添加缺失的特性
主要是通过在目标环境注入补丁代码,所以安装的时候是--save。 babel7.0之前的版本安装babel-polyfill,babel7之后的版本安装@babel/polyfill。
但是,@babel/polyfill目前只包含tc39的Stage4阶段的特性,根本无法满足小伙伴们的高超的编码手法,好在babel提供了预设功能,可以配置化的引入代码。
babel是如何工作的
babel是通过babel核心代码+babel插件来工作的
1.核心代码
在这个npm包里@babel/core
使用编码的方式可以直观的看到这个过程,看看打印出来是什么?
const babel =require("@babel/core");
const code=`(n)=>n**2`
const result=babel.transform(code,{
presets:["@babel/preset-env"]
})
console.log(result.code);
没错就是编译后的代码
2.插件(plugins)
Babel 是一个编译器(输入源码 => 输出编译后的代码)。就像其他编译器一样,编译过程分为三个阶段:解析、转换和打印输出。
现在,Babel 虽然开箱即用,但是什么动作都不做。它基本上类似于 const babel = code => code; ,将代码解析之后再输出同样的代码。如果想要 Babel 做一些实际的工作,就需要为其添加插件。
一句话概述就是 插件机制提供了babel的语法解析和代码转换的功能。
!插件是有序执行的,所以在配置中,顺序是很重要的
3.预设(presets)
顾名思义就是一份预先设置好的babel配置,里面有presets和plugins。
preset-env里最终输出的是一个配置对象:{plugins:Array}
里面只有插件数组
!预设是反序执行的(主要是为了兼容以前用户的常规写法),所以在配置中要特别注意
如何使用babel
1.安装依赖
- @babel/core
babel核心代码
- @babel/cli
这样会在node_modules里的.bin项目中添加了一个叫babel的可执行脚本
- @babel/preset-env
babel常用的预设
2.添加执行脚本
// package.json
...
scripts:{
babel:"babel index.js -o compiled.js", //单文件
babel-lib:"babel src -d lib" //多文件
//[cli更多选项](https://www.babeljs.cn/docs/babel-cli)
}
...
3.babel常规配置
因为babel的功能主要是通过插件来实现的,所以如果不做任何配置的话,相当于不执行任何插件,也就不做任何处理,所以我们写一份配置文件来让babel变的实用,当然也可以在脚本上添加参数,不过通常在项目中,实用babel配置文件更为直观
babel.config.js
// babel.config.js
module.exports = {
// presets 生效顺序是倒序的
presets: [
[
"@babel/preset-env",
{
// 如果配置,会覆盖browserslist配置,推荐使用browserslist,这样postcss以及其他工具共同使用一份配置
// targets: {
// "chrome": "58", 编译后的语法最低支持到chrome 58
// "esmodules": true 目标为支持es6模块的浏览器环境
// "node": true // 目标代码为当前node最新版本的标准
// },
// 按需自动引入corejs@3的polyfill,entry是全局引入
useBuiltIns: "usage",
// 需安装生产依赖core-js@3和regenerator-runtime
corejs: "3", // 当使用usage参数时,必须指定corejs版本,默认corejs@2,所以这里配置3,生产依赖需要安装core-js@3
}]
],
// plugins 生效顺序是正序的
plugins: [
// 打包后的代码,辅助函数统一从@babel/runtime里引入,可减少重复的helper代码
// 需要同时安装生产依赖@babel/runtime才能生效
["@babel/plugin-transform-runtime"]
]
};
.eslintrc.js
// .eslintrc.js
module.exports = {
// lint环境
env: {
es6: true,
node: true,
},
// 扩展规则
extends: ["airbnb-base"],
// 解析器
parser: "@babel/eslint-parser", // 配合babel使用
parserOptions: {
ecmaVersion: 12, //es12版本
sourceType: "module", // default script
ecmaFeatures: {
jsx:true,
impliedStrict: true,
},
},
// 自定义规则 0关闭,1警告,2错误
rules: {
},
};
package.json
// package.json
{
...
"scripts": {
...
"babel": "babel src -d lib",
},
"devDependencies": {
...
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"@babel/node": "^7.12.6", // 建议全局安装
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.1",
},
"dependencies": {
...
"@babel/runtime": "^7.12.5",
"core-js": "^3.8.0",
"regenerator-runtime": "^0.13.7"
},
// https://caniuse.com/ 可以查看各浏览器支持度
"browserslist": [
"> 1%", //全球超过1%人数使用的浏览器
"last 2 versions",// 所有浏览器兼容到最近的两个版本
"not ie <= 8"// ie版本不低于8
]
}
依赖的用途
开发依赖(--save-dev)
@babel/core
babel核心库@babel/cli
babel命令行@babel/preset-env
babel预设环境,包括已经稳定实现的es6及以上语法插件,当然还有常用的预设@babel/preset-react
和@babel/preset-typescript
@babel/plugin-transform-runtime
抽取babel辅助函数为公共runtime,减少重复代码@babel/node
转化es6语法为node支持的语法,推荐全局安装babel/eslint-parser
配合eslint使用,不然eslint识别不了超前的es语法
生产依赖(--save)
corejs@3
polyfill的代码,建议使用corejs 3.0版本regenerator-runtime
生成器语法的依赖@babel/runtime
这个是配合@babel/plugin-transform-runtime
使用的
编写babel插件
可以跟着这篇文章来写一个自己的插件插件开发手册传送门-英语
中文版比较滞后,大家酌情阅读插件开发手册传送门-中文