摘要:的工作过程的处理主要过程解析转换生成。代码转换处理,处理工具插件等就是在这个阶段进行代码转换,返回新的。若感兴趣了解更多内容,插件中文开发文档提供了很多详细资料。
Babel简介
Babel是Javascript编译器,是种代码到代码的编译器,通常也叫做『转换编译器』。
Babel的工作过程Babel的处理主要过程:解析(parse)、转换(transform)、生成(generate)。
代码解析
词法分析和语法分析构造AST。
代码转换
处理AST,处理工具、插件等就是在这个阶段进行代码转换,返回新的AST。
代码生成
遍历AST,输出代码字符串。
所以我们需要对AST有一定了解才能进行Babel插件开发。
AST在这整个过程中,都是围绕着抽象语法树(AST)来进行的。在Javascritp中,AST,简单来说,就是一个记录着代码语法结构的Object。感兴趣的同学可到https://astexplorer.net/ 去深入体验
比如下面的代码:
import {Button} from "antd"; import Card from "antd/button/lib/index.js";
转换成AST后如下,
{ "type": "Program", "start": 0, "end": 253, "body": [ { "type": "ImportDeclaration", "start": 179, "end": 207, "specifiers": [ { "type": "ImportSpecifier", "start": 187, "end": 193, "imported": { "type": "Identifier", "start": 187, "end": 193, "name": "Button" }, "local": { "type": "Identifier", "start": 187, "end": 193, "name": "Button" } } ], "source": { "type": "Literal", "start": 200, "end": 206, "value": "antd", "raw": ""antd"" } }, { "type": "ImportDeclaration", "start": 209, "end": 253, "specifiers": [ { "type": "ImportDefaultSpecifier", "start": 216, "end": 220, "local": { "type": "Identifier", "start": 216, "end": 220, "name": "Card" } } ], "source": { "type": "Literal", "start": 226, "end": 252, "value": "antd/button/lib/index.js", "raw": ""antd/button/lib/index.js"" } } ], "sourceType": "module" }插件开发思路
确定我们需要处理的节点类型
处理节点
返回新的节点
简单插件结构插件必须是一个函数,根据官方文档要求,形式如下:
module.exports = function ({ types: t }) { return { visitor: { ImportDeclaration(path, source){ //todo }, FunctionDeclaration(path, source){ //todo }, } } }
types来自@babel/types工具类,主要用途是在创建AST的过程中判断各种语法的类型和节点构造。
实现示例很多同学用过 babel-plugin-import ,它帮助我们在使用一些JS类库是达到按需加载。其实,该插件帮助我们做了如下代码转换:
//from import {Button } from "antd"; //to import Button from "antd/es/button"; import "antd/es/button/style.css";
我们先看看两者的AST有何差别,以帮助我们对转换有个清晰的认识:
转换前:
[{ "type": "ImportDeclaration", "start": 6, "end": 45, "specifiers": [ { "type": "ImportSpecifier", "start": 14, "end": 20, "imported": { "type": "Identifier", "start": 14, "end": 20, "name": "Button" }, "local": { "type": "Identifier", "start": 14, "end": 20, "name": "Button" } } ], "source": { "type": "Literal", "start": 28, "end": 44, "value": "antd/es/button", "raw": ""antd/es/button"" } }]
转换后:
[{ "type": "ImportDeclaration", "start": 5, "end": 41, "specifiers": [ { "type": "ImportDefaultSpecifier", "start": 12, "end": 18, "local": { "type": "Identifier", "start": 12, "end": 18, "name": "Button" } } ], "source": { "type": "Literal", "start": 24, "end": 40, "value": "antd/es/button", "raw": ""antd/es/button"" } }, { "type": "ImportDeclaration", "start": 46, "end": 76, "specifiers": [], "source": { "type": "Literal", "start": 53, "end": 75, "value": "antd/es/button/style", "raw": ""antd/es/button/style"" } }]
对比两棵树,我们应该有个大致的思路。在转换过程中,我们还需要一些参数,这些参数在配置文件(package.json或者.babelrc)中,提供了一些自定义配置,比如antd的按需加载:
["import",{libraryName:"antd",libraryDireactory:"es","style":"css"}]
现在我们开始尝试实现这个插件吧:
module.exports = function ({ types: t }) { return { visitor: { ImportDeclaration(path, source) { //取出参数 const { opts: { libraryName, libraryDirectory="lib", style="css" } } = source; //拿到老的AST节点 let node = path.node if(node.source.value !== libraryName){ return; } //创建一个数组存入新生成AST let newImports = []; //构造新节点 path.node.specifiers.forEach(item => { newImports.push(t.importDeclaration([t.importDefaultSpecifier(item.local)], t.stringLiteral(`${libraryName}/${libraryDirectory}/${item.local.name}`))); newImports.push(t.importDeclaration([], t.stringLiteral(`${libraryName}/${libraryDirectory}/style.${style}`))) }); //替换原节点 path.replaceWithMultiple(newImports); } } }
}
现在,简单版本的@babel-plugin-import的babel插件我们已经完成了。
若感兴趣了解更多内容,babel插件中文开发文档提供了很多详细资料。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/106485.html
摘要:快速体验安装依赖新建文件夹,在命令行里进入该文件夹,并执行如下命令生成文件是内置的一个,可通过命令行操作来编译文件。入门为了确保转换后的代码能正常的运行,最好在代码之前引入这是一个实现了部分特性的包。参考中文网入门 简介 Babel 是一个 JavaScript 编译器,可将我们代码中的 ES6 语法转换为 ES5 的语法,使我们的代码能在不支持 ES6 语法的环境中正常运行。配合一些...
摘要:最近的技术项目里大量用到了需要修改源文件代码的需求,也就理所当然的用到了及其插件开发。在这里我要推荐一款实现了这些标签的插件,建议在你的项目中加入这个插件并用起来,不用再艰难的书写三元运算符,会大大提升你的开发效率。具体可以参见插件手册。 最近的技术项目里大量用到了需要修改源文件代码的需求,也就理所当然的用到了Babel及其插件开发。这一系列专题我们介绍下Babel相关的知识及使用。 ...
阅读 2045·2021-11-24 09:39
阅读 735·2021-09-30 09:48
阅读 957·2021-09-22 15:29
阅读 2356·2019-08-30 14:17
阅读 1869·2019-08-30 13:50
阅读 1317·2019-08-30 13:47
阅读 947·2019-08-30 13:19
阅读 3361·2019-08-29 16:43