웹 공부하기/Frontend

[인프런] 프론트엔드 개발환경의 이해와 실습 (바벨의 기본 개념)

inthess 2021. 10. 20. 10:32
바벨의 기본 개념을 알아보고, 프로젝트에 직접 적용해보자.

바벨의 기본 개념

바벨이 나온 이유

브라우저마다 사용하는 언어가 달라서 프론트엔드 코드가 일관적이지 않을 때가 많다. 인터넷 익스플로러에서 Promise를 이해하지 못하는 것 처럼 말이다. 이와 같은 크로스브라우징을 해결해 줄 수 있는 것이 바로 바벨이다. ECMAScript2015+로 작성한 코드를 모든 브라우저에서 동작하도록 호환성을 지켜준다.

 

바벨의 기본 동작

바벨은 EMS2015 이상의 코드를 적당한 하위 버전으로 바꿔준다. 바뀐 코드는 최신 자바스크립트 코드를 이해하지 못하는 구 버전 브라우저에서도 잘 동작한다.

바벨을 이용해 아래 코드를 바꿔보자.

src/app.js

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

 

먼저 바벨 최신 버전과 터미널 도구를 사용하기 위한 커맨드라인 도구를 설치해준다.

$ npm install -D @babel/core @babel/cli

 

설치 후, 바벨 명령어로 적용시킨다.

$ npx babel ./src/app.js

적용시킨 결과를 보면 빌드 이전과 달라진 게 없을 것이다. 이유는 바벨의 빌드 단계에 나타난다.

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

  1. 파싱: 코드를 받아서 하나하나 각 토큰으로 분리함    ex) const / alert / = / ...
  2. 변환: ES6 코드를 ES5로 변환 → 플러그인의 역할
  3. 출력: 변환된 결과를 출력

 

플러그인

기본적으로 바벨은 코드를 받아서 코드를 반환한다. 즉, 파싱과 출력만 담당하고 변환 작업은 플러그인이 한다.

플러그인을 직접 만들어 동작 원리를 살펴보자.

my-babel-plugin.js

module.exports = function myplugin() {
  return {
    visitor: {
      Identifier(path) {
        const name = path.node.name // 파싱된 결과물에 접근

        // 바벨이 만든 AST 노드를 출력
        console.log("Identifier() name:", name)

        // 변환작업: 코드 문자열을 역순으로 변환
        path.node.name = name.split("").reverse().join("")
      },
    },
  }
}

플러그인 형식은 visitor 객체를 가진 함수를 반환해야 한다. 이 객체는 바벨이 파싱해서 만든 추상 구문 트리(AST)에 접근할 수 있는 메소드를 제공한다. 그 중에 Identifier() 메소드의 동작 원리를 살펴보는 코드이다.

 

이렇게 작성한 플러그인을 사용하기 위해서는 다음과 같이 작성하면 된다.

$ npx babel ./src/app.js --plugins ./my-babel-plugin.js

 

  • block-scoping 플러그인은 const, let 처럼 블록 스코핑을 따르는 예약어를 함수 스코핑을 사용하는 var로 바꿔주는 역할을 한다.
  • 화살표 함수를 지원하지 않는 브라우저도 있기 때문에 arrow-functions 플러그인을 이용해서 일반 함수로 바꿔줄 수 있다.
  • ES5에서부터 지원하는 엄격 모드를 사용하는 것이 안전하기 때문에 "use strict" 구문을 추가하고자 strict-mode 플러그인을 사용할 수 있다.

위의 3가지 플러그인들을 설치해보자.

$ npm install -D @babel/plugin-transform-block-scoping @babel/plugin-transform-arrow-functions @babel/plugin-transform-strict-mode

 

설치한 플러그인을 커맨드라인에서 사용하기에는 명령어가 너무 길어지기 때문에 웹팩처럼 기본 설정파일을 분리해준다.

babel.config.js

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

 

이렇게 설정파일을 작성하면 아래와 같이 보다 간단한 명령어로 빌드할 수 있다.

$ npx babel ./src/app.js

 

프리셋

코드 한 줄을 작성하는데도 세 개의 플러그인을 세팅해야하는 상황이 발생했다. 필요한 플러그인을 일일이 설정하기 보다는 목적에 맞게 여러가지 플러그인을 세트로 모아두는 것이 좋겠다. 이게 바로 프리셋이다.

 

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

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 배열에 사용한 세 개의 플러그인을 담았다.

 

프리셋을 사용하기 위해 바벨 기본 설정도 수정해준다.

babel.config.js

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

플러그인 세팅 코드를 제거하고 presets 배열에 방금 만든 my-babel-preset.js를 추가했다. 실행해보면 같은 결과를 출력할 것이다.

 

 

 

 


출처: [인프런] 프론트엔드 개발환경의 이해와 실습