실전 리액트 프로그래밍 개정판 - 이재승 지음 (참고자료)
지난번에 이어서 바벨에 대해서 더 깊이 공부해 보자.
바벨은 문자열로 입력되는 코드를 AST(abstract syntax tree)라는 구조체로 만들어서 처리한다. 플러그인에서는 AST를 기반으로 코드를 변경한다. => 플러그인을 제작하려면 AST의 구조를 알아야 한다.
astexplorer 사이트에서 const v1 = a + b;
코드의 AST를 확인해보자. 바벨은 babylon이라는 파서(parser)를 이용해서 AST를 만든다.
=> astexplorer 사이트의 파서 목록에서 babylon을 선택하면 다음과 같은 결과가 나온다.
"type": "Program"
: AST의 각 노드는 type 속성이 있다."type": "VariableDeclaration"
: 변수 선언은 VariableDeclaration 타입이다."declarations"
: 하나의 문장에서 여러 개의 변수를 선언할 수 있기 때문에 배열로 관리된다."type": "VariableDeclaration"
: 선언된 변수의 타입은 VariableDeclaration이다."type": "Identifier"
: 개발자가 만들어낸 각종 이름은 Identifier 타입으로 만들어 진다."name": "v1
: 실제 코드에 사용된 v1이라는 이름이 보인다."type": "BinaryExpression"
: 사칙연산은 BinaryExpression 타입으로 만들어진다. left, right 속성으로 연산에 사용되는 변수나 값이 들어간다.타입의 종류는 굉장히 많아서 필요할 때마다 문서를 찾거나 하자.
바벨 플러그인은 하나의 자바스크립트 파일로 만들 수 있다. 바벨 플러그인의 기본 구조는 다음과 같다.
module.exports = function({ types: t }) { // (1)
const node = t.BinaryExpression('+', t.Identifier('a'), t.Identifier('b')); // (2)
console.log('isBinaryExpression:', t.isBinaryExpression(node)); // (3)
return {};
};
이제 반환값의 형태를 자세히 살펴보자
module.exports = function({ types: t}) {
return {
visitor: { // (1)
Identifier(path) { // (2)
console.log('Identifier name:', path.node.name);
},
BinaryExpression(path) { // (3)
console.log('BinaryExpression operator:', path.node.operator);
// ...(모든 괄호 닫기)
const v1 = a + b;
코드가 입력되면 이 함수는 세 번 호출된다.const v1 = a + b;
코드가 입력되면 이 함수는 한 번 호출된다.프로젝트 하나를 만들어 보자.
mkdir test-babel-custom-plugin
cd test-babel-custom-plugin
npm init -y
npm install @babel/core @babel/cli
프로젝트 루트에 src 폴더를 만들고 그 밑에 code.js 파일을 만들고 콘솔 로그가 포함된 코드를 작성해 보자.
저 코드에 등장하는 두 개의 콘솔 로그를 제거하는 것을 목표로 해보자.
플러그인을 제작하기 위해서는 콘솔 로그 코드의 AST 구조를 이해해야 한다. console.log('asdf'); 코드의 AST는 다음과 같다.
자 이제 프로젝트 루트에 Plugins 폴더를 만들고 그 밑에 remove-log.js 파일을 만들고, 다음 코드를 입력하자.
모든 조건을 만족하면 AST에서 ExpressionStatement 노드를 제거한다.
우리가 만든 플러그인을 바벨 설정에 추가해 보기 위해 babel.config.js 파일을 만들고 다음 코드를 입력한다.
이제 바벨을 실행해 보자
npx babel src/code.js
목표대로 콘솔 로그가 제거됐다.
이번에는 이름이 on으로 시작하는 모든 함수에 콘솔 로그를 추가해 주는 플러그인을 제작해 보자.
먼저 함수의 AST 구조를 파악해 보자. 다음은 function f1(p1) {let v1;} 코드로 만들어진 AST다.
Plugins 폴더 밑에 insert-log.js 파일을 만들고, 다음 코드를 입력해 보자.
console.log(`call ${함수 이름}`)
; 형태의 코드를 담고 있다.babel.config.js 파일을 수정해서 remove-log.js 플러그인을 insert-log.js 플러그인으로 교체하고 바벨을 실행해 보자.
npx babel src/code.js
의도대로 on으로 시작하는 함수의 최상단에 콘솔 로그를 출력하는 코드가 생성된 것을 확인할 수 있다.