Open onvno opened 4 years ago
jscodeshift相关
使用介绍
jscodeshift issue
How to transform comments in a line
const comment = builders.Line(" Not for translation");
comment.trailing = true;
varDecl.comments = node.comments || [];
varDecl.comments.push(comment);
or
// Put a /* block comment */ immediately after the string literal:
const comment = builders.Block(" Not for translation ");
comment.trailing = true;
stringLiteral.comments = stringLiteral.comments || [];
stringLiteral.comments.push(comment);
jscodeshift一些示例
如何添加comment: https://astexplorer.net/#/nmno5f20v6
如何修改comment: https://astexplorer.net/#/gist/8c7d9f81226bbbdee5d9c7a2468ddaa0/c3d93b44e2bf90e0ff2553ec1c8d85dd2daf807e
如何学习jscodeshift,在issue212热心小哥答疑解惑,还提到如何学习使用这个库:
As far as I know there aren't any great docs. 😕
Some stuff I've done to learn:
I initially got started by reading this tutorial: https://www.toptal.com/javascript/write-code-to-rewrite-your-code AST Explorer is nice for understanding the AST format. You can dig into the AST on the right and see what's there. You might have been able to dig through and find comments there, for example. You can also console.log anything and look at the value and prototype in the Chrome console to get a better sense of what you can do with any particular thing (and autocomplete is helpful). I have the jscodeshift and recast repos on my machine and sometimes dig through them to figure out what functions are there and what I have access to. There are also plenty of examples out there to look at, e.g. https://github.com/facebook/jscodeshift#example-codemods
replace替换,使用了这个简单粗暴的方法:
module.exports = function(file, api, options) {
const j = api.jscodeshift;
const root = j(file.source);
j(root.find(j.ObjectExpression).at(0).get())
.replaceWith(JSON.stringify({foo: 4, bar: '5'}));
return root.toSource();
}
原始:
// Some code ...
const someObj = {
x: {
foo: 3
}
};
// Some code ...
转换后结果
// Some code ...
const someObj = {"foo":4,"bar":"5"};
// Some code ...
一些文章收集:
通过j(p)包裹返回的路径,所包含的属性可查看此链接:https://github.com/benjamn/ast-types#nodepath 一些方法可以用到:
// Replace one node with another node:
var fifth = path.get("elements", 4);
fifth.replace(newNode);
// Now do some stuff that might rearrange the list, and this replacement
// remains safe:
fifth.replace(newerNode);
// Replace the third element in an array with two new nodes:
path.get("elements", 2).replace(
b.identifier("foo"),
b.thisExpression()
);
// Remove a node and its parent if it would leave a redundant AST node:
//e.g. var t = 1, y =2; removing the `t` and `y` declarators results in `var undefined`.
path.prune(); //returns the closest parent `NodePath`.
// Remove a node from a list of nodes:
path.get("elements", 3).replace();
// Add three new nodes to the beginning of a list of nodes:
path.get("elements").unshift(a, b, c);
// Remove and return the first node in a list of nodes:
path.get("elements").shift();
// Push two new nodes onto the end of a list of nodes:
path.get("elements").push(d, e);
// Remove and return the last node in a list of nodes:
path.get("elements").pop();
// Insert a new node before/after the seventh node in a list of nodes:
var seventh = path.get("elements", 6);
seventh.insertBefore(newNode);
seventh.insertAfter(newNode);
// Insert a new element at index 5 in a list of nodes:
path.get("elements").insertAt(5, newNode);
json5-writer:想知道如何完整写如AST,可以参考此源码,同时为了快捷支持json5,做了一个四两拨千斤的处理x={}
json5源码思路 依次读取json,根据语义上的分割截取,截取到的串进行存储。 存储后清空临时变量。 在过程中,会反复根据当前片段状态,更改下阶段的属性。
项目中需要做一次校验处理,要对JSON做些小动作,开始了对AST的了解。 类似的需求如这个问题:fs 如何读取 js 模块的注释,从论坛回复得到了一些不错的启发。
recast
这个利器。在简单测试,发现
recast
对单行注释可以拿到,反倒是esprima
这里会有问题