작성한 javascript 코드를 지원하지 않는 브라우저를 고려해, 호환가능한 버전으로 트랜스파일링해주는(+ 여러가지) 컴파일러다. code parsing, abstract syntax tree(AST) 생성, AST에 plugin 야무지게 섞어서 새로운 코드 생성의 과정을 거친다.
(AST에 대한 내용은, 여기에서 친절하게 알려주시더라...)
preset은 es6+기능들 중 하위버전으로 구현할 수 있는 코드는 하위버전 구현체로 변환해주는 plugin 덩어리다.
babel은 javascript의 성장세에 맞춰 해마다 preset을 배포했었는데, 몇 년 전부터 preset-env 하나에 담아서 배포하고 있다.
(물론 용도에 따라 preset-react, preset-typescript 등이 있다. 이들은 단순히 하위버전 구현체로 바꿔준다는 개념은 아니다. jsx, typescript parsing 목적으로 사용되는 preset들이다.)
하지만 하위버전으로 구현할 수 있는 것도 한계가 있는지, Promise, Symbol, Generator, Iterator, Map, Set, Object.assign 등 몇몇 기능들은 preset이 변환시켜주지 않는다. 이런 기능들은 polyfill이 런타임 시점에 마저 변환시켜준다.
(왜 런타임인진 잘 모르겠다. 브라우저의 지원여부에 따라 polyfill의 적용범위가 정해지기 때문이라고 추측하고 있다.)
babel의 polyfill로 @babel/polyfill 과 @babel/plugin-transform-runtime이 있는데, 둘 다 regenerator-runtime(Generator 문법)와 core-js(그 외 기타 등등)를 dependencies로 갖는다는 공통점이 있다.
(둘을 사용하지 않고, 직접 regenerator-runtime과 core-js를 직접 import 하는 방법도 있다.)
@babel/polyfill이 deprecated되면서, preset-env에 useBuiltIns옵션이 추가됨.
useBuiltIns: entry
:target에 필요한 모든 polyfill을 추가함.
useBuiltIns: usage
:target에 필요한 polyfill들 중에서, 사용된 코드에 대한 polyfill만 추가함.
@babel/runtime를 참조하도록 코드를 수정함으로서, 중복제거 및 재사용성을 높여 파일 크기를 줄임.core-js3와 함께 사용 시, 전역 스코프를 오염시키지 않으며 @babel/runtime만으론 지원하지 않던 instance 메소드(ex. [1,2,3].includes(3))와 static 메소드(ex. array.includes(something))를 사용할 수 있음.proposal 옵션을 통해 제안단계의 스펙을 사용할 수 있음.