Babel

movie·2022년 8월 30일
1
post-thumbnail

브라우저마다 사용하는 언어가 달라서 코드가 일관적이지 못할 때가 많다. 스펙과 브라우저가 개선되고 있지만 여전이 인터넷 익스플로러는 프로미스를 이해하지 못한다.

크로스 브라우징 문제는 코드의 일관성을 해치고 초심자를 불안하게 만든다.

크로스 브라우징이란 플랫폼이나 각 브라우저의 렌더링 엔진 차이로 보이는 모습이 다른 경우가 있는데, 최적화 작업을 통해 기존에 의도한 대로 보이도록 하는 작업

(바벨은 혼돈이라는 뜻 😱)

자바스크립트 언어의 문법은 빠르게 진화하고 있지만 정작 자바스크립트를 실행해주는 환경은 이를 받쳐주지 못하는 경우가 많다. 예를 들어 브라우저 종류는 다양하고 어떤 브라우저가 어떤 문법을 지원하는지 일일이 파악하기 힘들다. nodejs의 경우에도 버전별로 지원하는 언어 문법이 다르기 때문에 이 또한 파악하기 힘들다.

이런 이유로 자바스크립트 개발자들은 최신 문법을 쓰자니 작성한 코드가 일부 실행환경에서 작동하지 않는 이유가 생길 수 있고, 모든 환경에서 돌아가게 코딩을 하자니 ES5 이하 방식으로 코드를 작성해야하는 딜레마를 경험하게 된다.

이런 딜레마를 해결하기 위해 등장한 것이 바로 자바스크립트 transpiler인 babel이다.

바벨은 엄연히 말하면 transpiler지만,

transpiler : 다른 실행 환경에서도 코드가 작동하도록 같은 언어를 유지한채 소스 코드의 형태만 바꾸는 과정

compiler라고도 불린다. (좀 더 편하게)

compiler : C나 Java같은 컴파일 언어로 작성된 소스 코드를 컴퓨터가 이해할 수 있도록 머신 코드로 바꿔주는 과정

사실상 자바스크립트는 컴파일 언어가 아니기 떄문에 컴파일 과정이 필요없다. 하지만 실제 자바스크립트 커뮤니티에서는 두 용어가 혼용되어 사용되고 있다.



트랜스파일(Transpile)

작성된 코드를 모든 브라우저에서 동작할 수 있도록 변환해주는 것을 트랜스파일이라고 말한다.

타입스크립트,
JSX,
..

⇣⇣⇣

자바스크립트


바벨의 주요 역할

  1. transpiler
  2. polyfill
  • ES2015+ 이상의 코드를 적당한 하위 버전으로 변경한다.
    • 모던 자바스크립트 코드를 구표준을 준수하는 코드로 바꿔준다.
  • 대상 환경에서 누락된 폴리필 기능을 한다.

폴리필이란?

  • 구현이 누락된 기능을 매꿔주는 역할

명세서(specification)에는 새로운 문법이나 기존에 없던 내장 함수가 추가되곤 한다.

transpiler가 이를 구표준을 준수하는 코드로 변경하지만, 새롭게 추가된 함수는 명세서 정의를 읽고 이에 맞게 직접 함수를 구현해야 사용할 수 있다. 자바스크립트는 매우 동적인 언어이기 때문에 어떤 함수라도 스크립트에 추가할 수 있다.

이렇게 변경된 명세서를 준수할 수 잇게 기존 함수의 동작 방식을 수정하거나, 새로 구현한 함수를 polyfill이라고 부른다. (구현이 누락된 새로운 기능을 메꿔준다 - fill in)

즉, 최신 자바스크립트 기능을 구식 자바스크립트 코드로 똑같이 구현한 코드를 말한다.



웹팩(모듈 번들러)과의 관계?

바벨은 개발자의 컴퓨터에서 돌아간다. 작성된 코드가 구표준을 준수하는 코드로 변경되는데 변경된 코드는 웹 사이트 형태로 사용자에게 전달된다.

웹팩같은 모듈 번들러(모던 프로젝트 빌드 시스템)은 코드가 수정될 때마다 자동으로 transpiler(바벨)를 동작시켜준다. 즉, babel을 동작 시켜준다. 모듈 번들러의 이런 과정이 없다면 개발이 끝난 코드를 한데 통합하는 데에 어려움이 있을 수 있다.

웹팩과 바벨을 babel-loader 패키지를 통해 연결시켜줄 수 있는데 웹팩 설정에서 바벨 로더를 설정해주면 된다. babel-loader는 웹팩이 모듈을 번들링할 때 바벨을 사용하도록 도와주는 역할을 한다.

// webpack.config.js
// 웹팩 공식문서

module.exports = {
  module: {
    rules: [
      // Babel 파일 로더 설정
      {
        test: /\.m?js$/i,
        exclude: /node_modules/,
        use: {
          loader:'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
}


바벨은 어떻게 JSX도 자바스크립트로 변환시켜줄까?

바벨을 사용하기 전에는 바벨에게 어떻게 코드를 변환해야 하는지를 알려주어야 한다.

npx babel [파일명]

# babel: ????

만약 아무 설정없이 바벨을 실행할 경우 코드에 아무 변화도 없을 것이다.

바벨이 코드를 변환하는 것은 알겠는데 어떻게 JSX도 자바스크립트로 변환시켜줄까?


정답은 plugin과 preset을 통해서이다!

plugin : 규칙 하나하나는 미세하게 적용할 때 사용

preset : 여러개의 규칙을 한번에 적용할 때 사용 (규칙을 모아놓은 세트)


preset의 예시 env

npm i -D @babel/preset-env

env 는 가장 범용적으로 사용되는 preset으로 ES6+(ES2015) 이상의 문법으로 작성된 코드를 ES5 문법으로 변환해주는 모든 규칙을 정의하고 있다.

npx babel [파일명] --presets=@babel/env

바벨에게 env preset을 적용하여 규칙을 알려준다면 바벨이 알아서 변환해줄 것이다.


만약 JSX를 사용하고 있다면?

react를 사용하고 있다면 JSX로 코드를 작성하고 있을 것이다.

JSX 또한 바벨에게 변환할 규칙을 알려주어야 한다.

이를 위한 preset으로는 react preset이 있다.

npm i -D @babel/preset-react

설치 후 바벨에게 규칙을 알려준다면 바벨이 JSX를 자바스크립트로 변환해준다.


리액트에서 바벨을 사용해야하는 또 다른 이유가 있다?

리액트에서는 데이터를 관리하기 위해 여러 자바스크립트 내장 함수를 사용하는데 filter, map 등 ES6 문법을 사용한다. 또 리액트에서 사용하는 여러 라이브러리 또한 ES6기반 코드들이므로 바벨이 필요하다.



이렇게 일일히 바벨에게 알려줘야해? 😱

// cli에서 바벨에게 규칙 알려주기 

npx babel [파일명] --presets=@babel/env
// 설정파일을 통해 바벨에게 규칙 알려주기 

{
  "presets": ["@babel/env"]
}

매번 바벨에게 cli를 통해 변환될 규칙을 알려주는 것은 매우 비효율적이다. 이런 이유로 바벨 설정 파일을 만들어 주는 것이다.!

바벨 설정파일은 .babelrc, babel.config.js, babel.config.json

이렇게 존재한다.

.babelrc : 주로 하위 디렉토리나 파일에서 특정 규칙을 적용할 때 적절

babel.config.js : 여러 패키지 디렉토리를 가진 프로젝트에 규칙을 설정할 때 유용

둘중 babel.config.js가 좀 더 보편적으로 사용되고, 바벨 공식문서에 따르면 babel.config.js를 사용하면 이를 구성하는 API가 노출되기 때문에 (캐싱과 관련해서 복잡성을 증가시킨다.) 정적인 구성인 babel.config.json을 사용하는게 좋은 선택이다.




참고

profile
영화보관소는 영화관 😎

0개의 댓글