手把手教你写几个实用的的AST插件
2020/1/4 5:21:31
本文主要是介绍手把手教你写几个实用的的AST插件,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
AST 是非常有用的
。
今天下午听了小组一个老哥做的AST分享,深以为然。
为了加深印象,就写了篇总结,顺便分享给大家,希望能给朋友们一些启发。
AST有用,口说无凭, 且看几个具体的案例
。
且不说:
Vue => React
React => Vue
的代码转换方法,
我们就看一个可以无痛升级旧版React
的工具:
react-codemod
代码地址:https://github.com/reactjs/re...
这个工具,功能十分强大,使用起来也很方便,只需要运行一行命令:
npx react-codemod <transform> <path> [...options]
这些无不借助了AST。
下面我们就进入今天的内容。
正文
本文的主要内容包括:
- 1 理论: AST 概念
- 2 实践: 使用 AST 实现一个代码转换工具, 把
var
转换成let
- 3 实践: 使用 AST 实现一个Eslint 插件, 禁用 console
- 4 实践: 使用 AST 实现一个Babel插件, 过滤 Debugger
1. AST 基本概念
AST 是什么
AST is a hierarchical program representation that presents source code structure according to the grammar of a programming language, each AST node corresponds to an item of a source code.
在计算机科学中,抽象语法
和抽象语法树
其实是源代码的抽象语法结构的树状表现形式
。
常用的浏览器就是通过将js代码转化为抽象语法树来进行下一步的分析等其他操作。
所以将js转化为抽象语法树更利于程序的分析。
AST 能做什么
- 代码语法的检查
- 代码风格的检查
- 代码的格式化
- 代码的高亮
- 代码错误提示
- 代码自动补全
- 等等。
AST 三板斧
- 生成AST
- 遍历和更新AST
- 将AST重新生成源码
为了便于理解, 我们看一个具体的例子。
这里顺便给大家介绍一个十分有用的网站: https://astexplorer.net/
你譬如:
声明, 变量, 类型等各种信息一应俱全。
而且这里也提供了各种插件模版供你选择:
十分的方便。
我们就根据这个例子, 我们做个小的实践。
2. 实践: 使用AST实现一个代码转换工具, 把var转换成let
比如, 现在要重构一个老项目, 你要把项目里的var 全部替换成let, 你会怎么做?
手动替换?
或者借助工具一键替换?
现在就教你一招:一键替换大法
。
首先还是要介绍一把大杀器: jscodeshift
jscodeshift 是一个 Javscript Codemod 工具,官方对 Codemod 的解释是:
Codemod is a tool/library to assist you with large-scale codebase refactors that can be partially automated but still require human oversight and occasional intervention.
jscodeshift 也是基于 esprima
的,其通过 path 可以很容易的在 AST 上遍历 node
。
现在我们就开始替换项目中的var.
首先,到 https://astexplorer.net 里面编写代码.
模板我们选: jscodeshift
官方自带的例子, 把变量名字反转:
我们现在要改变量, 这个工具很贴心的一点是可以高亮实时对照,
现在, 找到kind === var
的对象, 替换成let
:
得到如下代码:
export default function transformer(file, api) { const j = api.jscodeshift; return j(file.source) .find(j.VariableDeclaration, { kind: 'var'}) .forEach(path => { const letStatement = j.variableDeclaration('let', path.node.declarations) j(path).replaceWith(letStatement) }) .toSource(); }
这样也可以:
path.node.kind = 'let'; // 传入的实际是一个引用
实际效果:
大功告成!
假如我项目里有几个文件也需要相同的操作:
简单安装:
sudo npm install -g jscodeshift
执行:
jscodeshift -t transform.js ./src/demo.js --dry --print
这里用了--dry 和 --print
--dry
加上之后,不会立刻把新生成的代码覆盖源文件
--print
是打印出来看看
在实际项目里, 你需要在独立的分支里
操作,新生成代码之后, 需要你再检查检查
, review没有问题
之后才能合并。
3. 使用AST实现一个Eslint 插件, 禁用console
和上面的类似, 我们也可以做一个eslint 插件, 功能也很简单: 检查到使用console的时候就报错
。
期望达到的效果:
// Do not use console methods (at 1:9) console.log('haha') // --------^
我们这次选择 babel-eslint
模版。
代码实现:
const disallowMethods = ["log", "info", "warn", "error", "dir"]; export default function(context) { return { Identifier(node) { const isConsoleMethod = disallowMethods.includes(node.name) && node.parent.type === "MemberExpression" && node.parent.object.name === "console"; if (!isConsoleMethod) return; context.report({ node, message: "Do not use console methods" }); } }; }
实际效果:
简单有效。
不过你要是非要玩什么骚操作,比如自定义一个log, 那就没得搞了。
最后, 你可以把这段代码封装成一个完整的插件:
你可以自行实践。
4. 使用AST实现一个Babel插件, 过滤debugger
最后一个是过滤源代码中的debugger, Transform 我们选择babelv7
这个插件,我们期望达到的效果是:
var a = 1 debugger function test() { debugger a++ } debugger
到:
var a = 1; function test() { a++; }
这也是一个十分有用的功能。
代码实现:
export default function (babel) { const { types: t } = babel; return { name: "ast-transform", // not required visitor: { DebuggerStatement(path) { path.remove() } } }; }
实际效果:
总结
内容大概就是这么多,没什么难度,重在讲述理论和入门
。
对AST还不熟练的同学, 希望这篇可以帮助到你。
后面还有会AST在我们实际项目中的应用
, 我也会写一个实战篇
, 敬请期待!
以上。
延伸阅读
https://www.toptal.com/javasc...
最后
如果觉得内容有帮助,可以关注下我的公众号 「 前端e进阶 」,一起学习。
这篇关于手把手教你写几个实用的的AST插件的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-09一定要避坑:关于微信H5分享,温馨提示你不要再踩坑了!!!
- 2024-05-09本地项目放到公网访问!炒鸡煎蛋!
- 2024-04-07金融企业区域集中库的设计构想和测试验证
- 2024-03-11前端CSS的工程化——掌握Sass这四大特性就够了
- 2024-02-21h5关联css样式(html怎么和css关联)-icode9专业技术文章分享
- 2024-02-07Firefox禁止远程字体加速网页加载及图标字体补充安装
- 2024-02-07一个菜鸡前端的3年总结-「2023」
- 2024-01-18最火前端Web组态软件(可视化)
- 2024-01-12程序员提效 x10 的必备开源“神器”
- 2024-01-11前端可以监控静态资源的时间吗-icode9专业技术文章分享