你会 babel 插件么?

栏目: Python · 发布时间: 5年前

内容简介:在一个月黑风高的晚上,小黄问我:我: 我靠,小黄: 那你知道

在一个月黑风高的晚上,小黄问我: 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 里面,然后把转换的结构就可以拿出来分析了。

你会 babel 插件么?

通过上面的分析,我们可以知道 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 插件么?

文 / 小烜同学

天衣无缝的秘密是: 做技术,你快乐吗?

编 / 荧声

感谢您的阅读

欢迎关注、点赞、留言讨论、分享转发支持我们

期望赞赏作者?

请查看公众号菜单中「关于」-「支持我们」

欢迎读者来稿

创宇前端接受首发或授权转载的原创技术分享

赠送任选技术书籍

经常错过推送?

给创宇前端公众号加上星标吧

你会 babel 插件么?


以上所述就是小编给大家介绍的《你会 babel 插件么?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

iOS软件开发揭密

iOS软件开发揭密

虞斌 / 电子工业出版社 / 2011-5-1 / 79.00元

本书以严密的体系性提供了iPhone和iPad软件开发从入门到专家的系统性知识,并提供来源于真实项目的可重用商业代码。书中的每个实例都是项目经验的提炼,深入浅出地讲解iPhone和iPad软件开发的核心技术要点,基本涵盖了iOS软件开发在真实商业项目中所需要的所有主题,并将实例介绍的技术深度和超值的实用性结合在一起,成为本书的特色。 随书附赠的光盘中包含了书中大量案例的完整工程源代码,可以让......一起来看看 《iOS软件开发揭密》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具