[关闭]
@bornkiller 2018-07-18T08:16:42.000000Z 字数 1360 阅读 2175

开发 babel 插件

前端工具


前言

时光荏苒,ECMA 标准迭代终究进入正轨,而浏览器的实现程度依旧一言难尽。实践中应用 esnext 规范,babel 编译流程必不可少,将 ES6 代码编译转化为 ES5 代码,规避浏览器进度不一的弊病。babel 本身的可扩展性,其存在的意义早已超过单纯的标准兼容,如babili等,而这一切都借助于插件来实现。

Reference

关键词

visitor 模式实际访问节点路径,path 表示节点之间的连接,通过这个对象可以访问节点、父节点以及修改节点(类似 DOM 的操作)。

流程

Babel 的工作流可以用下面一张图来表示,代码首先经由 babylon 解析成抽象语法树,后经一些遍历和分析转换,最后根据转换后的 AST 生成新的常规代码。

babel-workflow.png-1570.4kB

插件的核心,暨通过 Visitor pattern 访问特定路径,修改 AST 达到目标。

插件实现

本文中,将参照 babel-plugin-import 实现更可定制化的按需加载插件,babel-plugin-shaking-import

假定原始代码与转换目标如下:

  1. // Original
  2. import { Observable, Subject } from 'rxjs';
  1. // Only necessary code
  2. import { Observable } from 'rxjs/Observable';
  3. import { Subject } from 'rxjs/Subject';

原始代码 AST 分析结果简化版如下:

  1. {
  2. "type": "ImportDeclaration",
  3. "specifiers": [
  4. {
  5. "type": "ImportSpecifier",
  6. "imported": {
  7. "type": "Identifier",
  8. "name": "Observable"
  9. },
  10. "importKind": null,
  11. "local": {
  12. "type": "Identifier",
  13. "name": "Observable"
  14. }
  15. },
  16. {
  17. "type": "ImportSpecifier",
  18. "imported": {
  19. "type": "Identifier",
  20. "name": "Subject"
  21. },
  22. "importKind": null,
  23. "local": {
  24. "type": "Identifier",
  25. "name": "Subject"
  26. }
  27. }
  28. ]
  29. }

借助 babel-types,生成 AST 结构,关键属性 specifier.localspecifier.imported 已由分析结果给出。

  1. types.importDeclaration(
  2. types.importSpecifier(specifier.local, specifier.imported),
  3. types.stringLiteral(destinationPath)
  4. );

然后将新 AST 结构插入,删除原始结构。

  1. path.insertBefore(declaration);
  2. path.remove();

全部代码参见 https://github.com/bornkiller/babel-plugin-shaking-import

Contact

Email: hjj491229492@hotmail.com
qrcode_for_gh_d8efb59259e2_344.jpg-8.7kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注