https://astexplorer.net/ 에 들어가서 @babel/parser
로 console.log('abc')에 대해 AST를 만들면 아래와 같다
plugins/remove-log-js
module.exports = function ({ types: t }) {
return {
visitor: {
ExpressionStatement(path) {
if (t.isCallExpression(path.node.expression)) {
if (t.isMemberExpression(path.node.expression.callee)) {
const memberExp = path.node.expression.callee;
if (
memberExp.object.name === "console" &&
memberExp.property.name === "log"
) {
path.remove();
}
}
}
},
},
};
};
위의 AST와 같이 비교해 보면
babel.config.js
const plugins = [
"./plugins/remove-log.js",
];
module.exports = { plugins };
src/consoleCode.js
console.log("aaa");
const v1 = 123;
console.log("bbb");
function onClick(e) {
const v = e.target.value;
}
function add(a, b) {
return a + b;
}
npx babel src/consoleCode.js
결과
const v1 = 123;
function onClick(e) {
const v = e.target.value;
}
function add(a, b) {
return a + b;
}
아래는 function func(p1) {let v1;}의 AST이다
이름이 on으로 시작하는 함수에 console.log('call 함수 이름')을 넣어주는 플러그인을 만들 것이다.
plugins/insert-log-js
module.exports = function ({ types: t }) {
return {
visitor: {
FunctionDeclaration(path) {
if (path.node.id.name.substr(0, 2) === "on") {
path
.get("body")
.unshiftContainer(
"body",
t.expressionStatement(
t.callExpression(
t.memberExpression(
t.identifier("console"),
t.identifier("log")
),
[t.stringLiteral(`call ${path.node.id.name}`)]
)
)
);
}
},
},
};
};
위의 AST와 같이 비교해 보면
babel.config.js
const plugins = [
"./plugins/insert-log.js",
];
module.exports = { plugins };
src/consoleCode.js
const v1 = 123;
function onClick(e) {
const v = e.target.value;
}
function add(a, b) {
return a + b;
}
npx babel src/consoleCode.js
결과
const v1 = 123;
function onClick(e) {
console.log("call onClick");
const v = e.target.value;
}
function add(a, b) {
return a + b;
}
📌 이번에 해본 FunctionDeclaration, ExpressionStatement이외에도 다양한 노드 들이 많기 때문에 필요할떄 마다 공식문서를 보면서 해야 할 것 같다.
참고 : 실전 리액트 프로그래밍
https://babeljs.io/