오늘은 바벨에 대해서 이야기 해 보려고 한다. 바벨이 무엇이며, 왜 필요하고, 기본적인 사용법이 어떻게 되는지 등등에 대해서 설명해 보도록 하겠다.
먼저 크로스 브라우징(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+ 코드를 현재 및 과거의 브라우저와 같은 환경에서 호환되는 버전으로 변환하는데 주로 사용되는 도구입니다.
바벨은 세 단계로 빌드를 진행한다.
- 파싱(Parsing) : 코드를 읽고 추상 구문 트리(AST)로 변환하는 단계
- 변환(Transforming) : 추상 구문 트리를 변경
- 출력(Printing) : 변경된 결과물을 출력
여기서 바벨은 파싱과 출력을 담당하고 변환은 다른 녀석이 진행을 하는데, 그 녀석이 바로 플러그인이다. 바벨 플러그인(plugin)은 바벨이 어떤 코드를 어떻게 변환할 지에 대한 규칙을 나타낸다. 플러그인은 직접 만들어서 커스텀 플러그인을 사용해도 되고, 이미 잘 만들어진 플러그인을 가져다가 써도 된다.
npm 패키지로 제공하는 플러그인을 설치하여 es6의 const, let을 var로 바꾸고, 화살표 함수를 일반 함수로 바꾸고 엄격 모드를 적용하여 ES6+를 ES5로 변환하는 바벨 설정 파일은 다음과 같다.
이렇게 설정값을 세팅하고 다시 빌드를 하면 다음과 같이 코드가 변한다.
여러가지 바벨 플러그인들은 아래의 바벨 공식문서에서 찾아볼 수 있다.
https://babeljs.io/docs/en/plugins
플러그인을 매번 일일이 설정하는 건 정말 번거롭다. 그래서 이렇게 필요한 플러그인들을 목적에 따라 세트로 묶어놓는 경우가 많다. 이러한 세트를 프리셋(preset)이라고 한다. 프리셋도 마찬가지로 직접 모듈을 만들어서 설정할 수도 있고, 바벨에서 제공하는 프리셋을 가져와서 사용할 수도 있다. 바벨 7 이전에는 연도별 프리셋을 제공했지만 이후 버전에서는 env 하나로 합쳐져서 무척 편리하게 사용할 수 있게 되었다.
대표적인 프리셋으로 ES6+를 변환하는 프리셋인 preset-env를 살펴보자. 프리셋 패키지를 설치하고 아래와 같이 바벨 설정 파일을 바꿔준다.
그러면 위에서 npx babel app.js 를 했던 결과와 같은 결과가 나오게 된다.
만약에 특정 브라우저 버전 이상을 지원해야 할 경우 바벨 설정파일에서 targets 속성 값으로 지정해 주면 된다. 예를 들어서 크롬 79 이상, IE 11 이상을 지원해 주는 코드로 변환하고 싶다면 아래와 같이 바벨 설정 파일을 바꾸어 주면 된다.
이번에는 변환과는 조금 다른 폴리필에 대해서 알아보고자 한다. 폴리필(polyfill)은 최신 ECMAScript 환경을 만들기 위해 코드가 실행되는 환경에 존재하지 않는 빌트인, 메소드 등을 추가하는 역할을 한다.
ES6에서 비동기 처리를 위해 등장한 Promise 객체는 env 프리셋을 가지고 변환을 하려고 해도 ie에서 인식하지 못한다. 바벨의 경우는 ES6+를 ES5로 변환할 수 있는 것들만 변환을 하는데, Promise와 같이 ES5에서 변환할 수 있는 대상이 없는 경우는 에러가 발생한다. 이러한 경우 우리는 폴리필을 통해서 이슈를 해결할 수 있다. Promise를 ES5로 변환할 수는 없지만 ES5 방식으로 구현하여 해결하는 것이다.
아래와 같이 바벨 설정 파일에 폴리필을 추가한다. useBuiltIns는 어떤 방식으로 폴리필을 사용할지 설정하는 옵션이고, corejs도 기본값이 2여서 이렇게 명시했다.
그리고 나서 빌드를 하면 아래와 같다.
corejs 패키지로부터 프로미스 모듈을 가져오는 임포트 구문이 상단에 추가되었다. 이 결과물은 이제 ie에서 정상적으로 돌아간다.
실무에서는 바벨을 직접 사용하는 경우보다는 웹팩으로 통합해서 사용하는 경우가 더 많다. 이 때 로더 형태로 제공되는 'babel-loader'를 사용한다.
'babel-loader'를 설치하고 웹팩 설정 파일을 다음과 같이 작성한다. 모든 js 파일을 바벨로 처리할 수 있게 했고, node_modules는 양이 많고 굳이 처리할 필요가 없기 때문에 제외해 주었다.
폴리필을 사용했다면 폴리필도 설치를 해 주어야 한다. 그리고 webpack으로 번들링 된 결과물을 확인하면 코드가 정상적으로 변환이 되었음을 알 수 있다.
참고자료
'Web Frontend Developer' 카테고리의 다른 글
[React] 클래스형 컴포넌트 vs 함수형 컴포넌트 (2) | 2020.07.01 |
---|---|
React와 TypeScript로 간단한 뉴스 어플리케이션 만들기 (feat. redux, redux-saga) (0) | 2020.06.25 |
<FE면접질문> #6. 운영체제 (0) | 2020.06.16 |
Webpack이란 무엇인가? (0) | 2020.06.15 |
<FE면접질문> #5. 자료구조 (1) | 2020.06.04 |