Babel

Hoon·2023년 9월 29일
0

FrontEnd

목록 보기
4/7
post-thumbnail

크로스 브라우징 : 브라우져마다 지원하는 환경이 다르기에 해석할 수 있는 언어 또한 다르다. (예를들어 Safari는 최근 몇년전만 해도 Promise.prototype.finally 메소드를 사용 할 수 없었다.)

이러한 크로스 브라우징 을 해결할 수 있는게 바로 트랜스파일러 Babel 이다.
Babel 은 ECMAScript2015 이후 최신 문법으로 작성한 코드를 모든 브라우저에서 동작하도록 호환성을 지켜준다. (ts, jsx, tsx 등도 포함)

  • A라는 소스 코드 파일을 읽어, B라는 소스 코드 파일로 변환시키는 행위를 트랜스파일 이라고한다.

Install

아래의 명령어를 통해 Babel 을 설치해준다.

$ npm install @babel/core @babel/cli
$ yarn add @babel/core @babel/cli
  • @babel/core : 핵심적인 동작이 담겨있는 바벨 코어

  • @bable/cli : 커맨드라인 명령어를 지원하기 위한 바벨 CLI


Babel Test

이제 간단한 테스트를 위해 ES6 문법인 constarrow function 을 사용해 테스트 파일 babel-test.js 를 만들었다.

// babel-test.js
const alert = (msg) => window.alert(msg);

아래의 명령어를 통해 트랜스파일 을 실행해보았더니

$ npx babel babel-test.js

똑같은 결과가 나왔다.


Babel의 동작 3단계

Babel 의 동작은 아래의 3단계로 구분된다.

  • 파싱 (Parsing) : 코드를 읽고 추상 구문 트리 (AST)로 변환하는 단계
  • 변환 (Transforming) : 추상 구문 트리를 변경하는 단계
  • 출력 (Printing) : 변경된 결과물을 출력하는 단계

이 과정에서 사실 BabelParsingPrinting 만 담당하게 되고 TransformingPlugin 이 처리하게된다.

아래는 constvar 로 바꿔주는 간단한 Plugin 을 구현한 예시코드이다.

// my-babel-plugin.js
module.exports = function myBabelplugin() {
  return {
    visitor: {
      VariableDeclaration(path) {
        console.log("VariableDeclaration() kind:", path.node.kind);

        if (path.node.kind === "const") {
          path.node.kind = "var";
        }
      },
    },
  };
};

이제 아래의 명령어를 통해 Plugin 을 적용시켜 다시 트랜스파일 을 실행해보았더니

$ npx babel babel-test.js --plugins './my-babel-plugin.js'

const 키워드가 var 로 잘 바뀐것을 확인 할 수 있다.


Plugins

이해를 위해서 이처럼 Plugin 을 작성해보았지만, 사실 Babel 사용시 Plugins 를 작성하는 일은 거의 드물고, 제공하는 Plugin 들을 사용한다.

아래는 대표적인 BabelPlugin 들이다.

  • @babel/plugin-transform-block-scoping

  • @babel/plugin-transform-arrow-functions

  • @babel/plugin-transform-strict-mode

위의 Plugin 들을 설치해주고 babel 의 설정파일인 babel.config.js 를 만들어준다.

// babel.config.js
module.exports = {
    plugins: [
        "@babel/plugin-transform-block-scoping",
        "@babel/plugin-transform-arrow-functions",
        "@babel/plugin-transform-strict-mode",
    ],
};

이제 npx babel babel-test.js 의 기본 명령어로 실행해도 위의 Plugin 들이 적용되어 use strict, var 로 변환, arrow function 변환 이 적용된 것을 확인할 수 있다.


Preset

preset: Babel 에서 목적에 맞게 여러개의 플러그인을 모아놓은 것 (n개의 plugin이 1개의 preset)

위에서 사용한 3개의 plugin 들로 custom preset 을 만들어보았다.

// my-babel-preset.js
module.exports = function myBabelPreset() {
  return {
    plugins: [
      "@babel/plugin-transform-block-scoping",
      "@babel/plugin-transform-arrow-functions",
      "@babel/plugin-transform-strict-mode",
    ],
  };
};

위에서 만든 presetplugin 과 마찬가지로 babel.config.js 에서 설정해주면 된다.

// babel.config.js
module.exports = {
  presets: ["./my-babel-preset.js"],
}

아래는 Babel 의 대표적인 preset 들이다.

  • preset-env : ECMAScript2015+ 를 변환할 때 사용
  • preset-flow : flow를 변환
  • preset-react : react를 변환
  • preset-typescript : ts를 변환

아래처럼 타겟 브라우저를 설정해줄수도있다. (해당 버전에서 호환되는 코드로 트랜스파일)

module.exports = {
    presets: [
        [
            "@babel/preset-env",
            {
                targets: {
                    chrome: "79",
                  	ie: "11",
                },
            },
        ],
    ],
};

polyfill

만들었던 babel-test.js 의 코드를 아래와 같이 수정한 뒤, babel 을 적용시켜 실행해보면

// babel-test.js
new Promise();

아래와 같이 변화가 없는 결과를 볼 수 있다.

PromiseES6 객체이고, Babel 은 ECMAScript2015+ 에서 SCMAScript5 버전으로 변환할 수 있는 것들만 변환하고, 그렇지 못한 것들은 polyfill 이라는 코드 조각들을 추가해서 해결해야 한다.

// babel.config.js
module.exports = {
    presets: [
        [
            "@babel/preset-env",
            {
                targets: {
                    chrome: "79",
                    ie: "11",
                },
                useBuiltIns: "usage",	// "usage", "entry", "false
                corejs: {
                    version: 3,
                },
            },
        ],
    ],
};
  • useBuiltIns : 어떤 방식으로 polyfill 을 사용할지 설정하는 옵션 (기본 false)
    (설정시에 polyfill package 중 core-js 를 모듈로 가져오며 yarn add core-js@3 명령어를 통해 core-js 를 설치해줘야한다.)

polyfill 설정 후 실행해보면, 아래와 같이 코드조각들을 가져온것을 확인할 수 있다.

profile
개발자 Hoon입니다

0개의 댓글