babel

fe_sw·2022년 8월 25일
0

Babel

목록 보기
1/1
post-thumbnail

바벨이란

바벨은 ES6+ 버전 이상의 자바스크립트나 JSX, 타입스크립트 코드를 하위 버전의 자바스크립트 코드로 변환 시켜 IE나 다른 브라우저에서 동작할 수 있도록 하는 역할을 한다.

크로스 브라우징

크로스 브라우징은 브라우저나 플랫폼마다 보여지는 모습이 다른 경우가 많은데, 이러한 차이를 최소화 하여 브라우저, 환경에 영향을 최소한으로 받고 해당 웹 서비스를 사용할 수 있게 최적화를 하는 작업을 말한다. 일부 최신 브라우저에서만 동작하는 기능을 그렇지 않은 브라우저에서 구현해야 할 경우, 기능을 단순화 하거나 생략해야 하는 경우가 발생하기도 한다.

설치

npm install -D @babel/core  @babel/cli

단계

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

파싱(Parsing) : 코드를 읽고 추상 구문 트리(AST)로 변환하는 단계
변환(Transforming) : 추상 구문 트리를 변경하는 것, 실제로 코드를 변경하는 작업을 한다.
출력 (Printing) : 경된 결과물을 "출력"하는 것

플러그인

기본적으로 바벨은 코드를 받아서 코드를 반환한다. 바벨 함수를 정의한다면 이런 모습이 될 것이다.

const babel = code => code

바벨은 파싱과 출력만 담당하고 변환 작업은 플러그인이 처리한다

프리셋

이처럼 바벨은 목적에 따라 몇 가지 프리셋을 제공한다.

  • preset-env
  • preset-flow
  • preset-react
  • preset-typescript

preset-env는 ECMAScript2015+를 변환할 때 사용한다.
preset-flow, preset-react, preset-typescript는 flow, 리액트, 타입스크립트를 변환하기 위한 프리셋이다.

타켓 브라우저

우리 코드가 크롬 최신 버전(2019년 12월 기준)만 지원하다고 하자. 그렇다면 인터넷 익스플로러를 위한 코드 변환은 불필요하다. target 옵션에 브라우져 버전명만 지정하면 env 프리셋은 이에 맞는 플러그인들을 찾아 최적의 코드를 출력해 낸다.

// babel.config.js
module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        targets: {
          chrome: "79", // 크롬 79까지 지원하는 코드를 만든다
        },
      },
    ],
  ],
}
// npx babel app.js

"use strict";
const alert = msg => window.alert(msg);

크롬은 블록 스코핑과 화살표 함수를 지원하기 때문에 코드를 변환하지 않고 이러한 결과물을 만들었다. 만약 인터넷 익스플로러도 지원해야 한다면 바벨 설정에 브라우져 정보만 하나 더 추가하면 된다.

// babel.config.js :
module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        targets: {
          chrome: "79",
          ie: "11", // ie 11까지 지원하는 코드를 만든다
        },
      },
    ],
  ],
}

폴리필

바벨은 ECMAScript2015+를 ECMAScript5 버전으로 변환할 수 있는 것만 빌드한다.
그렇지 못한 것들은 폴리필이 처리한다.

// app.js:
// 바벨로만 처리한 결과
new Promise()

// npx babel app.js

"use strict";
new Promise();


env 프리셋으로 변환을 시도했지만 Promise 그대로 변함이 없다. target에 ie 11을 설정하고 빌드한 것인데 인터넷 익스플로러는 여전히 프라미스를 해석하지 못하고 에러를 던진다.

env 프리셋은 폴리필을 지정할 수 있는 옵션을 제공한다.

// babel.config.js:
module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage", // 폴리필 사용 방식 지정
        corejs: {
          // 폴리필 버전 지정
          version: 2,
        },
      },
    ],
  ],
}

useBuiltIns는 어떤 방식으로 폴리필을 사용할지 설정하는 옵션이다. "usage" , "entry", false 세 가지 값을 사용하는데 기본값이 false 이므로 폴리필이 동작하지 않았던 것이다. 반면 usage나 entry를 설정하면 폴리필 패키지 중 core-js를 모듈로 가져온다(이전에 사용하던 babel/polyfile은 바벨 7.4.0부터 사용하지 않음).

corejs 모듈의 버전도 명시하는데 기본값은 2다. 버전 3과 차이는 확실히 잘 모르겠다. 이럴 땐 그냥 기본값을 사용하는 편이다.자세한 폴리필 옵션은 바벨 문서의 useBuiltIns와 corejs 섹션을 참고하자.

npx babel src/app.js
"use strict";

require("core-js/modules/es6.promise");
require("core-js/modules/es6.object.to-string");

new Promise();

core-js 패키지로부터 프라미스 모듈을 가져오는 임포트 구문이 상단에 추가되었다. 이제야 비로소 인터넷 익스플로러에서 안전하게 돌아가는 결과물을 만들었다.

웹팩으로 통합

실무 환경에서는 바벨을 직접 사용하는 것보다는 웹팩으로 통합해서 사용하는 것이 일반적이다.
babel-loader가 로더 형태로 지원한다.

// 설치
npm install -D babel-loader
// webpack.config.js
// 웹팩 설정에 로더를 추가
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader", // 바벨 로더를 추가한다
      },
    ],
  },
}

.js 확장자로 끝나는 파일은 babel-loader가 처리하도록 설정했다. 사용하는 써드파티 라이브라리가 많을수록 바벨 로더가 느리게 동작할 수 있는데 node_modules 폴더를 로더가 처리하지 않도록 예외 처리했다.

폴리필 사용 설정을 했다면 core-js도 설치해야한다. 웹팩은 바벨 로더가 만든 아래 코드를 만나면 core-js를 찾을 것이기 때문이다.

require("core-js/modules/es6.promise")
require("core-js/modules/es6.object.to-string")
// 설치
npm i core-js@2
// 최종모습
module.exports = {
    presets: [
      [
        "@babel/preset-env", //목적에 맞게 여러가지 플러그인을 세트로모아둔것(let->var , => 함수 변환 등등)
        {
          targets: {
            chrome: "79", //크롬 79까지 지원하는 코드
            ie: "11" //ie11까지 지원하는 코드 // npm i regenerator-runtime 필요함
          },
          useBuiltIns: "usage", // 폴리필 사용 방식 지정 , 플러그인은 es2015+ ->es5 변환할수 있는거만 변환하고,나머지는 폴리필을 통해 해결(예:promsise)
          corejs: {// 폴리필 버전 지정
            version: 2
          }
        }
      ]
    ]
  };

  //npm i @babel/preset-env @babel/cli
  //바벨을 웹팩으로 통합하는 방법 : npm i babel-loader -D
  //웹팩 설정에 로더를 추가
  //async await ->npm i regenerator-runtime

0개의 댓글