esbuildでビルドしてみる

webpackに比べてビルドが爆速だと話題のesbuildで試してみた話。
ビルドスクリプトとかをメモしておく。
動作環境は以下。

  • OS: windows 10
  • node v15.4.0
  • npm v7.0.15

参考にしたサイト。

インストール

npmですんなりインストール。
ついでに、変更検知してブラウザリロードしてくれる browser-syncと、ビルド時のログを色付けするchalkをインストール。

npm install --save-dev esbuild
npm install --save-dev browser-sync
npm install --save-dev chalk

reactでサンプルを作成するため、reactをインストール。

npm install react react-dom

適当にサンプルページ作成

ディレクトリ構成は ↓ な感じで、public/index.html と src/index.jsx に適当なサンプルを作る(index.css は今回は空ファイル)。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Web site created using esbuild" />
  <title>hoge</title>
  <link rel="stylesheet" href="index.css" />
</head>
<body>
  <div id="root"></div>
  <script src="index.js"></script>
</body>
</html>
import React from 'react';
import ReactDOM from 'react-dom';

import "./index.css";

ReactDOM.render(
  <h1>esbuildでビルドしてみた!</h1>,
  document.getElementById('root')
);

ビルドスクリプト作成

esbuildでビルドするためのスクリプト。

前半部分。ライブラリをインポートしたり、ビルド結果のディレクトリ(dist)を初期化したりする。

const { build } = require('esbuild');
const chalk = require('chalk');
const bs = require('browser-sync').create();
const fse = require('fs-extra');

const isDevEnv = process.argv.includes('--dev');
const isServeMode = process.argv.includes('--serve');
const outdir = 'dist';

try {
  fse.rmSync(outdir, { recursive: true, force: true });
  fse.mkdirSync(outdir);
  fse.copyFileSync('public/index.html', `${outdir}/index.html`);
} catch (err) {
  console.error(`[${chalk.green('build script')}] initialize dist failed:`, err);
  process.exit(1);
}

後半部分のビルド処理。

build({
  target: 'es2015',
  platform: 'browser',
  entryPoints: ['src/index.jsx'],
  outdir: outdir,
  bundle: true,
  minify: !isDevEnv,
  sourcemap: isDevEnv,
  watch: isServeMode ? {
    onRebuild: (err, result) => {
      if (err) {
        console.error(`[${chalk.green('build script')}] watch build failed:`, err);
      } else {
        console.log(`[${chalk.green('build script')}] watch build succeeded:`, result);
      }
    }
  } : false,
}).then((result) => {
  if (isServeMode) {
    console.log(`[${chalk.green('build script')}] Watching source files...`);
    bs.init({
      server: outdir,
      watch: true
    }, (err) => {
      if (err) {
        console.error(`[${chalk.green('build script')}] serve failed:`, err);
        bs.exit();
      }
    });
  } else {
    console.log(`[${chalk.green('build script')}] build succeeded:`, result);
  }
}).catch((err) => {
  console.error(`[${chalk.green('build script')}] build failed:`, err);
  process.exit(1);
});
  • 開発のときには、デバッグ容易にするため、minify せず、sourcemapを作成するようにする(7、8行目)
  • ソースを修正しながらビルド結果を確認するときには、ビルドオプションの watch を true にしてソースの変更を監視し、変更されたら再ビルド(10~15行目)
  • ビルド先の dist は browser-sync で監視していて、再ビルドされたらブラウザをリロードする(21~29行目)

上記のビルドスクリプトを動かすために、package.json の script に以下を追加。

"scripts": {
  "build": "node ./devtools/build",
  "serve": "node ./devtools/build --dev --serve",
},

ビルドのときには以下を実行。dist ディレクトリにビルド結果が作成される。

npm run build

開発のときには以下を実行。ブラウザが起動されてページが表示される。
ソースを修正したら再ビルドとブラウザリロードが自動的に実行される。

npm run serve

確かに、めっちゃビルドが速い。

その他

ここでは紹介しないが、TypeScript、Sass のビルドもできる。参考ページは以下。

以上です。