[10분 테코톡] Babel

흑우·2023년 12월 1일

10분 테코톡 - 5기

목록 보기
8/16

Babel이란?

  • 구형 브라우저나 환경에서 ES6+ 문법을 사용하기 위해 이전 버전의 자바스크립트 문법으로 변환해주는 도구

ES6 기준 (2015.06 출시)

  • 브라우저들은 ES6를 지원하기 위해서 약 1년에서 2년정도의 기간이 걸렸습니다.
  • 그렇다면 웹 개발자들은 이 기간동안 ES6 문법들을 사용하지 못했을까요?
    • 그렇지 않습니다! => Babel을 통해 ES6+를 이전 문법으로 다운그레드 해줘서 사용해줬습니다.

Babel 사용법

간단한 예시: 화살표 함수 transpiling

const fn = () => "바벨은 대단해"
  • 다음 코드를 transpiling 하기 위해서는 3가지 도구가 필요합니다.
    • @babel/core: 바벨의 핵심적인 기능
    • @babel/cli: 터미널로 바벨을 사용
    • @babel/plugin-transform-arrow-functions: 화살표 함수를 transform하는 플러그인
./node_modules/.bin/babel [변경할 파일] --out-dir [변환될 위치] --plugins=@babel/plugin-transform-arrow-functions
  • 이런식으로 명령어를 입력하게되면 아래와 같은 형식으로 transform됩니다.
var fn = function fn(){
	return "바벨은 대단해"
}
  • 하지만 ES6+에는 많은 기능들이 추가되었는 데 이러한 기능을 transform할 때마다 이런 플러그인들을 하나하나 설치해야할까요? 또 매번 복잡한 명령어를 입력해야 할까요?
    • 아니요? 보통은 babel.config.json이라는 설정 파일과 Preset을 활용합니다.
    • 설정 파일에는 config와 rc 파일이 있습니다.

babel.config.json

{
  "presets": [
  	"@babel/preset-env",
    {
    	"targets":{
        	"edge": "17",
          	"firefox": "60",
          	"chrome": "67",
          	"safari": "11.1"
        },
      	"useBuiltIns": "usage",
      	"corejs": "3.6.5"
    }
  ]
}
  • preset은 다양한 플러그인을 모아놓은 집합 같은 개념
  • preset을 활용하여 별도의 플러그인을 설치하지 않고 transpiling 진행 가능

Polyfill

  • Polyfill은 충전솜이라는 뜻을 가지고 있는데요.
  • 구형 브라우저에서 지원하지 않는 최신 기능을 지원하고자 가져오는 코드 뭉치
  • Babel은 Preset과 Plugin을 통해서 트랜스파일링을 진행합니다.
  • 트랜스파일링을 진행해도 모든 코드가 다 변하는 것이 아니라 Promise와 Array.prototype.incolues 같은 인스턴스 메서드들은 트랜스파일링이 진행되어도 그대로 남아있습니다.
  • 이럴때 필요한 게 Polyfill입니다. Polyfill은 런타임 환경에서 위와 같은 코드가 존재하지 않는다면 해당 코드를 추가해줍니다. => 부족한 부분을 채워주는 솜뭉치!
  • 예전에는 @babel/polyfill을 사용했으나 Babel 7.4.0부터는 deprecated
    • 현재는 core-js라는 것이 @babel/polyfill을 대체하고 있습니다.

useBuiltIns: entry

// babel.config.json
"useBuiltIns": "entry",
"corejs": "3.22"
// in
import "core-js"
// out
import "core-js/modules/es.set"
  • useBuiltIns옵션과 corejs 버전 명시를 같이하게 되면 import할 때 효과를 볼 수 있습니다.
  • useBuiltIns: entry => core-js/stable과 regenerator-runtime/runtime 모듈을 전역 스코프에 직접 삽입한 경우 이를 타깃 환경에 필요한 폴리필만 전역 스크포에 추가되도록 변경

useBuiltIns: usage (사용하는 것을 권장)

  • 실제 필요한 폴리필만 삽입
  • import 자체를 삽입해줘서 따로 삽입할 필요 없음
// in
var a = new Set();
// out
import "core-js/modules/es.set";

var a = new Set();

core-js 단독 사용

  • 전역 스코프가 오염될 수 있다는 단점을 가지고 있습니다.
  • 전역 스코프가 오염되었을 때 라이브러리를 사용할 때 예상치 못한 에러가 발생한다거나 이름 충돌이 발생할 수 있습니다.

@babel/plugin-transform-runtime + core-js 사용

  • 전역 스코프를 오염시키지 않습니다.
{
  "presets": [[
    "@babel/preset-env"
   ]],
   "plugins":[
   	["@babel/plugin-transform-runtime", {
    	"core-js": 3
    }]
   ]
}
  • 이런식으로 플러그인을 설치하고 core-js 버전 명을 명시하게되면 core-js-pure 패키지에서 폴리필 삽입
  • 만약에 프로젝트 내 패키지 중 전역 스코프에 의존하는 패키지가 존재한다면?
    • 해당 패키지를 포함해서 트랜스파일링을 진행해야합니다. (axios는 전역 Promise에 의존한다고 하네요)

babel.config.json / babelrc.json

babel.config.json

  • 여러 패키지 디렉토리를 가진 프로젝트에서 하나의 바벨 설정을 적용하고 싶을 때
    • node_modules도 적용하고 싶을 때 (axios에서 일어난 문제 해결!)

babelrc.json

  • 프로젝트 내에 서드 파티 라이브러리가 바벨에 의해 트랜스폼되기를 바라지 않는 경우
    • 특정 부분만 적용하고 싶은 경우

Webpack과 함께하는 Babel-loader

  • 어느정도 규모가 있는 프로젝트의 경우 보통 Webpack같은 모듈 번들러를 사용합니다.
  • 각 파일의 의존성을 파악해서 몇 개의 압축 파일로 만들어주고 최적의 결과를 만들어줍니다.
  • 이러한 Webpack과 Babel을 연결시켜주는 것이 Babel-laoder입니다.
module.exports = {
	module: {
    	rules: [
        	// babel-loader 설정
          	{
            	test: /\.m?js$/i,
              	exclude: /node_modules/,
              	use: {
                	lodaer: 'babel-loader',
                  	options: {
                    	presets: ["@babel/preset/env"]
                    }
                }
            }
        ]
    }
}

babel-loader vs ts-loader

const str: string = 9;
  • babel-loader: 에러 X

  • ts-loader: 에러 O

  • bebel-loader는 타입 체크를 하지 않는다.

  • enums 지원 x

    • 하지만 2021.7.26에 출시한 Babel 7.15버전부터는 모든 TS 코드 베이스를 컴파일 할 수 있다고 합니다.
  • Babel은 ECMAscript spec 기준이다보니 Decorator 같은 TypeScript에서 변화가 많은 기능은 지원하지 못합니다.

    • 하지만 관련 플러그인을 사용하면 이 도한 가능합니다.
  • babel-lodaer와 ts-lodaer의 속도를 비교해보면 프로덕트 환경과 개발 환경 둘다 babel-lodaer가 더 빨랐습니다.

마무리

이번 글에서는 babel에 관한 내용을 다뤘는데요. babel은 ES6+ 문법을 이전 문법으로 변환해주는 라이브러리라고만 알고 있었는 데 더 자세한 내용을 알게되어서 좋았습니다. 특히 Polyfill에 대한 개념과 babel-loader와 ts-lodaer를 비교하는 부분이 굉장히 흥미로웠습니다. 해당 영상의 내용대로라면 webpack을 구성할 때 관련 플러그인만 잘 설치한다면 ts-lodaer는 필요 없다는 것으로 이해했는데요. 최근에는 Vite를 통해서 간단하게 프로젝트를 생성하고 webpack을 통해 하나하나 프로젝트를 구성해본적은 오래된 거 같습니다. 조만간 webpack을 이용해서 프로젝트를 구성해봐야겠네요.

Reference

profile
흑우 모르는 흑우 없제~

0개의 댓글