ちょっとしたフロントエンドの開発で、TypeScriptに最初から対応していて、簡単に使えるものは何かないかな、と調べてみたメモです。React/Vue/Angularの場合はそれぞれの初期化コマンドで何から何まで用意してくれます。Next.js、Nuxt.js、Gatsbyなども、これらのビルドのステップを簡略化するコマンドを提供しています。基本的にこれらのウェブフロントエンドを開発するときには、小規模・中規模ぐらいならあんまり気にしなくておまかせでもいいと思います。
今回は、それらのフレームワーク固有のビルドツールとは別に環境を作りたい人で、TypeScriptの環境が欲しい、ウェブの開発がしたい、という前提でいろいろ探してみました。
今回試してみたのは次の4つです。
- Parcel
- Fusebox
- ncc
- Rome.js
JavaScriptのビルドツールとは
JavaScriptでビルドといっても、いろいろなステップがあります。
- TypeScriptやBabelを使って、ターゲットとなるバージョンのJavaScriptに変換
- SCSSとかPostCSSを使ってブラウザにない機能を使って書かれたCSSを素のCSSに変換
- webpackなどを使って、1つのJavaScriptファイル、もしくは遅延ロードをするJSファイル群を生成
まあ実際にはこんなに綺麗にステップが分かれることはなくて、webpackがimport文を追跡しつつファイルを探し、.tsを見つけてはTypeScriptで処理して(コンパイル)、コード中にSCSSを見つけてはSCSSの処理系に投げて、1つのファイルにまとめる(バンドル)・・みたいな工程を行ったりきたりしながらビルドします。以前は、これにJake、Gulp、Gruntなどのタスクランナーも組み合わせてやってましたが、今はwebpack単体にts-loaderなどを組み合わせる感じで一通りできます。webpackがシェア80%で一強ですね。
なお、これにファイルの変更検知を行って、変更時に変更部分だけをビルド(ウォッチ)、読み込んでいるブラウザに変更したことを伝えてリロードを行わせる開発サーバーとよぶサーバーも加えると、世間で「JavaScriptのビルドツール」と呼ぶ機能はだいたい網羅されるんじゃないですかね。
Parcel
Parcelはゼロコンフィグを目指したバンドラーです。TypeScriptも最初からサポートしています。エントリーポイントを指定するだけでビルドしてくれます。tsconfig.jsonがあればそれを拾って解釈してくれますし、なくても動きます。単にtsファイルをエントリーポイントとしてわたしてあげれば、そのままTypeScriptの処理系をインストールしつつビルドしてくれます。最初のビルドも高速ですし、キャッシュもしてくれて2回目以降も速いです。TreeShakingとかの生成されたファイルの最適化機構も入っているとのこと。
npm install -D parcel-bundler |
エントリーポイントにHTMLファイルを指定できて、フロントエンド開発の開発サーバーも付いている。これは無敵! と思いきや・・・わざと型を間違ったTypeScriptのファイルを入力しても何もエラーも出ません。
これは現在は意図した動作らしく、Parcelは最速でバンドルするだけを目指しており、設計方針としてエラーは出さないとのこと。もしかしたら、TypeScriptで開発し、Visual Studio CodeとかWebStorm上でエラーが出てくるなら問題ないとも言えるかもしれません。とはいえ、せっかくのチェック機構をまったく無視するのはTypeScriptを使うメリットがだいぶ削られてしまいます。また、別途CIなりを整備するのもちょっと手間ですよね。まあ、TypeScriptとかが流行る前は型チェックなんてなかったわけで、ちょっと昔の感覚を思い出しました。
Parcel 2系になったらTypeScriptのエラーを報告しない問題に対応するよ、と昨年のコメントにはあるものの、次の2.0のリリースまでのハードルはかなり高そう。2.0が出てさえくれれば設定のかんたんさとかは抜群なので、期待しています。
FuseBox
FuseBoxはそこそこ歴史はあるツールですが、ここで紹介する他のツールと違い、CLIを提供しません。JavaScriptかTypeScriptでビルドの設定ファイルを作ります。現状は3系ですが、これも新バージョンの4系が開発中で、@next
をつけてインストールします。
npm install -D fuse-box@next |
4系の最小は以下の通りです。これはデバッグビルドのための開発サーバーを立ち上げて開発支援をする、という設定ファイルです。
import { fusebox } from 'fuse-box'; |
テンプレートのところのHTMLはこんな感じで、CSSとJavaScriptの成果物を$なプレースホルダーに埋め込むようになっています。
|
とはいっても、デバッグ実行だけがしたいわけじゃなくて、productionビルドもしたいわけで、そうなるとたくさん書かないといけない。一応、フルセットのサンプルとして以下のようなコードが提示されています(今回はReactを作りたいわけではないので.tsxは.tsに書き換えました)。ここまで書かないといけないのであれば、CLIツールも一緒に提供してほしい気が・・・
import { fusebox, sparky } from "fuse-box"; |
ビルドは高速で快適です。tsconfig.jsonがなくても実行できます。なお、Node.js 10.xや11.xのバージョンではまだexperimentalなworker_threadパッケージを使っているので、12以降を使うか、--experimental-worker
オプションが必要です。開発サーバーもあり、HMRもできて、ウェブフロントエンド開発でTypeScriptでやりたい人には良いですね。
% npm start |
ncc
npmにアップロードするコードをシンプルにする、超快適に開発する、というのを目指して作られているのがnccです。ある意味browserifyの後継な感じを受けます。簡単。ひたすら簡単。Next.jsで有名なZeitが開発しています。
npm install -D @zeit/ncc |
npmのサイズを小さくするという目標を体現しているツールで、それ自身もTypeScript内臓だけど、インストールは一瞬で終わります。他への依存もなく、パッケージがとても小さい。
$ du -h |
コマンド体系はGoを目指していて、ncc build [script]でビルドができます。ncc run [script]で実行ができます。
% npx ncc run -q test.ts |
ts-nodeは実行にtypescriptパッケージが必要で、ts-nodeとtypescriptをインストールするとそれだけで52MBぐらいになってしまうので、ncc runをts-nodeがわりにするのも良さそうです。tsconfig.jsonは必要です。
コマンドは基本的にbuildとrunだけなので使い方は迷うことはないと思います。--watch
で監視しつつビルドしたり、--minify
で小さくしたり。
一方、ウェブフロントエンドの開発を手助けしてくれる開発サーバーはありません。ExpressとかでAPIサーバーを実装するには良さそうです。
Rome.js
こちらは超新進気鋭のビルドツールです。日本Node.jsユーザグループの会長に「かいちょー、何かJSのバンドラー兼ビルドサーバーまわりで、なんか新しげな良いのないですか」と聞いて教えてもらいました。
Babelの作者とかが関わっているツールです。コンパイラ、Linter、フォーマッター、テスト、バンドラーなどを全部まとめて持っていて、外部依存がないのがウリとのこと。なお、ウェブサイトはありますが、それよりもGitHubのREADMEの方がいろいろプロジェクトの背景等が詳しく書かれていたりします(実行の仕方の説明はREADMEは古くて動かないですが)。
npmにも上がっていないので、git clone
するところから。
git clone --depth 1 https://github.com/facebookexperimental/rome |
このヘルプメッセージから溢れ出るexperimental感。残念ながら、開発サーバーとかはないようです。Facebookなので、ウェブフロントエンドだけではなくて、React Nativeとかもターゲットに考えているのかもしれないし、そこのあたりはよくわかりません。
% npx rome --help |
rome run test.ts
で実行はできましたが、残念ながら、現段階ではこれもParcel同様型情報を削ぎ落としているだけっぽくて、TypeScriptの型チェックのエラーは出ませんでした。READMEには”Don’t use loose types such as any
“と強く書かれているので、型には厳しくなっていくと思われます。
基本方針の中には、修正方法を開発者に伝えないようなエラーメッセージはなくしていく、とか、「トークン」みたいなコンパイラ内部用語(ジャーゴン)が外に出ないようにして、コンパイラ視点ではなくて、プログラマー視点の用語の「文字」を出すようにしていく、みたいなことも書いてあるのは面白いなと思いました。単にTypeScriptとかに変換処理を投げるだけじゃなくて、その出力もラップして、開発者にとって使いやすい処理系を目指しています。なかなかに野心的なプロジェクトです。
・・・人に紹介するにはまだまだexperimentalすぎる感じはありますが。会長曰く「僕も試してないです。渋川さんなら一番早く書籍にしてくれるはず」とのこと。
まとめ
まだ正式リリースしていないバージョンも含めて、TypeScriptに最初から対応しているビルド・バンドルツールをいくつか紹介してきました。webpack一強だからこそ、そのwebpackにはない強みを出そうと活発に開発されています。このあたりのエコシステムの活発さはNode.js界隈はやはり強いですね。
まあ、お金をいただいてやる仕事はまだまだwebpackでいいかな・・・と思いつつ、手元でちょっと新しいライブラリを試行錯誤する時とかに、新しいものも使ってみようと思います。とりあえず、FuseBox@nextと、nccはすでに実用に耐えられるレベルかな、と思います。今回はウェブフロントエンド開発をするという前提で開発サーバーの有無とかも紹介しましたが、そうなるとFuseBoxは良さそうです。本当は使い捨てのサンプルで活用したかったので、そのユースケースにいちばんマッチしているParcel 2もリリースされたら使ってみようと思います。Rome.jsも新しい開発体験を目指していそうだし、開発者が強い人たちなので楽しみです。