자바스크립트는 ES2015에서 class 문법과 화살표 함수, 모듈 기능을 지원했다. 또한 async, optional 연산자, nullish 병합 연산자등의 다양한 문법이 추가되고 있다.
크롬, 사파리, 파이어폭스와 같은 모던 브라우저들은 이러한 최신 ECMAScript 명세를 꾸준히 반영하고 있다. 하지만 IE11와 같은 구형 브라우저들은 더 이상 업데이트가 이루어지지 않기 때문에, 신규명세에 대한 반영이 되지 않는다.
모던 브라우저도 브라우저마다 ECMAScript의 명세 구현율이 조금씩 다르기 때문에 어떤 브라우저에서든 애플리케이션의 일관성 있는 실행을 위한 환경을 구축하는 것이 필요하다. 이러한 환경을 만들때 사용하는것이 트랜스파일러이다.
1) Babel
Babel은 최신 명세(또는 ES2015 이상)의 문법을 구형 브라우저에서도 동작하는 코드로 트랜스파일 해주는 개발 도구이다. 만약 구형 브라우저의 지원이 필요한 프런트엔드 프로젝트라면 Babel의 사용은 필수적인 요소이다. Babel과 같은 트랜스파일러를 사용하지 않는다면, 구형 브라우저를 위한 코드를 별도로 작성해야 하고 ES2015 이상의 유용한 문법들을 사용할 수 없다.
이는 굉장히 비효율적인 작업이며, 개발 생산성을 떨어뜨리나. 반면, 트랜스파일러는 브라우저 지원 범위에 맞게 코드를 변환해주기 때문에 애플리케이션의 일관성 있는 동작을 기대할 수 있고, 개발 생산성도 크게 향상된다.
const a = () => console.log('transpiled!');
위와 같은 코드는 IE와 같은 구형 브라우저에서는 지원하지 않으므로 제대로 동작하지 않는다.
Babel을 사용하여 ES5 이하의 코드로 변환해 보자.
"use strict";
var a = function a(){
return console.log('transplied');
}
2)Babel의 설치
Babel은 개발환경에서만 필요한 패키지 이므로 -D 옵션을 추가하여 devDependencies에 설치한다. 자주 사용하는 명령어는 package.json에 스크립트를 등록하여 사용하는 것이 효율적이다.
$ npm install -D @babel/cli @babel/core @babel/preset-env
3) Babel의 설정 파일
Babel을 사용하여 원하는 방식대로 트랜스파일하려면 별도의 설정이 필요하다.
{
"presets" : [[@babel/preset-env",{
"useBuiltIns" : "usage",
"corejs" : 3
}]]
}
4) 자주 사용하는 설정 옵션
(1) plugins
{
"plugins" : [
"@babel/plugin-proposal-class-properties"
]
}
(2) presets
(3) extends
// src/A/babel.config.json
{
"presets" : ["@babel/preset-env"],
"plugins" : [
"@babel/plugin-proposal-class-properties"
]
}
// src/B/babel.config.json
{
"extends" : "../A/babel.config.json",
"plugins" : [
"@babel/plugin-proposal-private-property-in-object"
]
}
(4) env
(5) overrides
{
"presets" : ["@babel/preset-env"]
"overrides" : [
{
"includes: "./A",
"excludes: "./A/exclude.js",
"plugins" : ["@babel/plugin-proposal-private-property-in-object"]
}
]
}
Babel의 변환 작업은 런타임이 아닌 빌드 타임에 번들러와 같은 도구를 사용하여 실행된다. 반면 폴리필은 Promise, Map 처럼 트랜스파일만으로 해결할 수 없는 명세를 구현한 것이다. 이러한 폴리필 코드를 IE와 같은 구형 브라우저에 런타임 시 주입하여 해당 명세가 구현된 것처럼 사용할 수 있다.
구형 브라우저 지원을 위해 Promise와 fetch API에 대한 폴리필을 주입해야 한다.
Promise 폴리필 주입을 위해 core-js 패키지를 설치하고, 실제 프로덕션에서도 사용하기 때문에 dependencies로 설치한다.
$ npm install core-js
{
"presets" : [["@babel/preset-env",{
"useBulitIns : "usage",
"corejs" : 3
}]]
}
useBuiltIns 옵션을 'usage'로 설정하게 된다면, 파일에서 필요한 폴리필을 Babel에서 자동으로 주입한다. corejs 옵션은 사용할 core.js 패키지의 버전을 지정한다.
$ npm install whatwg-fetch
"scripts" : {
"my-script" : "node ./myScript.js",
"serve" : "webpack serve",
"build:dev" : "webpack --config webpack.config.js --mode=development"
"build:prod" : "webpack --config webpack.config.js --mode=production"
"transpile" : "babel src/js -d transpile"
},
transpile 스크립트 실행시 src/js 하위에 있는 파일들이 변환되어 transpile 폴더 하위에 생성