babel —— 常用插件

739 阅读4分钟

这是我参与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

image.png

该插件是作为@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创建的项目。具体的文档可以看这里