首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

手写第一个 babel 插件

在前文《babel是怎样工作的》中介绍了 Bable 中的的AST,这次咱们给 bable 写一个插件,文中会覆盖大部份的用法,如果你对某些细节不是很明白,可以去看一下官方的 Babel 手册,中文版在这里:

https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md

不过有的部分还没有翻译完。

访问节点

首先要找到要修改的节点,假设我们要帮一个特定的函数 加上调试用的信息,在这里只加上文件名就行了,而这个 长成这样:

使用者可以自己在 加上想要的名字,或者用插件加上去,第一步就是打开 AST Explorer(https://astexplorer.net/)并写一个简单的测试程序来确定 AST 应该是什么样的:

结果是这样:

AST

由于我们要能够判断使用者传入的几个参数,也要能确定使用者是在调用我们的函数,所以应该在 中进行处理:

判断是否为目标节点

下一步就是要判断是不是我们要做处理的节点了,这里先只简单的判断两个条件,函数名是 并且只能用一个参数:

如果要判断的目标比较复杂,目前也没有比较好的方法,只能这样比较。另外因为 babel 中只能拿到到 AST 信息,如果要判断类型等几乎是没有什么办法的,所以实际在写插件时必须考虑所有合理的写法,如果真的没办法处理时一定要要告诉使用者必须按照某种格式写,否则不会被处理

修改节点

在已经找到目标目标的前提下,要把文件名加入到参数中。这里直接加入 node 中的 ``__filename` 变量,这个变量在 node 的模块中是那个原始码文件的文件名。

那么为什么要用 修改 AST 的内容呢?直接用 加到 中不行吗?这里最大的差别在于 plugin 新增了节点,如果有上游的添加、删除等改变,babel 也必须要便利新的节点,所以要用 babel 的 API 让它知道有节点被改变了。

完整的代码如下:

接下来再来看看其他例子。

移除节点

假如要在正式环境把除错信息移除的话,就把 第二个以后的参数都移除掉:

的 可以用于获取指定位置的 对象,可用于处理特定的子节点。

替换节点和 template

这次需求变成了在代码中加上对 的判断,如果是生产环境就不要除错信息,结果像这样:

通常上面的代码在正式环境中并不会真的多出一个判断,因为一般 bundler 会把 NODE_ENV 换成字串常量,然后再由 minifier 移除掉不需要的部分。

因为要产出的代码变多了,这次就用 template

前面说过,要是新加入节点的话,babel 也会去遍历它,而我们加入的节点中就包含了要处理的目标节点,如果不进行特殊处理的话就会一直无限的遍历下去,所以要给添加的节点加上自己的标记,这样就可以避免重复处理。

抛出 error

在上一个例子中,为了要避免使用者少传参数而给了默认值,那如果要在少传参数时抛出错误又要怎么做呢。

如果没传参数的话应该会看到 babel 输出了这样的 error

到此为止,我们终于写出了自己的第一个 babel 插件。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20201217A0EG9200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券