대가는 결과를 만든다

[정리] babel 전반적 개념 본문

개발/Web관련

[정리] babel 전반적 개념

yunzema 2019. 12. 16. 15:44
반응형

최근 frontend 개발 패키지 중 Babel은 필수라고해도 과언이 아니다. 이 Babel에 대한 개념을 정확히 정리하고자 한다.

 

Babel이란?

최신 버전의 자바스크립트 코드를(ECMA 2015+/ES6 코드를) ES5 환경에서 동작하도록 컴파일하는 자바스크립트 컴파일러이다. (트랜스파일러라고 칭하기도 함.) 여기서 말하는 ES5 환경이란 즉 현재나 이전 브라우저 환경을 의미한다.

 

* ECMA자바스크립트 버전에 대한 내용 정리는 다른 글에서 하겠다.

 

babel의 주요 역할을 열거하자면, 

  • 문법의 변형
  • 타겟 환경에서 누락되어있는 부분을 보충하는 Polyfill 기능 (런타임에서 보충)
  • 소스코드의 변형 (codemods)
  • 기타 등등(여기서 비디오로 확인하라고 함 : https://babeljs.io/videos.html )

Plugin

Babel Plugin은 babel이 어떤 코드를 어떻게 판단할지에 대한 규칙을 나타낸다. Babel이 소스코드를 ES5로 변환하는 과정은 다음과 같다.

1. parsing : 구문 분석, 소스 코드를 읽어 추상 구문 트리(AST)로 변환하는 단계

2. transformation : 변환, 정해진 규칙대로 추상 구문 트리(AST)에 변형을 가하는 단계

3. printing : 출력, 변형이 가해진 추상구문 트리(AST)를 다시 코드로 출력

 

Babel이 위에서 말한 실제 역할을 하기 위해선 transformation 단계에서 사용할 변환 규칙이 필요하다. Babel Plugin이 바로 이 규칙의 역할을 한다. "이런 조건이면 이렇게 해석하고 변환해라"라고 하는 규칙을 담고 있다.

 

- 변환 플러그인 (@babel/plugin-transform-....) : 특정 표현/문법이 나타나면 특정 방식으로 변환하도록 함

- 문법 플러그인 (@babel/plugin-syntax-....) : 특정 표현/문법을 이해(파싱)할 수 있게 한다.

 

babel plugins : https://babeljs.io/docs/en/plugins

개별적인 플러그인들을 사용할 수 있지만, 아래 설명하게될 플러그인들의 묶음인 preset을 이용할 수도 있다.

 

Preset

Babel Plugin들의 모음이다. 함께 자주 쓰이는 특정 플러그인들의 조합을 묶음으로 만들어 논 것이다.

preset-typescriptpreset-minifypreset-react등의 babel 공식 지원 프리셋들도 있고, 커뮤니티 기반 프리셋들도 존재한다.

- 참고 npm 검색 결과 : https://www.npmjs.com/search?q=babel-preset

 

preset-env ?

필요한 플러그인을 프로젝트가 지원하고자 하는 환경에 기반해 빌드 타임에 동적으로 결정하는 특별한 프리셋이다.

이미 모아진 플러그인들의 정적 묶음인 프리셋과는 구별된다.

 

preset-env를 사용하고자 한다면, browserslist로 설정 형식을 명시할 수 있고, 여기에 명시된 환경에 필요한 플러그인들을 compat-table의 정보를 활용해 결정해 빌드과정에 포함시킨다.

- preset-env 공식문서 참고 : https://babeljs.io/docs/en/babel-preset-env.html

 

대부분의 경우 .browserslistrc 파일로 target 환경을 명시한다.

 

Polyfill

최신 ECMAScript 환경을 만들기 위해 코드가 실행되는 환경에 존재하지 않는 builtIn/method 등을 구현하여 추가 되는 것을 babel polyfill이라 한다.

Babel로 ECMAScript 명세에 도입된 문법을 ES5 문법으로 트랜스파일링/컴파일링할 수 있지만, 새 스펙에 추가된 builtIn, prototype.method 등의 추가는 babel의 역할이 아니기 때문에 필요하다.

 

예를 들어, ES5 이후 추가된 Promise같은 builtIn이나 Array.prototype.includes 등의 메소드가 코드에 있다면, 지원하지 않는 환경에서는 에러가 날 수 밖에 없다.

 

Babel polyfill은 실행환경에서 이런 builtIn, method등이 존재하는지 확인하고 추가한다. 앞서 말했던 plugin, preset은 빌드 타임 동작에 대한 설정이라면, polyfill은 런타임에 동작한다.

 

babel polyfill은 내부적으로 core-js에 의존한다.

 

- preset-env와의 사용 : babel polyfill 전체를 빌드에 포함하면 번들 사이즈가 너무 커진다. preset-env의 useBuiltIns 옵션을 사용하면 빌드 타임에 babel-polyfill 임포트를 꼭 필요한 폴리필 임포트로 대체해 번들이 필요 이상으로 커지는 것을 방지할 수 있다.

 

 

Outro

babel의 전반적인 개념만 정리했다.

three.js의 objloader에서 obj파일을 파싱하는데에 이 polyfill 포함 여부에 따라, 파싱속도가 엄청나게 차이났었던 경험이 있다. preset-env에서의 useBuiltIns 설정, 그에 따른 polyfill 적용 여부를 한번 정리할 필요가 있겠다. 복잡....

 

 

browserslist 참고 : https://github.com/browserslist/browserslist#queries

 

browserslist/browserslist

🦔 Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-preset-env - browserslist/browserslist

github.com

@babel/preset-env 참고 : https://babeljs.io/docs/en/babel-preset-env.html

 

Babel · The compiler for next generation JavaScript

The compiler for next generation JavaScript

babeljs.io

vu-cli browser compatibility 참고 : https://cli.vuejs.org/guide/browser-compatibility.html#browserslist

 

Browser Compatibility | Vue CLI

Browser Compatibility browserslist You will notice a browserslist field in package.json (or a separate .browserslistrc file) specifying a range of browsers the project is targeting. This value will be used by @babel/preset-env and autoprefixer to automatic

cli.vuejs.org

글 참고 : https://ahnheejong.name/articles/frontend-birds-eye-view-babel/

 

프론트엔드 기술 조감도 : Babel

자바스크립트 컴파일러 Babel과 관련된 플러그인, 프리셋, 폴리필 등의 개념에 대해 소개합니다.

ahnheejong.name

 

Comments