Babel-handbook使用
babelcompiler bundlertool
Babel
作为构建工具广泛采取的Javascript编译器,其转换编译、静态类型检查、动态polyfill等功能通过编写自定义插件来满足特定业务需求是工程化进阶必学知识点,此文章主要记录babel
内置功能包和插件的使用
预设是指根据配置加载对应插件的特定配置集合,每个预设在进行语法解析时会分别加载对应的转换插件而不用手动安装很多插件并配置
react相关预设
flow相关预设
typescript相关预设
此预设是在开发中最常用的,包含了ES3-ES2022的所需插件,通常设置presets > useBuiltIns: "usage"
搭配core-js
实现动态polyfill
json
{
"targets": "> 0.25%, not dead",
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3"
}
]
]
}
Note:useBuiltIns
默认为false,可使用usage
和entry
.usage时会根据当前浏览器targets
支持注入polyfill,entry
标识需要像老版本一样手动引入@babel/polyfill
相对比较繁琐
和工具包绑定使用的功能包,从Babel7以后所有单包的使用都需要提前安装@babel/core
多用于命令行操作
shell
pnpm add @babel/core @babel/cli
// 文件内容输出到stdout
npx babel src/index.js
// 文件编译输出
npx babel src/index.js -o dist/index.js
// 整个目录编译输出(-d: --dir)
npx babel src -d dist
// 编译附带sourcemap(-s: --sourcemap)
npx babel src/index.js -o dist/index.js -s
附带参数如下:
- --extensions
.ts,.js,.tsx,.jsx,.cjs,.mjs
指定babel
要处理的文件后缀
- --ignore
src/**/*.test.js
指定babel
要忽略的文件后缀
- --copy-files 复制文件,默认不复制被
--ignore
忽略的文件可以通过--no-copy-ignored
禁止
- --no-babelrc 指定不使用
.babelrc或.babelrc.json
配置文件
- --config-file 指定配置文件路径
- --out-file-extension
.mjs
指定输出文件后缀
- --keep-file-extension 指定保留原有文件后缀
- --presets
=@babel/preset=typescript,...
指定babel
要应用的预设
- --plugins
=@babel/proposal-class-properties,...
指定babel
要应用的插件
使用npm script
json
{
"scripts": {
"build:dir": "pnpm babel src -d dist"
}
}
结合require
钩子将babel注册到Node模块系统中并自动编译文件,在最细版本可以使用实验性功能experimental-worker替换
shell
pnpm add @babel/core @babel/register
index.js
js
console.log('this is index.js')
register.js
js
require('@babel/register')({
plugins: [],
presets: []
})
require('./index.js')
shell
node register.js
// console.log('this is index.js')
v7已弃用,推荐@babel/transform-runtime
搭配@babel/runtime
复用帮助函数减少代码体积
包含了babel运行时所需的帮助函数被@babel/transform-runtime
按需注入
此转换插件主要做了3件事:
- 使用
core-js
配置选项是否自动注入对应polyfill
- 使用
helpers
配置选项是否自动注入对应@babel/runtime/helpers
来替代行内帮助函数
- 使用
regenerator
配置选项指定是否自动注入@babel/runtime/renerator
来转换generator/async
语法
.babelrc
json
{
"targets": "> 0.25%, not dead",
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"helpers": true,
"regenerator": true
}
]
]
}
js
var sym = Symbol();
var promise = Promise.resolve();
var check = arr.includes("yeah!");
console.log(arr[Symbol.iterator]());
import _getIterator from "@babel/runtime-corejs3/core-js/get-iterator";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
var sym = _Symbol();
var promise = _Promise.resolve();
var check = _includesInstanceProperty(arr).call(arr, "yeah!");
console.log(_getIterator(arr));
独立适用于浏览器和非node环境,不推荐生产环境使用。暂略
多用于函数式变成方式操作都包含同/异步形式,所有转换操作将使用本地配置文 件
js
const babel = require('@babel/core')
const codeStr = `
function foo(a, b) {
return a + b;
}
`
js
babel.transform(codeStr, { babelrc: true }, (err, result) => {
console.log(result);
})
babel.transformAsync(codeStr, { babelrc: true }).then(result => {
console.log(result);
})
根据传入文件路径进行编译
js
const indexJs = path.resolve(__dirname, './index.js')
const fileResult = babel.transformFileSync(indexJs, {})
console.log(fileResult)
babel.transformFile(indexJs, {}, (err, result) => {
})
根据传入代码字符串返回对应ast
js
const astSyncRes = babel.parseSync(codeStr)
console.log(astSyncRes)
babel.parse(codeStr, {}, (err, res) => {
})
js
const parseAst = babel.parseSync(codeStr, {})
babel.transformFromAst(parseAst, codeStr, {}, (err, res) => {
const { code, map, ast } = res;
})
const astTransform = babel.tansformFromAstSync(parseAst, codeStr, {})
console.log(astTransform)
babel.parseAsnyc(codeStr)
.then(parseAst => {
return transformFromAstAsync(parseAst, codeStr, {})
})
.then(({ code, map, ast }) => {
})
根据源码转换ast
js
import { parse } from "@babel/parser"
const source = `
function foo() {
console.log(222)
}
`
console.log(parse(source, { sourceType: 'module' }))
根据ast转换代码
js
import { parse } from "@babel/parser"
import generate from "@babel/generator"
const source = `
function foo() {
console.log(222)
}
`
const ast = parse(source, {
sourceType: 'module'
})
console.log(generate(ast, {}, source));
获取源码中的具体位置,一般用于错误抛出具体位置
js
import { codeFrameColumns } from "@babel/code-frame"
const rawLines = `class Foo {
constructor() {
console.log("hello");
}
}`
const location = { start: { line: 2, column: 16 } }
const result = codeFrameColumns(rawLines, location, {
})
console.log(result)
用于操作字符串模版和对应类型ast生成,暂略
结合parser
遍历和更新节点,暂略
各种访问及断言方法的工具库,暂略