mirror of
https://github.com/luzhisheng/js_reverse.git
synced 2025-04-20 03:59:57 +08:00
AST操作之API用法-path路径
This commit is contained in:
parent
a4a2cb5513
commit
b6281e129e
@ -5,10 +5,16 @@
|
|||||||
在`@babel/traverse`模块中,path对象表示一个节点(node)在AST树中的位置,提供了一些属性和方法,
|
在`@babel/traverse`模块中,path对象表示一个节点(node)在AST树中的位置,提供了一些属性和方法,
|
||||||
用于访问节点的属性、子节点、父节点、兄弟节点等,并且可以对AST树进行修改。
|
用于访问节点的属性、子节点、父节点、兄弟节点等,并且可以对AST树进行修改。
|
||||||
|
|
||||||
|
`path`相关的源代码在这个js文件中
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
\node_modules\@babel\traverse\lib\path
|
||||||
|
```
|
||||||
|
|
||||||
**下面是一些常见的 path 对象的 API:**
|
**下面是一些常见的 path 对象的 API:**
|
||||||
|
|
||||||
| api | 功能 |
|
| api | 功能 |
|
||||||
|--------------------------|--------------------------------------------------------------------|
|
|--------------------------------|--------------------------------------------------------------------|
|
||||||
| path.node | 获取当前路径对应的节点。 |
|
| path.node | 获取当前路径对应的节点。 |
|
||||||
| path.parent | 获取当前路径对应节点的父节点。 |
|
| path.parent | 获取当前路径对应节点的父节点。 |
|
||||||
| path.parentPath | 获取当前路径对应节点的父路径。 |
|
| path.parentPath | 获取当前路径对应节点的父路径。 |
|
||||||
@ -20,6 +26,12 @@
|
|||||||
| path.remove() | 从 AST 中移除当前路径对应的节点。 |
|
| path.remove() | 从 AST 中移除当前路径对应的节点。 |
|
||||||
| path.insertBefore(nodes) | 在当前路径对应节点之前插入一个或多个节点。 |
|
| path.insertBefore(nodes) | 在当前路径对应节点之前插入一个或多个节点。 |
|
||||||
| path.insertAfter(nodes) | 在当前路径对应节点之后插入一个或多个节点。 |
|
| path.insertAfter(nodes) | 在当前路径对应节点之后插入一个或多个节点。 |
|
||||||
|
| path.insertAfter(nodes) | 在当前路径对应节点之后插入一个或多个节点。 |
|
||||||
|
| path.scope | 表示当前path下的作用域,这个也是写插件经常会用到的。 |
|
||||||
|
| path.container | 用于获取当前path下的所有兄弟节点(包括自身)。 |
|
||||||
|
| path.type | 获取当前path的节点类型。 |
|
||||||
|
| path.key | 获取当前path的key值,key通常用于path.get函数。 |
|
||||||
|
| path.toString() | 用于将 AST 节点转换回对应的源代码字符串。 |
|
||||||
|
|
||||||
**当前路径所对应的源代码**
|
**当前路径所对应的源代码**
|
||||||
|
|
||||||
@ -36,8 +48,7 @@ let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"});
|
|||||||
let ast = parse(js_code);
|
let ast = parse(js_code);
|
||||||
|
|
||||||
const visitor = {
|
const visitor = {
|
||||||
VariableDeclaration(path)
|
VariableDeclaration(path) {
|
||||||
{
|
|
||||||
console.log(path.toString());
|
console.log(path.toString());
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -60,18 +71,8 @@ var a = 123;
|
|||||||
编写代码
|
编写代码
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const fs = require('fs');
|
|
||||||
const {parse} = require("@babel/parser");
|
|
||||||
const traverse = require("@babel/traverse").default;
|
|
||||||
|
|
||||||
let encode_file = "./encode.js";
|
|
||||||
|
|
||||||
let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"});
|
|
||||||
let ast = parse(js_code);
|
|
||||||
|
|
||||||
const visitor = {
|
const visitor = {
|
||||||
Program(path)
|
Program(path) {
|
||||||
{
|
|
||||||
console.log(path.node.type);
|
console.log(path.node.type);
|
||||||
console.log(path.node.start);
|
console.log(path.node.start);
|
||||||
console.log(path.node.end);
|
console.log(path.node.end);
|
||||||
@ -92,28 +93,64 @@ traverse(ast, visitor);
|
|||||||
Program
|
Program
|
||||||
0
|
0
|
||||||
12
|
12
|
||||||
SourceLocation {
|
SourceLocation
|
||||||
start: Position { line: 1, column: 0, index: 0 },
|
{
|
||||||
end: Position { line: 1, column: 12, index: 12 },
|
start: Position
|
||||||
|
{
|
||||||
|
line: 1, column
|
||||||
|
:
|
||||||
|
0, index
|
||||||
|
:
|
||||||
|
0
|
||||||
|
}
|
||||||
|
,
|
||||||
|
end: Position
|
||||||
|
{
|
||||||
|
line: 1, column
|
||||||
|
:
|
||||||
|
12, index
|
||||||
|
:
|
||||||
|
12
|
||||||
|
}
|
||||||
|
,
|
||||||
filename: undefined,
|
filename: undefined,
|
||||||
identifierName: undefined
|
identifierName
|
||||||
|
:
|
||||||
|
undefined
|
||||||
}
|
}
|
||||||
script
|
script
|
||||||
null
|
null
|
||||||
[
|
[
|
||||||
Node {
|
Node
|
||||||
|
{
|
||||||
type: 'VariableDeclaration',
|
type: 'VariableDeclaration',
|
||||||
start: 0,
|
start
|
||||||
end: 12,
|
:
|
||||||
loc: SourceLocation {
|
0,
|
||||||
|
end
|
||||||
|
:
|
||||||
|
12,
|
||||||
|
loc
|
||||||
|
:
|
||||||
|
SourceLocation
|
||||||
|
{
|
||||||
start: [Position],
|
start: [Position],
|
||||||
end: [Position],
|
end
|
||||||
filename: undefined,
|
:
|
||||||
identifierName: undefined
|
[Position],
|
||||||
},
|
filename
|
||||||
declarations: [ [Node] ],
|
:
|
||||||
kind: 'var'
|
undefined,
|
||||||
|
identifierName
|
||||||
|
:
|
||||||
|
undefined
|
||||||
}
|
}
|
||||||
|
,
|
||||||
|
declarations: [[Node]],
|
||||||
|
kind
|
||||||
|
:
|
||||||
|
'var'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
```
|
```
|
||||||
@ -123,20 +160,9 @@ null
|
|||||||
需求:遍历所有节点,输出节点类型为NumericLiteral的value值
|
需求:遍历所有节点,输出节点类型为NumericLiteral的value值
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const fs = require('fs');
|
|
||||||
const {parse} = require("@babel/parser");
|
|
||||||
const traverse = require("@babel/traverse").default;
|
|
||||||
|
|
||||||
let encode_file = "./encode.js";
|
|
||||||
|
|
||||||
let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"});
|
|
||||||
let ast = parse(js_code);
|
|
||||||
|
|
||||||
const visitor = {
|
const visitor = {
|
||||||
enter(path)
|
enter(path) {
|
||||||
{
|
if (path.isNumericLiteral()) {
|
||||||
if(path.isNumericLiteral())
|
|
||||||
{
|
|
||||||
console.log(path.type);
|
console.log(path.type);
|
||||||
console.log(path.node.value);
|
console.log(path.node.value);
|
||||||
}
|
}
|
||||||
@ -159,22 +185,11 @@ NumericLiteral
|
|||||||
需求:获取上一级路径节点类型
|
需求:获取上一级路径节点类型
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const fs = require('fs');
|
|
||||||
const {parse} = require("@babel/parser");
|
|
||||||
const traverse = require("@babel/traverse").default;
|
|
||||||
|
|
||||||
let encode_file = "./encode.js";
|
|
||||||
|
|
||||||
let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"});
|
|
||||||
let ast = parse(js_code);
|
|
||||||
|
|
||||||
const visitor = {
|
const visitor = {
|
||||||
enter(path)
|
enter(path) {
|
||||||
{
|
if (path.isNumericLiteral()) {
|
||||||
if(path.isNumericLiteral())
|
console.log('当前节点类型:' + path.type);
|
||||||
{
|
console.log('上层节点类型:' + path.parentPath.type);
|
||||||
console.log('当前节点类型:'+path.type);
|
|
||||||
console.log('上层节点类型:'+path.parentPath.type);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -194,20 +209,9 @@ traverse(ast, visitor);
|
|||||||
需求:删除变量值
|
需求:删除变量值
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const fs = require('fs');
|
|
||||||
const {parse} = require("@babel/parser");
|
|
||||||
const traverse = require("@babel/traverse").default;
|
|
||||||
const generator = require("@babel/generator").default;
|
|
||||||
let encode_file = "./encode.js";
|
|
||||||
|
|
||||||
let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"});
|
|
||||||
let ast = parse(js_code);
|
|
||||||
|
|
||||||
const visitor = {
|
const visitor = {
|
||||||
enter(path)
|
enter(path) {
|
||||||
{
|
if (path.isNumericLiteral()) {
|
||||||
if(path.isNumericLiteral())
|
|
||||||
{
|
|
||||||
path.remove()
|
path.remove()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -218,8 +222,10 @@ traverse(ast, visitor);
|
|||||||
// 写入文件
|
// 写入文件
|
||||||
let {code} = generator(ast);
|
let {code} = generator(ast);
|
||||||
console.log(code)
|
console.log(code)
|
||||||
fs.writeFile('decode.js', code, (err) => {});
|
fs.writeFile('decode.js', code, (err) => {
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
打印内容:
|
打印内容:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -266,3 +272,28 @@ var a = 3;
|
|||||||
```
|
```
|
||||||
|
|
||||||
注意点,必须加上`&& path.node.value == 123`判断,否则就是无限循环
|
注意点,必须加上`&& path.node.value == 123`判断,否则就是无限循环
|
||||||
|
|
||||||
|
**获取当前path的key值**
|
||||||
|
|
||||||
|
需求:打印节点VariableDeclarator|BinaryExpression|Identifier的key值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const {parse} = require("@babel/parser");
|
||||||
|
const traverse = require("@babel/traverse").default;
|
||||||
|
|
||||||
|
let js_code = "var a = 1 + 2;";
|
||||||
|
|
||||||
|
let ast = parse(js_code, {
|
||||||
|
sourceType: 'module',
|
||||||
|
});
|
||||||
|
|
||||||
|
const visitor = {
|
||||||
|
"VariableDeclarator|BinaryExpression|Identifier"(path) {
|
||||||
|
console.log(path.key)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
traverse(ast, visitor);
|
||||||
|
```
|
||||||
|
|
||||||
|

|
@ -1 +1 @@
|
|||||||
var a = 3;
|
var a = 123;
|
@ -1,26 +1,16 @@
|
|||||||
const fs = require('fs');
|
|
||||||
const {parse} = require("@babel/parser");
|
const {parse} = require("@babel/parser");
|
||||||
const traverse = require("@babel/traverse").default;
|
const traverse = require("@babel/traverse").default;
|
||||||
const generator = require("@babel/generator").default;
|
|
||||||
let encode_file = "./encode.js";
|
|
||||||
|
|
||||||
let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"});
|
let js_code = "var a = 1 + 2;";
|
||||||
|
|
||||||
let ast = parse(js_code, {
|
let ast = parse(js_code, {
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
});
|
});
|
||||||
|
|
||||||
const visitor = {
|
const visitor = {
|
||||||
enter(path) {
|
"VariableDeclarator|BinaryExpression|Identifier"(path) {
|
||||||
if (path.isNumericLiteral() && path.node.value == 123) {
|
console.log(path.key)
|
||||||
path.replaceWith({type: "NumericLiteral", value: 3});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
traverse(ast, visitor);
|
traverse(ast, visitor);
|
||||||
|
|
||||||
// 写入文件
|
|
||||||
let {code} = generator(ast);
|
|
||||||
console.log(code)
|
|
||||||
fs.writeFile('decode.js', code, (err) => {
|
|
||||||
});
|
|
||||||
|
@ -1 +1 @@
|
|||||||
var a = 123;
|
let jscode = "var a = 1 + 2;";
|
Loading…
x
Reference in New Issue
Block a user