babel

Jinmin Kim·2023년 7월 7일

babel

babel6 : .babelrc
babel7 : babel.config.js

babel 적용 방법

@babel/core 
@babel/cli 
@babel/plugin-transform-arrow-functions 
@babel/plugin-transform-template-literals
@babel/preset-react
  • @babel/core : 바벨을 이용하기 위한 필수 패키지
  • @babel/cli : 명령줄에서 바벨을 사용
  • @babel/plugin-transform-arrow-functions
    @babel/plugin-transform-template-literals
    : plugin들을 간편하게 묶음으로 제공하는 presets를 설치해도 가능
  • @babel/preset-react : JSX파일을 컴파일 하기위해 리액트관련 preset 사용

@babel/cli

명령줄에서 바벨을 사용할수있으며, 명령어를 직접사용하여서
모던 자바스크립트 -> 레거시 자바스크립트로 변환한다.

npx babel src/code.js --presets=@babel/preset-react --plugins=@babel/plugin-transform-template-literals,@babel/plugin-transform-arrow-functions
const element = <div>babel test</div>
const text = `element type is ${element.type}`
const add = (a,b) => a+b;

->->->->->->->->->->->->->->->->

const element = /*#__PURE__*/React.createElement("div", null, "babel test");
const text = "element type is ".concat(element.type);
const add = function (a, b) {
  return a + b;
};

babel.config.js로 설정

프로젝트 루트에 babel.config.js를 생성

const presets = ['@babel/preset-react'];
const plugins = [
    '@babel/plugin-transform-template-literals',
    '@babel/plugin-transform-arrow-functions'
]
module.exports = {presets, plugins};

"npx babel 실행파일" 명령어만 입력하면 컴파일이 실행

  • 컴파일된 파일 출력하기
npx babel src/code.js --out-dir dist
npx babel src/code.js --out-file dist.js

--out-dir 과 --out-file 옵션을 이용해 각각 폴더의 하위에 동일한 파일이름으로 파일을 출력하거나, 파일 단위로 출력 할 수 있습니다.

webpack의 babel-loader

// webpack.config.js
const path = require('path')
module.exports = {
    entry : './src/code.js',
    output : {
        path : path.resolve(__dirname, 'dist'),
        filename : 'code.bundle.js'
    },
    module : {
        rules : [{test : /\.js$/, use: 'babel-loader'}],
    },
    optimization : {minimizer : []}
}

entry : 번들링할 모듈의 진입점 되는 파일입니다.
output : 번들링 후 출력할 파일의 경로와 파일이름을 저장합니다.
module.rules :
-> test : 정규표현식으로 대상이 되는 파일의 형식
-> use : 대상파일에 적용할 loader를 작성.

여기에서는 .js로 끝나는 자바스크립트 파일에 대해 babel-loader가 사용되도록 했으며, babel-loader는 바벨의 설정파일을 사용하므로, 아까 만들었던 babel.config.js파일의 내용을 설정값으로 이용합니다.

@babel/core직접 이용

// runBabel.js
const babel = require('@babel/core');
const fs = require('fs')

const filename = './src/code.js';
const source = fs.readFileSync(filename, 'utf8');
const presets = ['@babel/preset-react'];
const plugins = [
  '@babel/plugin-transform-template-literals',
  '@babel/plugin-transform-arrow-functions'
];
const {code} = babel.transformSync(source,{
  filename,
  presets,
  plugins,
  configFile: false
});
console.log(code)

@babel/core모듈 + 파일을 읽기위해 fs모듈을 가져오고
source변수에 fs.readFileSync 메서드를 이용해 파일을 읽습니다.
presets와 plugins에 설정내용을 담고,
transformSync메서드를 호출해 바벨을 실행
configFile속성은 babel.config.js설정파일을 이용할지 여부를 작성.
여기에서는 코드에 이미 내용이 포함되어있으므로 false로 작성.
마지막줄은 code속성을 콘솔에 출력하는 것인데,
파일로 따로 출력하고싶다면 fs모듈을 이용.

node runBabel.js

바벨의 컴파일 단계

  1. 파싱(parse) 단계 : 입력된 코드로부터 AST(abstract syntax tree)를 생성합니다.
  2. 변환(transform) 단계 : AST를 원하는 형태로 변환합니다.
  3. 생성(generate) 단계 : AST를 코드로 출력합니다.

babel 설정

  1. extends : 상속처럼 기존의 설정파일을 확장해 사용하고,
    호출하는 설정파일에서는 새로운 설정을 재정의해서 사용할 수 있습니다.
  2. env : 이용하면 앱의 실행 환경에 따라 다른 설정을 적용할 수 있습니다.
  3. overrides : 이용하면 파일단위로 다른 설정을 적용할 수 있습니다.

extends 속성

extends속성을 이용해서 다른 설정파일을 가져와 확장해보겠습니다.
어떤 식으로 덮어씌워지는지 보겠습니다.

설정파일 "A"
// src/common/.babelrc
{
    "presets": ["@babel/preset-react"],
    "plugins": [
        [
            "@babel/plugin-transform-template-literals",
            {
                "loose":true
            }
        ]
    ]
}

플러그인에 옵션을 설정하 때는 배열로 만들어서 두 번째 자리에 옵션을 넣습니다. 템플릿리터럴 플러그인의 loose옵션은 문자열을 연결할 때 concat메서드 대신에 '+'연산자를 사용합니다.

이번에는 extends속성을 이용해 방금작성한 common/.babelrc 파일을 불러올 example-extends/.babelrc 파일을 작성해보겠습니다.

설정파일 "B"

// src/example-extends/.babelrc
{
    "extends": "../../common/.babelrc",
    "plugins": [
        "@babel/plugin-transform-arrow-functions",
        "@babel/plugin-transform-template-literals"
    ]
}

설정파일 B에서 A를 불러오는 형태입니다.

설정파일 A에는 preset에 대한 설정이 있기 때문에 B에서는 따로 작성할 필요가 없습니다.
A에 작성했던 "loose":true 옵션은 B의 템플릿리터럴 플러그인 설정이 이미 존재하기 때문에 확장하지 않습니다.
결과적으로 호출하는 설정파일 B가 설정에서 우선순위를 가집니다.
상속의 형태라고 생각하면 쉽습니다.

const element = <div>babel test</div>
const text = `element type is ${element.type}`
const add = (a,b) => a+b;
// CLI
npx babel example-extends/code.js

이 코드를 실행해보면 설정파일 A에서 template-literal 플러그인 설정 "loose":true가 적용되지 않았다는 것을 알 수 있습니다.

적용된 설정파일의 추상적인 형태입니다.

// EXAMPLE
{
    "presets": ["@babel/preset-react"],
    "plugins": [
        "@babel/plugin-transform-arrow-functions",
        "@babel/plugin-transform-template-literals"
    ]
}

env속성

env는 환경별로 다른 설정값을 적용하는데 사용하는 속성입니다.
presets와 plugins를 아까 사용한 설정파일과 동일하게 작성하고 env속성을 추가합니다.

// src/example-env/.babelrc
{
    "presets": ["@babel/preset-react"],
    "plugins": [
        "@babel/plugin-transform-template-literals",
        "@babel/plugin-transform-arrow-functions"
    ],
    "env": {
        "production" : {
            "presets":["minify"]
        }
    }
}

env속성에 작성한 코드를 보세요. production환경에서 minify preset(압축 프리셋)을 사용합니다.
production환경에서 바벨이 실행될 경우 기존의 react preset은 유지되고 minify preset이 추가되는 형태가 됩니다.

  • production 환경에서 실행해보기
// window CLI
set NODE_ENV=production&&npx babel ./src/example-env
// result CLI
const element=/*#__PURE__*/React.createElement("div",null,"babel test"),text="element type is ".concat(element.type),add=function(c,a){return c+a};

production환경에서 실행했으므로 minify preset이 적용돼 압축된 코드가 출력됩니다.
NODE_ENV 환경변수를 따로 설정하지 않으면 기본값인 development가 적용됩니다.

overrides 속성

overrides속성을 파일별로 설정할 때 사용합니다.

{
    "presets": ["@babel/preset-react"],
    "plugins": [
        "@babel/plugin-transform-template-literals"],
    "overrides":[
        {
            "include":"./service1",
            "exclude":"./service1/code2.js",
            "plugins":["@babel/plugin-transform-arrow-functions"]
        }
    ]
}

overrides속성을 보세요.
include작성한 service1폴더를 포함, exclude에 작성한 service1/code2.js를 제외하고 plugins 또는 presets의 패키지를 적용한다는 의미입니다.
결과적으론 service1폴더에서 code2.js파일만 제외하고 presets나 plugins가 적용되는 것입니다.

// result
// service1/code.js
const element = /*#__PURE__*/React.createElement("div", null, "babel test");
const text = "element type is ".concat(element.type);

const add = function (a, b) {
  return a + b;
};

// service1/code2.js
const element = /*#__PURE__*/React.createElement("div", null, "babel test");
const text = "element type is ".concat(element.type);

const add = (a, b) => a + b;

화살표함수 플러그인 적용이 제외된 code2.js만 화살표함수가 바벨로 컴파일이 되지 않았습니다.

** 출처 사이트
1. https://velog.io/@kwonh/Babel-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95%EA%B3%BC-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EA%B3%BC%EC%A0%95
2. https://velog.io/@kwonh/Babel-%EB%B0%94%EB%B2%A8-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95-2-extends-env-overrides-%EC%86%8D%EC%84%B1

profile
Let's do it developer

0개의 댓글