본문 바로가기
Be Smart/Vue

[Vue] Babel이란?

by 반월하 2021. 8. 10.
728x90

 바벨에 대해서 이야기하기 전에, 먼저 크로스 브라우징(Cross Browsing)에 대해서 설명이 필요하다.

크로스 브라우징은 브라우저나 플랫폼마다 보이는 모습이 다른 경우가 많은데, 이러한 차이를 최소화하여 브라우저, 환경에 영향을 최소한으로 받고 해당 웹 서비스를 사용할 수 있게 최적화를 하는 작업을 말한다.

 

일부 최신 브라우저에서만 동작하는 기능을 그렇지 않은 브라우저에서 구현해야 할 경우, 기능을 단순화 하거나 생략해야 하는 경우가 발생하기도 한다. 프런트엔드 개발자들에게 크로스 브라우징 이슈는 코드의 일관성을 망가트리고 혼란스럽게 만드는 요소중 하나이다.

 

이러한 크로스 브라우징 이슈를 해결하기 위해 생겨난 툴이 바벨이다. ES6+ 버전의 자바스크립트나 타입스크립트, JSX 등 다른 언어로 분류되는 언어들에 대해서도 모든 브라우저에서 동작할 수 있도록 호환성을 지켜준다.

바벨은 이렇게 추상화 수준을 유지한 채로 코드를 변화시키는 트랜스파일러의 역할을 한다.

바벨을 통해 ES6+ 의 자바스크립트 코드는 하위 버전으로 변화되고, 그로 인해 IE나 다른 브라우저에서 동작할 수 있게 만든다.

 

바벨 공식 웹사이트에서는 바벨을 다음과 같이 정의한다.

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. 

바벨은 주로 ECMAScript 2015+ 코드를 현재 및 과거의 브라우저와 같은 환경에서 호환되는 버전으로 변환하는데 주로 사용되는 도구입니다.

 

바벨의 진행 단계


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

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

여기서 바벨은 파싱과 출력을 담당하고 변환은 플러그인이 진행을 하게된다.

바벨 플러그인(plugin)은 바벨이 어떤 코드를 어떻게 변환할 지에 대한 규칙을 나타낸다.

플러그인은 직접 만들어서 커스텀 플러그인을 사용해도 되고, 이미 잘 만들어진 플러그인을 가져다 사용해도 된다.

 

npm 패키지로 제공하는 플러그인을 설치하여 es6의 const, let을 var로 바꾸고, 화살표 함수를 일반 함수로 바꾸고

엄격 모드를 적용하여 ES6+를 ES5로 변환하는 바벨 설정 파일은 다음과 같다.

 

module.exports = {
	plugin: [
    	"@babel/plugin-transform-block-scoping",
        "@babel/plugin-transform-arrow-function",
        "@babel/plugin-transform-strict-mode",
    ]
}

 

이렇게 설정값을 세팅하고 다시 빌드를 하면 다음과 같이 코드가 변한다.

 

// terminal에서 babel로 app.js 빌드

// (before) app.js
const alert = msg => window.alert(msg);


// (after) app.js
"use strict";

var alert = function (msg) {
	return window.alert(msg);
};

 

Preset


플로그인을 매번 일일이 설정하는 것은 번거롭다.

그래서 필요한 플러그인들을 목적에 따라 세트로 묶어놓는 경우가 많다. 이러한 세트를 프리셋(preset)이라고 한다.

프리셋도 마찬가지로 직접 모듈을 만들어서 설정할 수도 있고, 바벨에서 제공하는 프리셋을 가져와서 사용할 수도 있다. 바벨 7 이전에는 연도별 프리셋을 제공했지만 이후 버전에서는 env 하나로 합쳐져서 무척 편리하게 사용할 수 있게 되었다.

 

대표적인 프리셋으로 ES6+를 변환하는 프리셋인 preset-env를 살펴보자. 프리셋 패키지를 설치하고 아래와 같이 바벨 설정 파일을 바꿔준다.

 

module.exports = {
	presets: [
    	'@babel/preset-env'
    ]
}

그러면 위에서 npx babel app.js를 했던 결과와 같은 결과가 나오게 된다.

 

만약에 특정 브라우저 버전 이상을 지원해야 할 경우 바벨 설정 파일에서 targets 속성 값으로 지정해 주면 된다.

예를 들어서 크롬 79 이상, IE 11 이상을 지원해 주는 코드로 변환하고 싶다면 아래와 같이 바벨 설정 파일을 바꾸어 주면 된다.

 

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

 

Polyfill


이번에는 변환과는 조금 다른 폴리필에 대해서 알아보고자 한다.

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

 

ES6에서 비동기 처리를 위해 등장한 Promise 객체는 env 프리셋을 가지고 변환을 하려고 해도 ie에서 인식하지 못한다. 바벨의 경우는 ES6+를 ES5로 변환할 수 있는 것들만 변환을 하는데, Promise와 같이 ES5에서 변환할 수 있는 대상이 없는 경우는 에러가 발생한다. 이러한 경우 우리는 폴리필을 통해서 이슈를 해결할 수 있다. Promise를 ES5로 변환할 수 없지만 ES5 방식으로 구현하여 해결하는 것이다.

 

아래와 같이 바벨 설정 파일을 폴리필을 추가한다. useBuiltIns는 어떤 방식으로 폴리필을 사용할지 설정하는 옵션이고, corejs도 기본값이 2여서 이렇게 명시했다.

 

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

그러고 나서 빌드를 하면 아래와 같다.

 

// 폴리필을 추가하여 빌드
npx babel app.js

// (before) app.js
new Promise();

// (after) app.js
"use strict";

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

new Promise();

corejs 패키지로부터 프로미스 모듈을 가져오는 임포트 구문이 상단에 추가되었다. 이 결과물은 이제 ie에서 정상적으로 돌아간다.

 

 

실무에서는 바벨을 직접 사용하는 경우보다는 웹팩으로 통합해서 사용하는 경우가 더 많다. 

이때 로더 형태로 제공되는 'babel-loader'를 사용한다.

 

'babel-loader'를 설치하고 웹팩 설정 파일을 다음과 같이 작성한다. 모든 js파일을 바벨로 처리할 수 있게 했고, node_modules는 양이 많고 굳이 처리할 필요가 없기 때문에 제외해 주었다.

 

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader', // 바벨 로더를 추가한다 
      },
    ]
  },
}

 

 

 

 

 

 

 

 

728x90

댓글