Denoでブラウザで動くJSファイルをビルドするには
DenoでTypeScriptをブラウザで動くJavaScriptにビルドしたかったため調査した結果です。欲しい機能は以下です。
- JavaScriptモジュール(ES Modules)形式で出力したい。
- TypeScriptをJavaScript変換したい。
- Minifyしたい。
- 動的インポートで書いたファイルをコード分割したい。
- Tree Shakingしたい。
- 設定ファイル無し、コマンド一発でビルドしたい。
Denoのビルドツール
結論を述べるとDenoはまだまだ人口が少なくサードパーティモジュールが充実しておらず、これらの機能を満たすビルドツールがありませんでしたので、作ることにしました。
Denoバンドル
実は私もビルドツールを探し回っているときに知ったのですが、Deno標準のdeno bundle
コマンド、およびDeno.emit()
APIは、サーバーサイド・フロントエンド両用ではありません。
私はこれらを、サーバーサイドとブラウザの両方で使うためのバンドルツールだと勘違いしていました。こちらの解決済みのISSUEを読むと、開発陣はdeno bundle
はあくまでDenoで実行されるスクリプトを一つのファイルにまとめるために作ったというようなことを言っています。
公式マニュアルにはバンドルしたファイルがブラウザでもインポートできることが書かれていますので私は勘違いしてしまったのですが、それはDenoもブラウザも同じES Modulesなのでブラウザ向けのバンドルもできてしまうというだけだったのですね。
ということで、遠い将来は方針変更があるかもしれませんが、少なくともしばらくはDenoにブラウザ向けビルドツールが組み込まれることは無さそうです。
そもそもDenoはNode.jsと同じくサーバーサイドJavaScript実行環境ですので当たり前ですね。
Packup
PackupはParcel風のDeno用バンドルツールです。DenoのサードパーティモジュールはDenoのバージョンアップに追従していけていないものが多く、インストールしても動かないものがあったりするのですが、2022/01/17現在これは動きました。
欲しかった機能のほとんどを満たすのですが、動的インポートができなかったため今回は見送りました。
まだできることが少ないのですが、将来が期待されます。
SWC
SWCはRustで書かれたビルドツールです。最近はとても盛り上がっているように感じます。DenoもRustで書かれており、Denoの型チェックに使っているとのことですが、残念ながらまともに動くサードパーティモジュールがありませんでした。
esbuild
esbuildは公式にDenoでの使い方が書かれています。ちゃんと動きます。
ES Modulesも、TypeScriptも、Minifyも、動的インポートも、Tree Shakingもサポートしています。2022/01/17現在Denoで唯一まともなビルドツールと言えるかと思います。
しかし、残念なことにhttpsから始まるDenoのモジュールをインポートすることができません。また、今のところコマンドがありません。
結局どうしたらいいか
他にもDenoのビルドツールはありますが、動くかどうか確かめるだけでもひと苦労です。
Node.jsのような気軽な感じが全く無い・・・。
現実的な方法はesbuildを使って、Denoのモジュールを使えるようにするプラグインを合わせて使うことです。
私が開発中のライブラリBeako.jsでは、Denoのビルドツールが充実するまで、独自に簡易ビルドツールを設けることにしました。Beako.js専用ではないのでお困りの際はご利用ください。
あくまで、Denoのビルドツールが充実するまでの措置ですので、将来削除する可能性はあります。
deno moduleプラグイン
esbuild_deno_loaderというモジュールを使うと、httpsから始まるDenoのモジュールをインポートしてビルドすることができるようになります。
beako build
コマンド
上記プラグインだけを使ったesbuildをコマンドにしました。
コマンドをインストール
deno install -fA https://deno.land/x/beako_cli@0.2.0/beako.ts
ビルド実行
beako build script.ts --outdir=public
outdirのデフォルトはdistディレクトリです。ひとつのファイルにバンドルするときは--outfile=script.js
のようにします。
これでようやく欲しい機能がすべて揃いました。
Discussion