바벨 (1) ( 바벨 실행 )

jaehan·2023년 2월 11일
0

babel

목록 보기
2/4
post-thumbnail

바벨이란?

Babel은 JavaScript 컴파일러입니다.
Babel은 현재 및 이전 브라우저 또는 환경에서 ECMAScript 2015+ 코드를 이전 버전과 호환되는 JavaScript 버전으로 변환하는 데 주로 사용되는 도구 체인입니다.

위 설명은 공식 문서에서 가져온 문장이다.
가볍게 생각하면 javascript문법이 계속해서 생겨나면서 아직 브라우저에 적용이 안된 경우가 있을 수 있기 때문에 이 코드를 구버전 javascript 문법으로 변환시켜주는 컴파일러이다.

예를 들면 아래의 화살표 함수를 기본 함수 표현식으로 변환시켜 주는 것이다.

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

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

📌 현재에는 JSX, 타입스크립트와 같은 정적 타입 언어, 코드압축 등에도 사용된다

실행법

바벨을 실행하는 방법은 네가지가 있지만 주로 세가지를 많이 사용한다.

  1. @babel/cli : command line에서 바벨을 사용
  2. babel-loader : webpack에서 바벨을 사용
  3. @babel/core : babel을 사용하기 위한 필수 패키지

바벨을 사용해 보기 위해 패키지를 설치해야 한다
npm install @babel/core @babel/cli @babel/plugin-transform-template-literals @babel/plugin-transform-arrow-functions @babel/preset-react

📌 바벨은 파싱과 출력을 담당하고 플러그인이 변환 작업을 처리한다.
📌 preset은 plugins의 집합이다.

아래와 같은 코드를 작성해서 세가지 방식으로 변환 시켜 보자.

src/code.js

// jsx -> createElement
const element = <div>babel test</div>; // preset-react

// template-literals -> concat
const text = `element type is ${element.type}`; // plugin-transform-template-literals

// arrow-functions -> normal func
const add = (a, b) => a + b; // plugin-transform-arrow-functions

1. @babel/cli

cli는 command line에서 사용하기 위한 것이기 때문에 터미널에 아래 명령어를 입력하면 작동한다.

npx babel src/code.js --presets=@babel/preset-react --plugins=@babel/plugin-transform-template-literals,@babel/plugin-transform-arrow-functions

그럼 아래처럼 결과가 콘솔에 출력된다.

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;
};

근데 이렇게 할때마다 입력하기 귀찮으니 config파일을 작성해서 사용한다.

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 src/code.js 를 입력하면 위와 같은 결과가 나온다.

2. babel-loader

웹팩을 이용하기 때문에 웹팩도 같이 설치해준다

npm install webpack webpack-cli babel-loader

webpack.config.js

const path = require("path");
module.exports = {
  entry: "./src/code.js", // 번들링할 파일 지정
  output: {
    path: path.resolve(__dirname, "dist"), // 현재 폴더 경로에서 dist 폴더밑으로
    filename: "code.bundle.js", // 이 이름으로 결과 생성
  },
  module: {
    rules: [{ test: /\.js$/, use: "babel-loader" }],
  },
  optimization: { minimizer: [] },
};

npx webpack을 입력하면 아래처럼 결과가 저장된다.

dist/code.bundle.js

/******/ (() => { // webpackBootstrap
var __webpack_exports__ = {};
// jsx -> createElement
const element = /*#__PURE__*/React.createElement("div", null, "babel test"); // preset-react

// template-literals -> concat
const text = "element type is ".concat(element.type); // plugin-transform-template-literals

// arrow-functions -> normal func
const add = function (a, b) {
  return a + b;
}; // plugin-transform-arrow-functions
/******/ })()
;

3. @babel/core

@babel/clibabel-loader 둘다 @babel/core를 이용해서 바벨을 실행한다.

@babel/core를 직접 사용하는 방법도 있다.

runBable.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, // babel.config.js 사용 x
});
console.log(code);

node runBabel.js을 입력하면 콘솔창에 결과가 나온다

👍 @babel/core를 직접 사용하면 자유도가 높다

예를 들어 한 코드에 아래와 같은 설정을 입힌다고 해보자

const presets = ["@babel/preset-react"];
const plugins = ["@babel/plugin-transform-arrow-functions"];

const presets = ["@babel/preset-react"];
const plugins = ["@babel/plugin-transform-template-literals"];

이 설정값에 대해 @babel/clibabel-loader를 이용하면 똑같은 preset-react를 두번 실행한다.

@babel/core로 이걸 해결할 수 있는데 AST를 이용하는것이다

💡 AST(abstract syntax tree)는 코드의 구문이 분석된 결과를 담고 있는 구조체이다

이걸로 어떻게 해결하냐면 바벨은 컴파일 시에 세단계를 거친다

  1. 파싱 단계: 입력된 코드로부터 AST를 생성한다.
  2. 변환 단계: AST를 원하는 형태로 변환한다.
  3. 생성 단계: AST를 코드로 출력한다.

❗️ 따라서 코드가 같으면 AST도 같기 때문에 재사용 할수 있다

runBabel2.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 { ast } = babel.transformSync(source, {
  // ast만 생성
  filename,
  ast: true,
  code: false,
  presets,
  configFile: false,
});

const { code: code1 } = babel.transformFromAstSync(ast, source, {
  filename,
  plugins: ["@babel/plugin-transform-template-literals"],
  configFile: false,
});
const { code: code2 } = babel.transformFromAstSync(ast, source, {
  filename,
  plugins: ["@babel/plugin-transform-arrow-functions"],
  configFile: false,
});

console.log(code1);
console.log(code2);

위 코드처럼 preset-react에 대해 AST를 만들어서 재사용해서 효율을 높일 수 있다.

참고: 실전 리액트 프로그래밍

0개의 댓글