合并Literal类型的计算表达式
将如下示例代码进行合并
1
| var a = !![], b = 'Hey ' + 'Rach' + '!',c = 8 + 3 * 40,d = Math.abs(-911) % 19,e = true ? 996:250;
|
使用babel库中的evaluate方法
源代码路径
1
| node_modules/@babel/traverse/lib/path/evaluation.js
|
查看 AST-Tree
发现这五个变量的初始化节点类型有三种 UnaryExpression, BinaryExpression, ConditionalExpression
然后通过代码遍历查看结果
优先顶层遍历
1 2 3 4 5 6 7
| const vistor = { "UnaryExpression|BinaryExpression|ConditionalExpression"(path){ const {value} = path.evaluate(); console.log(path.toString(), value); } }
|
查看结果
这里出现了结果,但是遍历是从顶层开始的
优先底层遍历
1 2 3 4 5 6 7 8 9
| const vistor = { "UnaryExpression|BinaryExpression|ConditionalExpression":{ exit: function(path){ const {value} = path.evaluate(); console.log(path.toString(), value) } } }
|
查看结果
enter:默认值,顶层优先
exit:底层优先
通用完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| const parser = require("@babel/parser")
const traverse = require("@babel/traverse").default
const t = require("@babel/types")
const generator = require("@babel/generator").default
var jscode = "var a = !![], b = 'Hey ' + 'Rach' + '!',c = 8 + 3 * 40,d = Math.abs(-911) % 19,e = true ? 996:250;";
function PathToLiteral(path, value){ switch (typeof value) { case "boolean": path.replaceWith(t.BooleanLiteral(value)); break; case "string": path.replaceWith(t.StringLiteral(value)); break; case "number": path.replaceWith(t.NumericLiteral(value)); break; default: break; } }
function do_replace(path){ const {value} = path.evaluate(); PathToLiteral(path, value); }
const vistor = { "UnaryExpression|BinaryExpression|ConditionalExpression":{ enter: [do_replace] } }
const ast = parser.parse(jscode); traverse(ast, vistor)
let {code} = generator(ast) console.log(code)
|
查看结果
总结
尽量多阅读源码,应有尽有。