npm install -D @babel/core @babel/cli
- 바벨이 설치되면 node_modules / .bin / babel 이 있는 것을 알 수 있다.
이제 app.js를 만들고 코드를 쳐본다
// app.js
const alert = (msg) => window.alert(msg);
그리고 바벨을 실행시켜본다.
npx babel app.js
app.js에 작성했던 코드가 잘 나오는 것을 알 수 있다.
바벨은 세 단계로 빌드를 진행한다.
- 파싱 (Parsing)
- 코드를 읽고 AST(추상 구문 트리)로 변환하는 단계를 ‘파싱’이라고 한다. 이것은 빌드 작업을 처리하기에 적합한 자료구조인데, 컴파일러 이론에 사용되는 개념이다.
- 변환 (Transforming)
- 추상 구문 트리를 변경하는 것을 ‘변환’ 단계로, 실제 코드를 변경하는 작업을 한다.
- 출력 (Printing)
- 변경된 결과물을 ‘출력’하는 것이 바벨의 마지막 작업 단계이다.
그러나 위 케이스의 경우 app.js에 작성한 코드가 아무런 변환 없이 그대로 출력된 것을 알 수 있다. 즉, 파싱 및 출력 과정은 거쳤지만 변환은 거치지 않은 것으로 보인다.
플러그인
기본적으로 바벨은 코드를 받아서 코드를 반환한다. 만일 바벨 함수를 정의한다면 다음과 같을 것이다.
const babel = code => code;
바벨은 파싱과 출력만 담당하고 변환 작업은 다른 녀석이 처리하는데 이를 플러그인이라고 부른다.
커스텀 플러그인
- myBabelPlugin 파일을 하나 만들어 아래 코드를 복붙한다.
- 아래 플러그인은 변환과정을 거치지 않고, 그저 바벨이 만든 AST 트리의 노드를 출력하는 역할만을 한다.
// my-babel-plugin.js:
module.exports = function myBabelPlugin() {
return {
visitor: {
Identifier(path) {
const name = path.node.name;
// 바벨이 만든 AST 노드를 출력한다
console.log("Identifier() name:", name);
},
},
};
};
- 위 플러그인을 실행하기 위한 명령어를 알고자 babel에 도움을 요청했다
help에서 플러그인을 사용하고자 한다면 babel app.js —plugins “사용할 플러그인” 명령어를 사용하면 된다고 한다.
실행해보자 !
우리가 위 my-babel-plugin에 작성한 코드는 아무런 변환 과정 없이, 그저 AST 트리의 노드를 출력하는 역할만 했다.
이제 변환과정이 있는 플러그인을 실행시켜보자
// my-babel-plugin.js:
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("");
},
},
};
};
Identifier() name으로 출력되는 노드들은 동일한 것을 알 수 있다.
그러나 마지막 줄 출력 결과를 보면 모든 노드들의 문자열이 뒤집힌 것을 알 수 있다.
우리가 하려는 것은 ECMA2015로 작성한 코드를 IE에서 돌리는 것이다. 먼저 const 코드를 var로 변경하는 플러그인을 만들어보자.
// myplugin.js:
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";
}
},
},
};
};
- const가 var로 잘 변경되는 것을 알 수 있다.
그러나
우리가 겨우 코드 한 줄을 변환하기 위해서 작성해야하는 코드가 너무 많다.
우리에겐 babel 플러그인 라이브러리가있으니, 이를 활용해보자
1. NPM 패키지 플러그인 설치
npm install -D @babel/plugin-transform-block-scoping
2. 설치한 플러그인 사용
npx babel app.js --plugins @babel/plugin-transform-block-scoping
- 커스텀 플러그인을 활용했을 때와 동일한 결과를 보인다.
- IE에서는 화살표 함수도 지원하지 않는데, arrow-function 플러그인을 이용해서 일반 함수로 변경할 수 있다.
3. 화살표 함수 플러그인
npm install -D @babel/plugin-transform-arrow-functions
- 화살표 함수가 일반 함수로 변환된 것을 알 수 있다.
- ES6부터는 strictmode를 사용하는 것이 안전하기 때문에 “use strict” 구문을 추가하고자 한다.
- strict-mode 플러그인을 사용하자.
- 그 전에 커멘드라인에 사용해야 할 플러그인이 많아지기 때문에 이를 하나의 파일로 분리할 수 있다.
// babel.config.js
module.exports = {
plugins: [
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-strict-mode",
],
}
babel.config.js를 활용하면 babel을 실행할 때 플러그인을 하나하나 추가해주지 않아도 된다.
- 이렇게 우리는 es6로 되었던 문법을 es5로 다운그레이드 및 IE에서도 안전하게 작동되는 코드로 트랜스파일 하였다.
프리셋
- ES6로 코딩할 때 필요한 플러그인을 일일이 설정하는 일은 굉장히 귀찮다.
- 코드 한 줄을 작성하는데 세 개의 플러그인 세팅을 했기 때문이다.
- 목적에 맞게 여러 플러그인을 세트로 모아놓은 것을 프리셋이라 하고, 이러한 프리셋을 사용하면 편하게 트랜스파일 할 수 있다.
커스텀 프리셋
- 위에서 사용한 세 개 플러그인을 하나의 프리셋으로 만들어보자
module.exports = function mypreset() {
return {
plugins: [
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-strict-mode",
],
};
};
- preset에 플러그인을 묶어뒀으니 babel-config.js를 수정해주어야한다.
module.exports = { presets: ["./mypreset.js"], };
그럼 이렇게 babel 명령어만 입력해도 우리가 의도했던 모든 것이 잘 변환되는 것을 알 수 있다.
프리셋 사용하기
- 이처럼 바벨은 목적에 따라 몇 가지 프리셋을 제공한다.
- preset-env
- ES6 → ES5로 변환할 때 사용
- preset-flow
- flow를 변환
- preset-react
- react를 변환
- preset-typescript
- typescript를 변환
- preset-env
env 프리셋 설정과 폴리필
- 과거에 제공했던 연도별 프리셋에 비해 env 프리셋은 무척 단순하고 직관적인 사용법을 제공한다
타켓 브라우저
- 우리 코드가 최신 크롬버전만 지원한다고 가정하자, 그러면 굳이 IE에 맞는 코드로 변환할 필요 없다. target option에 브라우저 버젼명만 지정하면 env 프리셋은 이에 맞는 플러그인을 찾아 최적의 코드를 출력한다.
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
chrome: "79", // 크롬 79까지 지원하는 코드를 만든다
},
},
],
],
}
- 크롬은 화살표 함수, ES6 문법 모두 지원하기 때문에 코드를 변환하지 않고도 위와 같은 결과를 출력한다.
그렇다면 만일 target에 IE를 넣으면 어떻게 될까?
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
chrome: "79", // 크롬 79까지 지원하는 코드를 만든다
ie: "11", // IE 11까지 지원하는
},
},
],
],
};
- 내가 해준 것은 그저 Target에 ie:11만을 추가했을 뿐인데, 바벨이 알아서 ie에도 적용할 수 있는 es5 문법으로 코드를 변환해주었다.
- 아주 편하다 !
'⚓️ 개발환경' 카테고리의 다른 글
[⚓️Webpack] CRA 없이 웹팩 프로젝트 만들기 | 웹팩의 시대는 끝났나 ? | 웹팩 커스터마이징 (0) | 2025.03.11 |
---|---|
[개발환경] npm, pnpm, yarn let’s go (0) | 2024.09.02 |
[⚓️개발환경] 웹팩이란 무엇인가 (6) | 2024.07.08 |
[⚓️개발환경] 프론트엔드 개발에 Node.js가 필요한 이유 (8) | 2024.06.25 |
[⚓️개발환경] Package.json vs Package-lock.json 그리고 Caret, Tilde 등등.. (4) | 2024.06.25 |