본문 바로가기
Babel

Babel

by 양털의매력 2020. 3. 15.

바벨의 공식문서에 따르면 다음과 같이 나와있다.

 

Babel is a JavaScript compiler
Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.

 

바벨이란 자바스크립트 표준인 ECMA 2015+/ES6+의 최신 문법으로 작성된 코드를 이전 단계의 문법(ES5)으로 변환시켜주는 자바스크립트 컴파일러이다. (소스를 소스로 바꿔주어 트랜스파일러라고도 부른다)

 

이러한 트랜스파일러가 필요한 이유는 구형 브라우저 (ex. IE 등)에서는 ES6+ 구문이 호환이 되지 않기 때문에 구형 브라우저에서도 자바스크립트를 작동시키기 위해서는 ES5로 변환이 필요하다. 바로 이때 바벨이 사용되는 것이다.

 

바벨을 활용하면 웹 브라우저간 호환 걱정 없이 최신 문법으로 자유롭게 코딩할 수 있다.

 

 

그러면 지금부터 바벨에 대한 실습을 하면서 바벨을 어떻게 활용하는지, 구성요소가 어떠한 기능을 하는지 알아보려고 한다.

 


먼저 바벨 연습 프로젝트를 만들어준다.

$ mkdir babel_tutorial
$ cd babel_tutorial
$ npm init -y

그리고 ES6+ 문법으로 작성된 예제파일을 하나 만들어 준다.

 

// es6.js

const hello = "world";

const temp = () => {
  console.log(`hello ${hello}`);
};

temp().then(() => console.log(hello));

const, async, 템플릿리터럴, promise에 대해서 작성하였고 이것을 바벨을 통해 트랜스파일을 해볼것이다.

 

우선 바벨을 설치한다. (개발의존성으로 설치, 빌드시에만 필요하기 때문)

 

$ npm i -D @babel/core @babel/cli

@babel/core : 바벨의 핵심파일로 바벨을 사용하기위한 핵심 모듈

@babel/cli : 터미널에서 바벨을 사용하기위한 패키지

 

그 다음에 바벨을 실행시켜보겠다.

 

$ npx babel es6.js --out-file es5.js

이렇게 하고 es5.js를 보면 코드가 es6와 똑같이 나온다. 바벨이 코드를 어떻게 바꿔줄지 설정을 하지 않았기 때문이다. 따라서 다음에 나올 plugin 또는 preset 설정이 필요하다.


Plugin

바벨의 플러그인은 바벨이 어떤 코드를 어떻게 변환할지에 대한 규칙을 나타낸다. 플러그인을 통하여 바벨이 코드를 변환시켜주는 것이다.  플러그인을 통해 바벨이 어떻게 코드를 변환시키는지 알아보겠다.

 

먼저 위에 나온 것 중에 temp라는 함수에는 arrow-function과 template-literals가 쓰였다. 이것을 변환시켜주는 플러그인을 설치한다. (공식문서에 plugins부분을 보면 플러그인들에 대해서 알 수 있다 https://babeljs.io/docs/en/plugins)

 

$ npm install --save-dev @babel/plugin-transform-arrow-functions @babel/plugin-transform-template-literals

그 다음 다음과 같이 다시 바벨을 실행시킨다.

 

 

$ npx babel es6.js --out-file es5.js --plugins @babel/plugin-transform-template-literals --plugins @babel/plugin-transform-arrow-functions

 

그리고 es5.js를 보면 다음과 같이 temp함수에서 화살표함수와 템플릿리터럴이 es5에 맞게 바뀐것을 알 수 있다.

 

 

하지만 매번 cli에 직접 플러그인을 실행시키는 것은 비효율적이다. 그래서 보통 사용하는 방법은 babel 설정 파일로 플러그인을 설정해주는 것이다.

 

프로젝트 루트에 .babelrc를 추가해준다.

 

{
  "plugins": [
    "@babel/plugin-transform-arrow-functions",
    "@babel/plugin-transform-template-literals"
  ]
}

그리고 다시 다음과 같이 실행해주면 아까랑 똑같이 es5.js가 만들어지는 것을 확인할 수 있다.

 

$ npx babel es6.js --out-file es5.js

 

Preset

preset은 위의 플러그인을 한데 모아놓은 것이다. es6를 플러그인을 하나하나 설치해서 하는 것은 특정한 사항이 아니면 귀찮은 일이다. 그렇기 때문에 preset을 통하여 한번에 여러 규칙을 한번에 적용한다.

 

바벨의 공식 preset은 다음과 같다 (공식문서)

- @babel/preset-env : 가장 범용적인 preset으로 ES6 이상으로 작성된 모든 문법을 ES5로 바꾸어 준다.
- @babel/preset-flow : flow 변환
- @babel/preset-react : react 변환
- @babel/preset-typescript : typscript 변환

 

공식 preset말고도 많은 비공식 preset이 있다. 그럼 preset-env를 설치하여 적용해보겠다.

 

$ npm install --save-dev @babel/preset-env

preset을 받고 .babelrc 를 다음과 같이 수정한다.

 

{
  "plugins": [],
  "presets": ["@babel/preset-env"]
}

그리고 다시 바벨을 실행시키면 이번에는 temp함수 뿐만아니라 다른 것들도 전부 바뀐 것을 알 수 있다.

(ES6에서는 use strict가 defalt이기 때문에 변환 시 use strict 모드!)

 

 

preset-env는 모든 es6 플러그인을 제공하기 때문에 오래된 브라우저의 경우, 번들이 엄청 커져버릴 수도 있다. 

그래서 옵션을 통하여 원하는 브라우저만 지원하도록 플러그인을 명시할 수 있다.

Polyfill

Babel 폴리필은 최신 ECMAScript 환경을 만들기 위해 코드가 실행되는 환경에 존재하지 않는 빌트인, 메소드 등을 추가한다.

즉, 기존의 ES5에 없었던 문법인데 ES6 이후에 새로 생겨난 문법 (예를들어, promise나 Array.prototype.includes) 같은 것을 추가해준다.

 

바벨 폴리필은 실행환경에서 이러한 빌트인, 메소드 등이 있는지 확인하고 존재하지않으면 추가한다.

(플러그인과 프리셋은 빌드 할 때, 폴리필은 런타임 시에 동작한다!!)

 

참고로 @babel/polyfill은 바벨 7.4부터 deprecated 되었다. 그대신 preset-env에서 폴리필을 지정할 수 있는 옵션을 제공한다. 

 

es6.js에 promise와 includes를 추가하고 바벨을 실행시켜 보았다.

 

const hello = "world";

const temp = () => {
  console.log(`hello ${hello}`);
};

temp().then(() => console.log(hello));

new Promise();

[].includes(hello);

결과는 다음과 같다.

 

바뀌거나 하지않고 그대로 반영된 것을 알 수있다. 이대로 구형브라우저 등에서 사용하면 아마 에러가 나올 것이다.

 

.babelrc에 preset-env에 다음과 같은 옵션을 추가하고 다시 바벨을 실행시켜보았다.

 

{
  "plugins": [],
  "presets": [
    [
      "@babel/preset-env"
      {
        "useBuiltIns": "usage",
        "corejs": {
          "version": 2
        }
      }
    ]
  ]
}

 

useBuiltIns 옵션을 통해 폴리필을 설정해 줄 수 있는데 다음의 3가지 옵션이 있다.

- usage : 실제 소스코드에 필요한 폴리필만 추가시킨다.

- entry :  지정된 환경(브라우저)에 필요한 폴리필은 전부 포함시킨다.

- false :  defalt 값 (그래서 폴리필이 추가가 되지않았던 것)

 

entry로 지정하면, 번들 사이즈가 너무 커지기 때문에 usage로 필요한 것만 추가시키는게 좋을 것 같다. 옵션을 지정하고 corejs의 버젼을 지정해준다. 이렇게 해주면 core-js에서 소스코드에 필요한 것만 가져오게 된다. 

 

이렇게 하고 바벨을 실행시켜준 결과는 다음과 같다.

 

core-js에서 모듈을 가져오는 부분이 추가된 것을 알 수 있다.


정리하자면 babel은 최신 자바스크립트 문법을 구형 브라우저에서 사용할 수 있도록 변환시켜주는 자바스크립트 컴파일러이고, plugin을 통해 babel 컴파일 규칙을 추가할 수 있다. 그리고 이러한 plugin을 모아둔 것이 preset이다.

 

preset-env의 옵션을 사용하여 지원하고자 하는 환경에 따라 필요한 플러그인도 명시할수 있다.

 

polyfill을 이용하면 런타임 시에 필요한 빌트인이나 메소드를 추가할 수 있고, preset-env설정을 통하여 필요한 폴리필만 불러와 번들 사이즈가 엄청 커지는 것을 막을 수 있다.

 

그동안 CRA나 CRNA를 통해 프로젝트를 만들때 babel을 많이 봐왔는데 babel이 무엇인지, 어떤 기능을 하는지 잘 모르고 있었다.

 

하지만 이번 babel에 대한 예제를 해보면서 babel에 대한 전반적인 감을 잡을 수 있었던 것 같다. 나중에 CRA가 아닌 직접 리액트 개발환경을 셋팅할 예정인데 많은 도움이 될 것 같다.

 

보통 웹 프로젝트에서 babel과 항상 같이 사용되는 것이 있는데 바로 webpack이다.

 

다음에는 webpack에 대해서 공부해봐야겠다.

 

아래는 참고한 레퍼런스 입니다.

https://velog.io/@pop8682/%EB%B2%88%EC%97%AD-%EC%99%9C-babel-preset%EC%9D%B4-%ED%95%84%EC%9A%94%ED%95%98%EA%B3%A0-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80-yhk03drm7q

https://babeljs.io/

https://yunzema.tistory.com/281

https://ahnheejong.name/articles/frontend-birds-eye-view-babel/

https://blog.cometkim.kr/posts/start-modern-javascript-with-babel/

http://jeonghwan-kim.github.io/series/2019/12/22/frontend-dev-env-babel.html

https://avengersrhydon1121.tistory.com/225

https://www.daleseo.com/js-babel/

댓글