はじめに
この記事では以下のことについて解説しています。
- esbuildについて
- esbuildを使ってTypeScriptで書かれた Node.js関数をビルドする方法
- esbuildの注意点
前回の記事でTSのビルドツール Parcel を使って TypeScriptで書かれた Node.js関数をビルドする方法を紹介しました。本記事では esbuild というTSのビルドツールを使った手法を紹介します。
esbuidとは
Parcelと同様にフロントエンドのビルドツールです。公式に挙げられている特徴として
- キャッシュなしでの高速なビルド
- ES6 と CommonJS をサポート
- Tree shaking(利用されていないコードの除去)、minify, ソースマップの生成に対応
- JavaScript, CSSだけでなく TypeScript と JSX をサポート
とTSのビルドでやれて欲しいことは一通りできます。
使っていて思うのはとにかく実行が速い。 公式が自ら「An extremely fast bundler for the web」と推すだけあります。
そして後述しますが、tsconfig.json
の設定をベースにモジュール解決もよしなにやってくれるので、esbuild側で設定することはほとんどありません。ほぼ Zero Config で使えます。 Parcelの意義とは
早速使ってまいりましょう。
esbuild のインストール
npm install --save-exact --save-dev esbuild
esbuildでTypeScriptで書かれた Node.js関数をビルドする
以下のbuildコマンドを package.json
に追記します。
"scripts": {
"build": "esbuild ./src/index.ts --bundle --platform=node --outfile=./dist/index.js"
}
$ npm run build
> advent-calendar-2024@1.0.0 build
> esbuild ./src/index.ts --bundle --platform=node --outfile=./dist/index.js
dist/index.js 5.9kb
⚡ Done in 17ms
秒でビルドできました。--bundle
オプションを指定している場合、勝手にTree shakingをしてくれます。
追加で以下のオプションも指定できます。
--minify
その名の通り指定すると minify
してくれます。
--sourcemap
sourcemapを生成してくれます。
--platform=node
Node.jsのビルドの際には指定します。今回では指定必須です。
--format
出力されるJSのフォーマットをCommonJS形式で出力するか、ESModule形式で出力するか。
package.json で "type": module
としているので、--format=esm
としましょう。
esbuild使用時の注意点
tsconfig.json
の outDir
設定を読んでくれない
下記のリンクを見ても分かるように、outDir
はtsconfig.json
の読んでくれるオプションの対象外のようです。
(なんでやねんっ!)ってなりますが、--outfile
オプションで出力先を指定してあげましょう。
型チェックは行われない
esbuildもParcelと同様にTSの型チェックが行われません。公式も「うちはビルドを超速でやることが仕事だ。型チェックはtscにでもやらしておけ」的なことを開き直っていますおっしゃっています。
However, esbuild does not do any type checking so you will still need to run tsc -noEmit in parallel with esbuild to check types. This is not something esbuild does itself.
試してみましょう。
import * as ff from '@google-cloud/functions-framework'
import { hoge } from '@/hoge/hoge.js'
export const helloGET: HttpFunction = (req: ff.Request, res: ff.Response) => {
let hogehoge: string = hoge();
hogehoge = 1; // strgin型にnumberを代入
console.log(hogehoge)
res.send(`Hello World!`);
});
$ npm run build
> advent-calendar-2024@1.0.0 build
> esbuild ./src/index.ts --bundle --minify --sourcemap --platform=node --outfile=./dist/index.js
dist/index.js 2.6kb
dist/index.js.map 10.6kb
⚡ Done in 13ms
型チェックで余計な時間を割くよりもビルドの速さを追い求めた結果なのでしょう。
VSCodeなどのIDEを使っていれば型の誤りがあると赤波線が出たりするのでそれで全然カバーできますし、CI/CDなどで tsc --noEmit
のステップを挟めば無問題でしょう。
esbuildを使った、TypeScriptで書かれた Node.js関数のビルドコマンドの完成系
ということで最終的なビルドコマンドは以下になります。この章以降でも引き続き esbuild を使っていきます。
{
// ...
"scripts": {
"build": "esbuild ./src/index.ts --bundle --minify --sourcemap --platform=node --format=esm --outfile=./dist/index.js"
}
// ...
}
ビルド結果として以下のようなものが出力されていれば、無事実行できたと判断していいでしょう。
var o=()=>"hogehoge";var g=(r,e)=>{let t=o();console.log(t),e.send("Hello World!")};export{g as helloGET};
//# sourceMappingURL=index.js.map
おわりに
2章にわたってTypeScriptで書かれたNode.js関数のビルド方法(というよりビルドツールの紹介)をしてきました。
くれぐれも、流行っているからだとか周りがイケてると言っているから闇雲にビルドツールを選定するのではなく、きちんと目的や規模にあったものを選択してきましょうね。