这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战
前言
上篇已经看了一些babel的基本常识,这篇文主要是整理下工作中常用到的babel插件,会持续补充。
babel插件
babel的运行过程主要包括三个阶段:parse(解析),transform(转化),generate(生成)。
babel插件主要分为两类:语法插件和转化插件。
@babel/parser
babel的代码解析器,将源码解析成AST。
@babel/core
babel的编译器,核心API都定义在这里边。
@babel/generator
babel的代码生成器,读取AST并将其转化为向后兼容的代码。
@babel/types
用于处理AST节点的工具库,包含了构造,验证和变换AST节点的方法。
@babel/plugin-transform-runtime
@babel/plugin-transform-runtime的作用是转义代码,它提供了一些公共API,这些API会帮助代码转化。代码转义后可能需要安装@babel/runtime-corejs3
babel使用了一些很小的helper作为通用工具函数,默认情况下,这些helper会在每个需要它的文件中都添加,但是某些情况下会造成代码重复。
为什么需要@babel/plugin-transform-runtime
-
@babel/plugin-transform-runtime插件会开启babel对helper code的复用,节省了代码体积。这也是该插件出现的原因,所有的helper将引用@babel/runtime模块以避免编译后的文件里出现重复代码。
-
为代码创造一个沙盒环境。若使用@babel/polyfill会污染全局作用域,但是该插件会使用core-js去替换内置对象(Promise,Set等),从而让代码环境更干净,所以你可以直接使用@babel/plugin-transform-runtime+@babel/runtime-corejs,而无需引入@babel/polyfill
plugins: [
[
"@babel/plugin-transform-runtime",
{
absoluteRuntime: false, //设置从哪个目录导入helpers/polyfill
corejs: 3, //false或者number,引入对应corejs版本来重写需要polyfill的API
helpers: true, //如果置为不开启,可能会每个文件都引入同一个helper code;开启后则是将helpers提取到公共模块,通过在每个文件引入公共模块的helper
regenerator: true, //是否对generator,async函数进行转化,true则引入@babel/runtime/regenerator避免污染全局作用域
useESModules: false //启用时,helpers将不经过@babel/plugin-transform-modules-commonjs处理。在webpack这种模块系统里可以生成更小的构建代码
}
]
]
其他配置都好理解,这里单独记录下absoluteRuntime这个配置:
默认情况下,absoluteRuntime的设置是:@babel/runtime-corejs3,@babel/runtime-corejs2,@babel/runtime
@babel/plugin-transform-runtime插件直接从默认配置引入helpers与polyfill,但是这要求这些包必须在被编译文件的node_modules里。对于嵌套的node_modules或者项目之外的命令行,是找不到文件模块的。这种情况语序开发者设置一个绝对路径插入到输出代码。
@babel/runtime
工具库:babel模块化的运行时辅助工具函数 + regenerator-runtime
该插件是作为@babel/plugin-transform-runtime插件的运行时依赖使用的。
@babel/plugin-transform-modules-commonjs
将ES模块转化为CommonJS,该插件包含在@babel/preset-env中。
@babel/runtime-corejs
- 2版本:仅支持全局变量,如Promise,Symbol,Set等
- 3版本:2版本的基础上,还支持实例属性,如includes方法等。
@babel/cli
在命令行中使用babel命令来编译文件。一般很少用,因为打包工具已经帮我们做好了。
@babel/node
在node环境运行ES6代码。
@babel/polyfill
用来处理编译的代码中出现的新的API,如Generator,Set,Proxy,Promise等全局对象,或者Array.from等新的方法。
缺点:
-
打出来的文件包非常大。@babel/polyfill会加载整个polyfill库,把所有的方法都加到原型链上。
-
污染全局变量。对很多对象的原型链都做了修改,使得开发过程变得非常不可控。
基于以上两个问题,都会倾向于使用@babel/runtime-corejs
@babel/preset-env
babel提供的预设配置库,无需关注环境和语法就可以直接使用最新的JS,具体的配置可以看这里。
@babel/preset-env不支持stage-x插件。
提倡配置targets参数来提供项目支持的目标环境。如果不设置,默认将代码转化为ES2015+
@vue/babel-preset-env
这个插件是专门针对Vue项目的,基于@babel/preset-env,@babel/plugin-transform-runtime(使用了helpers替换内联babel的helpers)等插件的封装。
@vue/babel-preset-app
该插件是仅针对通过vue-cli创建的项目。具体的文档可以看这里。