你会 babel 插件么?

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

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

在一个月黑风高的晚上,小黄问我: 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 插件么?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Think Python

Think Python

Allen B. Downey / O'Reilly Media / 2012-8-23 / GBP 29.99

Think Python is an introduction to Python programming for students with no programming experience. It starts with the most basic concepts of programming, and is carefully designed to define all terms ......一起来看看 《Think Python》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码