LoginSignup
7
1

More than 1 year has passed since last update.

Node.js のビルドツール「esbuild」について!

Posted at

esbuild.png

はじめに

esbuild は、キャッシュなしで高速なビルドを可能とする Node.js のビルドツールです。

ビルドツールには、esbuild の他に、Webpack、Gulp、Parcel、Rollup、Browserify、FuseBox などがあります。

私自身が webpack を普段使っていて、ビルドに時間がかかりすぎているのが気になり、esbuild について調べてみようと思いました。

esbuild の特徴としては、

  • キャッシュなしでの高速なビルド
  • ES6 と CommonJS をサポート
  • ES6 の Tree shaking 対応(利用されていないコードの除去)
  • JavaScript と Go による API
  • TypeScript と JSX をサポート
  • ソースマップの生成
  • ソースコードの最小化
  • プラグイン(現在、experimental で v1.0.0 より前に対応予定)

が挙げられます。

この中でも注目すべきは、そのビルド速度にあると思います。

なぜ早いのか?

  1. esbuild は Go で書かれており、ネイティブコードへコンパイルしている

ほとんどのビルドツールは、Javascript によって書かれており、JIT コンパイルを使用するため、速度が遅い。

Go は、並列処理が得意で共有メモリをスレッド間で使用する。また、ヒープメモリも共有している。

よって、CPU を効率的に使用して、並列処理を行える。

  1. 並列で処理を行う

昨今のPCは、複数のメモリを持っているため、効率的に並列処理を行える。

  1. esbuild は、0 から速度を意識して作られた

3rd パーティライブラリを使用するのに比べ、パフォーマンスに対して多くのメリットが得られる。

例えば、多くのバンドラでは、公式の TypeScript コンパイラを使ってパースしているが、そのコンパイラは、パフォーマンスを最優先として作られていない。

その点、0 からパフォーマンスを最優先として作ることで、高速にコンパイルが可能となる。

  1. メモリを効率的に使用する

esbuild は、JavaScript の抽象構文ツリーへは 3 回しかアクセスしない。

また、Go は、コンパクトにしてメモリに保存するため、より効率的にメモリを使用できる。

esbuild の制限

簡単な使い方

$ echo "{}" > package.json
$ yarn add esbuild react react-dom
app.jsx
import * as React from 'react'
import * as Server from 'react-dom/server'

let Greet = () => <h1>Hello, world!</h1>
console.log(Server.renderToString(<Greet />))
$ ./node_modules/.bin/esbuild app.jsx --bundle --outfile=out.js
$ node out.js

速度比較

今回は、create-react-app で作ったアプリケーションのビルド速度を比較します。

通常の React アプリケーション

$ npx create-react-app react-ts-app --template typescript
$ cd react-ts-app
$ vim tsconfig.json
target を es2016 に修正
$ vim src/App.tsx
svg 関連のコードをコメントアウト
$ sudo rm -fr build && /usr/bin/time yarn build

esbuild 版 React アプリケーション

$ npx create-react-app react-ts-app --template typescript
$ cd react-ts-app
$ vim tsconfig.json
target を es2016 に修正
$ vim src/App.tsx
svg 関連のコードをコメントアウト
build.ts
const { argv } = require('process')
const { build } = require('esbuild')
const path = require('path')

const options = {
  define: { 'process.env.NODE_ENV': process.env.NODE_ENV },
  entryPoints: [path.resolve(__dirname, 'src/index.tsx')],
  minify: argv[2] === 'production',
  bundle: true,
  target: 'es2016',
  platform: 'browser',
  outdir: path.resolve(__dirname, 'dist'),
  tsconfig: path.resolve(__dirname, 'tsconfig.json')
}

build(options).catch(err => {
  process.stderr.write(err.stderr)
  process.exit(1)
})
$ sudo rm -fr build && /usr/bin/time node build.ts

結果

通常の React アプリケーション
3.91 real         5.40 user         0.66 sys
3.43 real         5.53 user         0.60 sys
2.96 real         5.25 user         0.57 sys

esbuild 版 React アプリケーション
0.10 real         0.12 user         0.02 sys
0.08 real         0.12 user         0.01 sys
0.08 real         0.12 user         0.01 sys

おわりに

結果を見てもらうと分かるようにかなり高速にビルド出来ました。

create-react-app で作られるアプリケーションには、svg をインポートしている部分がありますが、ここは別途プラグインでやる必要がありそうですが、

今回の目的とは違っていたので、コメントアウトで対応しました。

単純に置き換えるだけではうまくいかないところがあったり、まだ、メジャーバージョンも 1 になっていなかったりするので、様子見しつつ、タイミングを見て導入できればと思います。

開発当初は気にならないほどの速度でビルド出来ていても、開発が進むにつれてだんだんビルドが遅くなり、ストレスに感じることもあるかと思います。

そんな時にぜひ esbuild も検討してみてはいかがでしょうか?

お知らせ

Webサイト・ツール・LP作成のご依頼は、

こちらからお問い合わせいただけます。お気軽にご相談ください。

参考

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1