[Babel] 바벨의 기본 개념

상민·2022년 7월 30일
0
post-thumbnail

바벨의 배경

크로스 브라우징

브라우져마다 사용하는 언어가 달라서 프론트엔드 코드는 일관적이지 못할 때가 많다
크로스브라우징의 혼란을 해결해 줄 수 있는 것이 바로 바벨
ECMAScript2015+로 작성한 코드를 모든 브라우저에서 동작하도록 호환성을 지켜준다
타입스크립트, JSX처럼 다른 언어로 분류되는 것도 포함한다

트랜스파일과 빌드

이렇게 변환하는 것을 트랜스파일 한다 라고 표현
타입스크립트 -> 자바스크립트
JSX -> 자바스크립트
처럼 트랜스파일 후 여전히 코드를 읽을 수 있다

바벨의 기본 동작

바벨 설치

npm install @babel/core @babel/cli
  • app.js

const alert = msg => window.alert(msg);

ES6 문법인 화살표함수const를 사용해서 코드를 작성한다
ES6를 지원하지 않는 브라우저 같은 경우는 이 코드를 인식하지 못한다

바벨을 통해서 모든 브라우저에서 인식할 수 있도록 변환해보자

바벨을 실행할 때는 node_modules/.bin/babel 명령어를 통해 실행해도 되고 npx를 사용해 실행할 수 있다

npx babel app.js

바벨은 세 단계로 빌드를 진행한다

  1. 파싱(Parsing)
  2. 변환(Transforming)
  3. 출력(Printing)

파싱은 코드를 받아가지고 각 토큰별로 다 분해한다
예를들면 위 코드에서 const alert = ... 이런식으로 분해한다

변환은 ES6로 되어있는 코드를 ES5코드로 변환한다
마지막으로 변경된 결과물을 출력하는 것으로 바벨은 작업을 완료한다

하지만 결과를 보면 빌드 이전과 변한게 없다.

npx babel app.js
const alert = msg => window.alert(msg); // 빌드 결과

이는 파싱은 했지만 변환 작업을 하지 않은 것이다
변환하지 않고 출력했기 때문에 결과가 이전과 동일한 것이다


플러그인

바벨은 파싱출력만 담당하고 변환 작업은 플러그인이 담당한다

커스텀 플러그인

  • my-babel-plugin.js

module.exports = function myplugin() {
  return {
    visitor: {
      VariableDeclaration(path) {
        console.log("VariableDeclaration() kind:", path.node.kind); // const

        // const => var 변환
        if (path.node.kind === "const") {
          path.node.kind = "var";
        }
      },
    },
  };
};

VariableDeclaration 메소드는 파싱된 결과를 path라는 객체로 받는다
path.node.kind 값이 'const'이면 'var'로 변환해주는 코드이다
ES6문법인 const를 ES5문법인 var로 변환해주는 플러그인이다

이 플러그인을 가지고 다시 바벨을 실행시켜보자
플러그인 사용법은 --plugins 옵션에 플러그인을 추가하면 된다

npx babel --help

  --plugins [list]
// 바벨 실행
npx babel app.js --plugins ./my-babel-plugin.js

// 빌드 결과
VariableDeclaration() kind: const
var alert = msg => window.alert(msg);

플러그인 사용하기

이러한 결과를 만드는 것이 block-scoping 플러그인이다
const, let 처럼 블록 스코핑을 따르는 예약어를 함수 스코핑을 사용하는 var로 변경한다

npm install -D @babel/plugin-transform-block-scoping

해당 플러그인을 사용해서 다시 app.js를 트랜스파일 해보자

npx babel app.js --plugins @babel/plugin-transform-block-scoping

var alert = msg => window.alert(msg); // 실행 결과

커스텀 플러그인과 같은 결과를 보인다

ES6인 화살표 함수도 arrow-functions 플러그인을 사용해서 일반 함수로 변경할 수 있다

npm install -D @babel/plugin-transform-arrow-functions
npx babel app.js --plugins @babel/plugin-transform-arrow-functions --plugins @babel/plugin-transform-block-scoping 

// 실행 결과
var alert = function (msg) {
  return window.alert(msg);
};

const, let 키워드가 var로 변환되었고, 화살표 함수도 일반 함수로 변환이 되었다

ECMAScript5 부터 지원하는 엄격 모드를 사용하는 것이 안전하기 때문에 use strict 구문을 추가한다
이는 strict-mode 플러그인을 사용한다

npm install -D @babel/plugin-transform-strict-mode
npx babel app.js --plugins @babel/plugin-transform-arrow-functions --plugins @babel/plugin-transform-block-scoping --plugins @babel/plugin-transform-strict-mode

//실행 결과
"use strict";

var alert = function (msg) {
  return window.alert(msg);
};

상단에 "use strict"; 구문이 추가된 것을 확인할 수 있다

플러그인이 많아질수록 커맨드라인이 길어지므로 기본 설정파일인 babel.config.js를 작성하자

  • babel.config.js

module.exports = {
  plugins: [
    "@babel/plugin-transform-block-scoping",
    "@babel/plugin-transform-arrow-functions",
    "@babel/plugin-transform-strict-mode",
  ],
};

babel.config.js를 작성했으면 이제 바벨을 실행할 때 간편하게 npx babel app.js만 입력해도 플러그인이 전부 적용된다

npx babel app.js

// 실행 결과
"use strict";

var alert = function (msg) {
  return window.alert(msg);
};

프리셋

ES5+으로 코딩할 때 필요한 플러그인을 일일이 설정하는 일은 매우 번거롭다
목적에 맞게 여러가지 플러그인을 세트로 모아둔 것프리셋이라고 한다

커스텀 프리셋

위에서 사용한 세 개의 플러그인을 하나의 프리셋으로 만들어보자

  • my-babel-preset.js

module.exports = function myBabelPreset() {
  return {
    plugins: [
      "@babel/plugin-transform-block-scoping",
      "@babel/plugin-transform-arrow-functions",
      "@babel/plugin-transform-strict-mode",
    ],
  };
};

plugins 프로퍼티에 플러그인을 담은 배열이 들어있는 객체를 반환하는 myBabelPreset 함수를 만들고 babel.config.js에 presets에 추가해준다

  • babel.config.js

module.exports = {
  presets: ["./my-babel-preset.js"],
};

기존의 plugins를 지우고 presets를 추가한다
presets에는 프리셋 배열이 들어가는데 위에 작성한 커스텀 프리셋을 추가한다

npx babel app.js

// 실행 결과
"use strict";

var alert = function (msg) {
  return window.alert(msg);
};

참고: https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard

profile
FE Developer

0개의 댓글