자바스크립트 번들러, esbuild로 React 빌드하기
새로운 자바스크립트 번들러 esbuild를 알아보고 React 빌드하기
자바스크립트에서 모듈이 등장하고 이런 모듈을 번들링하기 위한 번들러가 등장했다.
현재까지도 가장 많이 사용하는 webpack이 대표적인 번들러다.
회사에서도 webpack을 통해 번들링하고 있는데 프로젝트가 커서 빌드가 꽤 오래 걸린다.
그래서 알아보던 중 빠른 새로운 번들러를 알게됐고 그게 esbuild다.
esbuild
esbuild에서 제공하는 다른 번들러와의 속도 차이이다. 꽤 많은 차이가 난다.
esbuild가 이렇게 빠를 수 있는 이유를 esbuild에서는 아래와 같이 설명한다. (자세한 내용은 공식문서 참고)
Go로 작성됨- 병렬 처리
- 효율적인 메모리 사용
- esbuild는 처음부터 모두 직접 개발함
esbuild는 컨텐츠 타입에 맞는 loader를 가지며 loader를 통해 파일을 esbuild가 읽을 수 있게 한다.
기본으로 내장된 loader가 있고 js, jsx, ts, tsx loader가 지원된다.
기본으로 내장된 컨텐츠 타입과 loader은 공식문서에 정리되어있다.
esbuild + react
esbuild로 react를 실행하며 사용법을 간단히 익혀보자
React 18 기준으로 작성되어
ReactDOM.render가 사용되지 않는다.
esbuild와 react관련된 패캐지를 설치한다.
$ mkdir {project}$ cd {project}$ yarn init$ yarn add -D esbuild$ yarn add react react-dom
이후 index.jsx, App.jsx, util.js 파일을 작성했다.
// src/index.jsximport React from 'react';import ReactDOM from 'react-dom/client';import App from './App';const root = ReactDOM.createRoot(document.querySelector('#root'));root.render(<App />);// src/App.jsximport React from 'react';import { getRandomWelcomeText } from './utils';function App() {return (<div><h1>{getRandomWelcomeText()}</h1></div>);}export default App;// src/utils.jsexport function getRandomWelcomeText() {const welcomeTexts = ['Hello World', 'Welcome', 'Hi esbuild'];return welcomeTexts[Math.ceil(Math.random() * 10) % welcomeTexts.length];}
그리고 yarn build 명령어를 추가하자
// package.json..."scripts": {"build": "esbuild src/index.jsx --outdir=dist --bundle"}...
outdir은 번들링 된 파일을 위치할 폴더이고 --bundle 옵션을 통해서 import된 파일을 모두 하나의 파일로 번들링한다.
마지막으로 html 파일을 만들어주면 된다.
<!-- index.html --><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><script src="./dist/index.js" defer async></script><body><div id="root"></div></body></html>
빌드 후 index.html 파일 브라우저에서 확인해보면 잘 동작하는걸 확인할 수 있다.
$ yarn build
간단히 esbuild + react로 앱을 실행해봤다.
아직 일반 번들러와 직접 비교해보지 못했지만 확실히 빠르다는 느낌이 있었다.
webpack vs esbuild
webpack으로 번들링한 결과와 esbuild로 번들링한 결과를 비교해봤다.
먼저 기존에 가장 많이 쓰는 webpack + babel 조합으로 빌드해봤다.
const path = require('path');module.exports = {entry: './src/index.jsx',output: {path: path.resolve(__dirname, 'dist'),filename: 'index.js',},module: {rules: [{test: /\.(jsx|ts)$/,use: {loader: 'babel-loader',options: {loader: 'jsx',},},},],},};
간단히 babel-loader만 사용하도록 webpack 설정을 한 후 번들링한 결과다.
별다른 설정이 없을때 3.18s가 걸렸다.
다음으로 esbuild (+ esbuild-loader) esbuild 번들링과 내부 loader를 사용한 결과다.
0.37s가 걸렸다. 생각보다 차이가 많이 난다.
지금은 페이지 하나에 해당하는 코드를 번들링한 결과 차이다.
하지만 실제로 사이드 프로젝트에 적용했을때도 생각보다 차이가 많이 났다.
babel-loader vs esbuild-loader
이렇게만 보면 babel이 느린건지 webpack이 느린건지 알 수 없다.
webpack + esbuild-loader의 조합도 확인해봤다.
3.40s초로 babel-loader를 사용했을때 보다 크게 차이가 나지 않았다.
코드 양이 작아서 크게 체감되지 않았을 수 있다.
그래서 실제 사이드프로젝트에 webpack + esbuild와 webpack + babel을 사용해 확인해봤을때 평균 4.0s정도 webpack + esbuild가 빨랐다
esbuild를 사용해보니 생각보다 기존 도구들과 차이가 나서 다음에 실제로 적용해보고 싶다.
다음에 적용하게 된다면 추가로 글을 남겨야겠다.