[⚓️개발환경] 바벨이란 무엇인가?

2024. 8. 12. 09:25·⚓️ 개발환경
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에 작성했던 코드가 잘 나오는 것을 알 수 있다.

바벨은 세 단계로 빌드를 진행한다.

  1. 파싱 (Parsing)
    1. 코드를 읽고 AST(추상 구문 트리)로 변환하는 단계를 ‘파싱’이라고 한다. 이것은 빌드 작업을 처리하기에 적합한 자료구조인데, 컴파일러 이론에 사용되는 개념이다.
  2. 변환 (Transforming)
    1. 추상 구문 트리를 변경하는 것을 ‘변환’ 단계로, 실제 코드를 변경하는 작업을 한다.
  3. 출력 (Printing)
    1. 변경된 결과물을 ‘출력’하는 것이 바벨의 마지막 작업 단계이다.

그러나 위 케이스의 경우 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를 변환

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
'⚓️ 개발환경' 카테고리의 다른 글
  • [⚓️Webpack] CRA 없이 웹팩 프로젝트 만들기 | 웹팩의 시대는 끝났나 ? | 웹팩 커스터마이징
  • [개발환경] npm, pnpm, yarn let’s go
  • [⚓️개발환경] 웹팩이란 무엇인가
  • [⚓️개발환경] 프론트엔드 개발에 Node.js가 필요한 이유
이효린
이효린
  • 이효린
    나는 이효린
    이효린
  • 전체
    오늘
    어제
    • 분류 전체보기 (40)
      • 🩵 React (14)
      • 💛 Javascript (3)
      • ⚓️ 개발환경 (9)
      • ⛓️‍💥 알고리즘 (0)
      • 🤍 ReactNative (1)
      • 🔥 취준일기 (2)
      • 🗂️ 자료구조&알고리즘 (2)
      • 기타 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    React
    MSW
    -
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
이효린
[⚓️개발환경] 바벨이란 무엇인가?
상단으로

티스토리툴바