바벨은 자바스크립트 컴파일러이다.
바벨은 현재 환경이나 더 오래된 브라우저 환경에서 ECMAScript2015+(ES6, ES7) 문법들을 사용할수 있도록 변환해주는 역할을 하는 도구이다 .
npm install @babel/core @babel/cli
const alert = (msg) => window.alert(msg);
위의 코드의 const 변수선언과 화살표함수는 ES6 문법이다.
npx babel src/app.js
바벨을 실행해서 app.js의 코드를 컴파일 해보면 변환이 되지 않고 app.js 의 코드 그대로 출력이 된다.
이유가 뭘까 ?
바벨은
이렇게 총 3가지의 단계로 나누어져있다.
파싱은 코드를 추상구문트리(AST)로 변환을 하는 단계이고, 그 후에 실제로 코드를 변환하는 작업이 이루어진다.
하지만 실질적으로 변환작업을 하는것은 바벨이 하는것이 아니라 바벨 플러그인이 그 역할을 하기때문에 출력 단계가 이루어져도 똑같은 코드가 출력되는것이다.
플러그인을 작성함으로써 출력단계를 실행해보자.
밑의 코드는 공식 문서에 있는 예제 코드이다.
module.exports = function myBabelPlugin() {
return {
visitor: {
Identifier(path) {
const name = path.node.name;
// 바벨이 만든 AST 노드를 출력한다
console.log("Identifier() name:", name);
// 변환작업: 코드 문자열을 역순으로 변환한다
path.node.name = name.split("").reverse().join("");
},
},
};
};
커스텀 플러그인을 만들때는 저 visitor라는 객체를 리턴해주어야한다.
visitor 객체는 여러 함수들이 있는데, 공식 문서에 예제로 있는 코드 Identifier라는 함수를 가지고 있고 이 함수는 path라는 인자를 받는다. path에 접근해서 노드 조각에 접근할 수 있도록한다.
실제적으로 const를 ES5에 맞게 var로 변환해보도록 하자.
module.exports = function myBabelPlugin() {
return {
visitor: {
VariableDeclaration(path) {
console.log("VariableDeclaration() kind:", path.node.kind); // const
if (path.node.kind === "const") {
path.node.kind = "var";
}
},
},
};
};
npx babel src/app.js --plugins './my-babel-plugin.js'
위의 플러그인을 실행 시키니 const 로 선언했던 변수가 var로 변환된 걸 볼 수 있다.
이런식으로 변수 지정을 ES5에 맞게 변경해주는 플러그인이 block-scoping 플러그인이다.
npm install --save-dev @babel/plugin-transform-block-scoping
npx babel src/app.js --plugins @babel/plugin-transform-arrow-functions --plugins @babel/plugin-transform-block-scoping
이처럼 arrow-functions 플러그인까지 실행시켰더니 잘 변환되었다.
하지만 이런식으로 플러그인들을 하나하나 추가하다보면 코드량이 상당히 증가한다.
이를 해결하기 위해 webpack.config.js 파일을 설정 해주었던것처럼 babel.config.js 파일을 설정해준다.
module.exports = {
plugins: [
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-strict-mode",
],
};
npx babel src/app.js
위의 플러그인들만 설정해주면 알아서 플러그인들이 다 적용되어서 컴파일이 된다.
하지만 저 코드 한줄을 위해서 config.js 파일을 만들어서 플러그인을 3개나 연결을 해주어야하는게 여간 성가신일이 아닌데,
이를 위해서 미리 여러가지 플러그인을 모아놓은 프리셋을 사용해서 간단하게 설정해줄 수있다.
module.exports = function myBabelPreset() {
return {
plugins: [
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-strict-mode",
],
};
};
module.exports = {
presets: ["./my-babel-preset.js"],
};
이렇게 해도 똑같이 컴파일되어서 출력 된다.