Babel

heyhey·2022년 12월 22일
0

frontend

목록 보기
7/14

ES6 에서 ES5로 컴파일 해주는 트랜스 파일러입니다.

컴파일러와 트랜스파일러의 차이

  • 컴파일러 : 한 언어로 작성된 소스 코드를 다른 언어로 바꾸는 것입니다.

  • 트랜스 파일 :

    a라는 소스코드 파일을 읽어서 b라는 소스코드 파일로 변환시키는 행위, 컴파일 했을 때 , 추상화 수준이 같은 코드로 변환합니다.

    구버전의 소스코드를 신버전에 호환하는 형식으로 바꾸기도 하며, 신버전의 소스를 구버전에 호환되게 하기도 하는것이 목적입니다.

사용법

설치하기

npm install @babel/core @babel/cli
js 파일을 하나 만들고 babel로 실행시켜 보겠습니다.

const alertMessage = (msg)=>{window.alert(msg)}
실행하기

npx babel myJS.js
바벨 명령어를 통해 트랜스 파일을 하게 되면 똑같은 결과가 나오게 됩니다. 일단 바벨의 빌드 단계부터 알아봅시다.

바벨의 빌드 단계

  • 파싱 : 코드를 읽고 추상 구문 트리로 변환하는 단계를 파싱이라고 합니다. 빌드 작업을 처리하기 적합한 구조인데, 컴파일러 이론에 사용되는 개념입니다.

  • 변환 : 추상 구문 트리를 변경하는 것이 변환 단계 입니다. 실제 코드를 변경합니다.

  • 출력 : 변경된 결과물을 출력합니다.

앞선 작업에서 바벨이 변환을 못한 것 같은데 바벨은 파싱과 출력만 담당하고 , 변환작업은 '플러그인'이 처리하게 됩니다.

= 바벨의 코드 변환은 플러그인 혹은 preset 설정 파일에 적용함으로써 활성화 됩니다.

바벨 플러그인

custom-babel-plugin.js 를 만들면서 알아보겠습니다.

module.exports = function customBabelPlugin() {
    return {
        // 보통 visitor라는 객체를 만들게 됨
        visitor: {
            Identifier(path) {
                const name = path.node.name;

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

                // 변환 작업: 코드 문자열을 역순으로 변환
                path.node.name = name.split("").reverse().join("");
            },
        },
    };
};
  • 바벨의 플러그인은 오브젝트 내부에 visitor : 프로퍼티를 반환하는 함수로 시작됩니다.

  • visitor 프로퍼티 내부에 Identifier 매소드를 구현합니다.

  • Identifier 가 받을 path 에서는 node.name 등 정보를 가져올 수 있습니다.

이제 실행을 해보겠습니다. 바벨의 여러 명령어 중 plugins 명령어를 이용하겠습니다.
npx babel myJS.js --plugins './custom-babel-plugin.js'

=> 결과창

change name:alertMessage
change name:msg
change name:window
change name:alert
change name:msg

const egasseMtrela = gsm => wodniw.trela(gsm);

AST 노드의 토큰 하나하나를 path.node.name 으로 가지고 있습니다 . 그리고 이것을 뒤집어 출력해줍니다.

이런식으로 js 파일의 코드를 하나씩 확인하면서 바꿔줄 수 있습니다.

이번에는 const를 var로 바꾸는 플러그인을 만들어 보겠습니다.

module.exports = function customBabelPlugin() {
    return {
    	visitor: {
            VariableDeclaration(path) {
                if (path.node.kind === "const") {
                    path.node.kind = "var";
                }
            },
        },
    };
};

위와 동일하게 실행시키면 아래와 같이 바뀌게 됩니다.

구형 브라우저에서 호환되지 않는 const를 var로 변환하기 때문에 그 브라우저에서도 사용할 수 있게 됩니다.

var alertMessage = (msg)=>{window.alert(msg)}

바벨이 제공해주는 플러그인 사용해보기

우리가 만들었던 customBabelPlugin은 이미 플러그인 형태로 제공되고 있습니다.

babel-plugin-transform-block-scoping 에서 let을 var로 바꿔주는 것을 확인할 수 있습니다.
npm install @babel/plugin-transform-block-scoping

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

결과

var alertMessage = (msg)=>{window.alert(msg)}

const 가 var 로 바껴있는 것을 확인할 수 있습니다.

마찬가지로 ()=> 함수 또한 트랜스컴파일해줄 수 있는 플러그인을 설치하고 같이 실행해 보겠습니다.

plugin-transform-arrow-functions

콤마(,) 를 이용해 여러개를 같이 사용할 수 있습니다

npx babel myJS.js --plugins @babel/plugin-transform-block-scoping,@babel/plugin-transform-arrow-functions
결과

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

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 myJS.js
를 바로 실행해도 플러그인을 적용한 결과로 나옵니다.

프리셋

많은 양의 바벨 플러그인을 사용해야 하는데, 바벨의 플러그인 설치는 시간과 관리가 힘듭니다. 그래서 목적에 맞게 여러개의 플러그인을 모아놓은 것을 프리셋이라고 부릅니다.

custom-babel-preset.js 파일을 만들고,

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

babel.config.js 내용도 바꿔줍니다.

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

실행시켜주면, 뭉쳐진 preset이 잘 적용이 됩니다.

바벨 프리셋

자주 사용되는 프리셋 몇개가 있습니다.

  • preset-env : ES6 를 변환할 때 사용됩니다.

  • preset-flow : flow 를 변환합니다.

  • preset-react : react를 변환합니다.

  • preset-typescript : typescript를 변환합니다.

타겟 브라우저 설정해보기

babel.config.js 작성

module.exports = {
    presets: [
        [
            "@babel/preset-env",
            {
                targets: {
                    chrome: "79",
                },
            },
        ],
    ],
};

targets 가 추가 되었습니다. 결과는 어떨 까요 ? 화살표 함수와 const 가 둘다 그대로 적혀있습니다.

왤까요? chrome 이 최신 문법들을 사용이 가능하기 때문에 그대로 사용되는 것입니다.

하지만 이 targets에 ie가 적힌다면 어떻게 될까요?

targets: {
    chrome: "79",
    ie: "11"
}

ie 에서 호환이 되기 위해 function과 var으로 변환된 결과가 나타나게 됩니다.

리액트에서 자동으로 preset을 만들어 줘서 잘 몰랐었으나
Babel을 이해하고, 적용시키기 위해 크로스 브라우징을 해결해볼 수 있는 기회가 생겼으면 좋겠습니다.

profile
주경야독

0개의 댓글