Babel 설정을 하려고 보니 Transfile이니 Pollyfill이니 하는 용어들이 지속적으로 나왔고 Babel을 더 잘 이해하기 위해서 찾아보다가 정리를 해놔야겠다고 생각이 들었다.
javascript에 있어서 trnafile은 최신 javascript 문법(const, arrow function, ...)을 이해할 수 없는 브라우저가 이해할 수 있도록 변환해주는 것이라고 말할 수 있다. Babel은 이렇게 변환을 해주는 Transfiler이고 이 Babel이 있으면 최신 문법을 사용해서 코딩을 하더라도 똥멍청이 IE도 알아듣게 만들 수 있다.
하지만 Transfile만 한다고 해서 내 코드를 이전 버전의 브라우저가 모두 이해할 수는 없다. Transfile은 문법을 최신으로 변환해 주지만 Object와 Method(Map, Set, Promise, ...)는 변환하지 못하기 때문이다.
Pollyfill은 브라우저가 알아들을 수 없는 Object와 Method를 알아들을 수 있는 Object와 Method로 정의한 코드이다.
예를 들어 다음과 같이 Object 및 Method를 core-js라는 폴리필 라이브러리를 이용하면 이전 버전의 브라우저가 이해할 수 있는 코드로 바꿔준다.
var sym = Symbol();
var promise = Promise.resolve();
var check = arr.includes("yeah!");
console.log(arr[Symbol.iterator]());
⬇
import _getIterator from "@babel/runtime-corejs3/core-js/get-iterator";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
var sym = _Symbol();
var promise = _Promise.resolve();
var check = _includesInstanceProperty(arr).call(arr, "yeah!");
console.log(_getIterator(arr));
현재는 deprecated 방식으로, 커스텀
regenerator runtime
과core-js
가 포함되어 있다.
적용 방식은 매우 쉽다.
먼저, 다음 명령어로 다운로드 받고 webpack.config.js entry에 @babel/pollyfill
을 추가해준다.
npm i -D @babel/pollyfill
// webpack.config.js
module.exports = {
entry: ["@babel/polyfill", "./app/js"],
};
@babel/pollyfil
은 전역 공간에 폴리필을 채워넣기 때문에 전역 공간이 오염 되어 폴리필 충돌이 일어날 수 있고 브라우저에서 필요하지 않은 폴리필까지 넣기 때문에 번들 크기가 커진다.
대상 환경에 필요한 문법 변환 및 폴리필을 세부적으로 관리 할 필요없이 최신 JavaScript를 사용할 수있는 스마트 사전 설정
@babel/pollyfill
이 dprecated
됨에 따라 core-js
를 사용하는 것이 추천된다.
@babel/preset-env
에서 corejs
옵션을 사용하여 버전을 지정할 수 있고 useBuiltIns
옵션으로 어떻게 폴리필을 다룰 것인지 설정한다.
사용 방법은 다음과 같다.
core-js는 버전 3을 쓰기 위해 함께 install 하고 webpack.config.js 파일에서 아래와 같이 설정해 준다.
npm i -D @babel/preset-env core-js @babel/runtime-corejs3
// webpack.config.js
module.exports = {
presets: [['@babel/preset-env', {useBuiltIns: "usage", corejs: 3}]]
};
core-js
를 @babel/preset-env
가 대상 환경이 필요로 하는 특정 모듈로 바꿔준다.// before
import "core-js";
// after
import "core-js/modules/es.string.pad-start";
import "core-js/modules/es.string.pad-end";
// before
var a = new Promise();
// after
import "core-js/modules/es.promise";
var a = new Promise();
이렇게 @babel/preset-env
를 통해서 폴리필을 설정할 수 있고 useBuiltIns: "entry"
옵션을 사용하면 전역 스코프가 오염되지만 useBuiltIns: "usage"
옵션을 사용하면 번들의 크기를 줄일 수 있고 전역 오염을 피할 수 있다.
코드 사이즈를 줄이기 위해 이미 사용한
helper code
를 재사용 할 수있는 플러그인
Babel은 기본적으로 매우 작은 helper code
를 필요한 모든 파일에 추가한다. 애플리케이션이 여러 파일에 분산되어 있는 경우는 중복이 발생한다.
@babel/plugin-transform-runtime
은 이러한 중복을 방지하기 위해 helper code
들이 @babel/runtime
을 참조하여 재사용할 수 있게 해준다.
위에서 install한 것에 추가로 다음을 install 해주고 webpack.config.js를 설정해준다.
npm i -D @babel/plugin-transform-runtime babel/runtime
// webpack.config.js
module.exports = {
presets: [['@babel/preset-env']],
plugins : [["@babel/plugin-transform-runtime",{corejs: 3}]]
};
core-js@3
와 @babel/transform-runtime
를 함께 사용하면 core-js-pure
버전으로부터 폴리필을 주입하는데 core-js-pure
버전은 전역 스코프를 오염시키지 않는다.
단, 외부 모듈이 전역공간에 선언된 최신 객체를 필요로 할 경우 매번 webpack의 include 옵션에 포함시켜줘야 한다는 단점이 있다.(자세한 설명)