内容简介:在一个月黑风高的晚上,小黄问我:我: 我靠,小黄: 那你知道
在一个月黑风高的晚上,小黄问我: babel
你知道么?
我: 我靠, babel
我肯定知道啊,你这是在侮辱谁?
小黄: 那你知道 babel
是怎么工作的么?
我: 当然了,第一步是进行词法、语法解析,解析成 AST
,第二步就是接收到 AST
之后,对节点进行添加、更新、删除等操作,这也是插件要介入的地方,第三步就是把转换后的 AST
转换成字符串的代码。
小黄: 厉害啊,那你写过插件么?
我: 没有,没写过。
小黄: 你居然没写过?
我: 我靠,你什么眼神?等着,我晚上给你撸一个,对了,你有资料吗?
小黄: 有,拿着 Babel 插件手册(https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md)
要干个啥?
说了要写一个插件,总不能写个 1 + 1 等于 2 吧。正好在看 antd
的内容,那就搞个简单的按需加载的插件吧。
// 我们这么写 import { Button, Table } from 'antd'; // 其实相当于 import Button from 'antd/lib/button'; import Table from 'antd/lib/table';
所以,目标确定了,我们还等啥呢?
撸起袖子开干
在大概的了解了上面的资料之后,我们就开干了。
通过阅读资料,我们知道 Babel
插件需要我们暴露一个方法,这个方法返回一个含有 visitor
的对象。
module.exports = ({ types: t }) => { visitor: { } };
那么我们要怎么去分析代码呢?很简单,我们去把代码贴到 AST explorer 里面,然后把转换的结构就可以拿出来分析了。
通过上面的分析,我们可以知道 import { Button, Table } from 'antd';
是一个 ImportDeclaration
节点,所以我们需要去操作这个类型的节点,所以在 visitor
里我们这么写。
module.exports = ({ types: t }) => ({ visitor: { ImportDeclaration(path) { // 我们可以通过 specifiers 拿到导入的东西,source 来拿到从哪个库导入的 const { specifiers, source } = path.node; // 排除 default 的导入情况 if (!t.isImportDefaultSpecifier(specifiers[0])) { } } } });
上面使用的 babel.types
是一个帮助大家更好的操作节点的 工具 库,大家可以到这里去看详细文档。
好了,上面我们已经拿到了导入的语句,现在我们去拿到导入了什么东西,以及从什么库导入的,这样我们就能够完成转换了。
module.exports = ({ types: t }) => ({ visitor: { // 我们可以通过第二个参数里的 opts 来拿到参数配置 ImportDeclaration(path, { opts }) { // 我们可以通过 specifiers 拿到导入的东西,source 来拿到从哪个库导入的 const { specifiers, source } = path.node; // 排除 default 的导入情况 if (!t.isImportDefaultSpecifier(specifiers[0])) { const declarations = specifiers.map(specifier => { // 我们可以通过 specifier.imported.name 获取到导入的东西 // 先写死 antd const importPath = `${source.value}/lib/${specifier.imported.name}`; // 我们通过上面的信息返回了一条 import 语句 return t.ImportDeclaration( [t.ImportDefaultSpecifier(specifier.local)], t.StringLiteral(importPath) ); }); // 将上面生成的 import 语句替换到原来的语句 path.replaceWithMultiple(declarations); } } } });
大功告成,那么编写一个 babel
插件的大概流程就是这样,当然了,这个简单的插件肯定还有很多配置、边界问题等等没有考虑到,这个简单的 demo 我上传到了我的仓库。(点击「阅读原文」查看)
文 / 小烜同学
天衣无缝的秘密是: 做技术,你快乐吗?
编 / 荧声
感谢您的阅读
欢迎关注、点赞、留言讨论、分享转发支持我们
期望赞赏作者?
请查看公众号菜单中「关于」-「支持我们」
欢迎读者来稿
创宇前端接受首发或授权转载的原创技术分享
赠送任选技术书籍
经常错过推送?
给创宇前端公众号加上星标吧
以上所述就是小编给大家介绍的《你会 babel 插件么?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- IDEA 插件:多线程文件下载插件开发
- 从头开发一个Flutter插件(二)高德地图定位插件
- Gradle插件开发系列之gradle插件调试方法
- Gradle插件开发系列之开发第一个gradle插件
- WordPress插件开发 -- 在插件使用数据库存储数据
- Gradle插件开发系列之发布gradle插件到开源库
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。