コンテンツにスキップ

開発コンソール

開発のループでは、小さな疑問が次々に湧きます。どのマイグレーションが適用済みか。 あのテーブルには実際に何が入っているのか。この文はハンドラが期待するものを返すのか。 404 のエラーページはどう見えるのか。あのアセットは本当に思っている場所から配信されて いるのか。

それぞれに専用ツールはあります。しかし合わせれば 4 つのアプリケーションで、うち 3 つは 接続文字列を貼り付ける必要があり、1 つは別プロセスが開いている SQLite ファイルには そもそも到達できません。

pw dev は起動時にもうひとつアドレスを表示します。

pw dev: console http://127.0.0.1:18081

ホバーで展開され、コンソールへのリンクとタブを閉じるまで隠すボタンが現れた pw dev ランチャー

以下のすべてがそのページ上にあり、すでに動いているプロジェクトを指しています。 そのための設定は何もしていません。

プロジェクト名、環境、開発ループの現在のフェーズ、reseed ボタン、ペイン一覧が並ぶコンソールの概要ページ

概要ページはループそのものです。いまどのフェーズにいるか、最後に変わったのはいつか、 失敗したならその診断結果が出ます。アプリケーションへのリンクは別タブで開きます。 ペインは用途とともに一覧され、プロジェクトが無効にしたペインは消えるのではなく、 どの設定で戻せるかを表示します。

ナビゲーションはどのペインでも同じで、ペインがスクロールしても画面上部に留まります。 その右端にある API リファレンスは外部リンクです。そのページはアプリケーション自身の ものであり、ランタイム設定が指定したパスで配信されるからです。

データペインは、アプリケーションが開いたデータベースを、アプリケーションが開いた その接続の上で見るテーブルブラウザです。この後半部分が、別ツールではなくここにある 理由です。SQLite のデータベースは 1 プロセスが掴んでいるファイルであり、:memory: に至ってはファイルですらありません。どちらもアプリケーションの外からは届きません。 だからこのペインはアプリケーションの中で動きます。

SQLite データベースのテーブル一覧。スキーマのバージョンが示され、フレームワークが管理するテーブルにはその旨の印が付く

ヘッダーはどの接続か、どのエンジンか、スキーマがどのバージョンかを示します。 goose_db_version のようなフレームワーク側のテーブルには印が付くので、 プロジェクト自身のテーブルが際立ちます。

テーブルを開くとまずデータが出て、スキーマはタブひとつ隣にあります。

memos テーブル。フィルタ欄があり、表の先頭と末尾に挿入用の空行、各行に del ボタンが並ぶ

行はその場で編集できます。変更したセルは赤くなり、その行の del ボタンは revert に変わります。行が「これから何が起きるか」を語り、戻る道は進む道と同じ場所にあります。 save を押すまでデータベースには何も届きません。行ごとの save でも、上部の save all でもかまいません。表の両端にある空行が挿入を書き込む場所で、空のままにした列は スキーマが決めた既定値を取ります。

ソートとフィルタはページ内で完結します。サーバーに問い合わせないからこそ、 編集途中の内容を失わずに使えます。

編集を終えて元に戻す道は概要ページにあります。reseed はプロジェクトの シードデータセットを適用します。clear-insert なので、 対象のテーブルは一度空にされてから入れ直されます。

ステートメントコンソールは、同じ接続に対して 1 文を実行します。

2 つのテーブルを結合する SELECT と、それが返した 3 行が表示されたステートメントコンソール

読み取りには上限がありますが、書き込みにはありません。開発用データベースは 試す場所だからです。explain は文を実行せずに実行計画だけを読みます。

プロジェクトの .pw.sql に書かれた文が、パラメータとともにすべて並びます。

公開・非公開それぞれの文が、パラメータ名と型とともに並ぶ宣言済みクエリの一覧

ここから実行すると、アプリケーションが組み立てるのと同じ文が組み立てられます。 SQL を写したものではなく、生成されたビルダそのものです。非公開の文も一覧され、 むしろここで試す価値が最も高いのはそれです。プロジェクト内の他のどこからも、 まだ呼べないからです。

パラメータには型があります。フォームのフィールドで表現できない型を取る文も一覧には 残ります。生成が見落としたのかと悩まずに、見つかってはいることが分かるためです。

storybook は、プロジェクトのテンプレートを 1 つずつ、パラメータ型から合成した値で レンダリングします。

単体でレンダリングされた 404 エラーテンプレート。rendered と HTML のタブがあり、下に編集可能なパラメータ欄がある

各ストーリーはレンダリング結果か、生成された HTML を整形したものを表示します。 下のパラメータは編集でき、書き換えて再レンダリングすれば、テンプレートに別の問いを 投げられます。プロジェクトのスタイルシートはストーリーに読み込まれるので、 Tailwind を使ったテンプレートはアプリケーション上と同じ見た目になります。

テンプレートはドキュメントシェルの中と単体のどちらでもレンダリングできます。 ページを確認するのか断片を確認するのかの違いです。

非公開のテンプレートも含まれます。非公開の文と同じ理由です。どちらのレジストリも pwdev ビルドタグの下でプロジェクト自身のパッケージに生成されます。プロジェクトが 公開していないシンボルは、他のどこからも届かないからです。

doctor ペインは、いまのプロジェクトに対して pw doctor を実行した結果です。ターミナルに戻る必要はありません。

検査項目とその結果、エラー・警告・注意の件数がまとまった doctor ペイン

テレメトリビューアは別アドレスではなく、 コンソールの最後のペインです。リクエストはメソッドとパスで命名されるので、 トレースの一覧がそのまま元のリクエストとして読めます。

コンソール内のテレメトリビューア。GET / や GET /assets/app.css といったトレースと、プロセスのメモリ・スレッド数が並ぶ

コンソールの一部は、コンソールの上にありません。ひとつめは失敗したときに出ます。 生成、マイグレーション、ビルド——ループのどれかが失敗すると、その失敗は アプリケーションが配信するページの上に重ねて表示されます。壊れたビルドが、後ろの ターミナルではなく、すでに開いているタブで見えるようにするためです。 アプリケーションが差し替わったページは自分でリロードします。

もうひとつは、入口のほうです。コンソールのアドレスは起動時に一度表示されるだけで、 実際に見たくなる頃——リビルドを何度か挟んだ後——には、もう画面の外にあります。 そこで、アプリケーションが配信するすべてのページの隅に小さなボタンが浮かび、 専用のタブでコンソールのインデックスを開きます。もう一度押しても新しいタブは 増えず、さっきのタブに戻ります。ループが 2 つの動くアプリケーションの間にいる間は ボタンにリングがつきます。そのページが古いことを告げるものは、他にありません。

リンクと状態表示、それだけです。リクエスト一覧もクエリ数も、処理時間のパネルも、 アプリケーション側のページには出しません。それらはテレメトリビューア のもので、あちらなら失敗したビルドより長生きします。

assets ペインは、アプリケーションが静的に配信しているもの、それぞれの出どころ、 配信時の種別を一覧します。ファイルがあるはずなのに 404 になるとき、そして編集した 場所とは違うところから配信されているときの答えがここにあります。

コンソールは開発用の面であり、リリースビルドには構造的に存在しません。レジストリも、 ペインも、それらが必要とするブラウザ側のコードも、すべて pwdev ビルドタグを持ちます。 pw build はそれをコンパイルもリンクもせず、配信もできません。 本番で有効にするフラグはありません。有効にする対象がそもそも無いからです。

スキーマの編集機能はありません。このフレームワークでスキーマが変わる手段は マイグレーションであり、コンソールからも変えられるなら、同じ問いに対する答えが 2 つになってしまいます。ペインはスキーマがどのバージョンかを報告するだけで、 動かす手段はマイグレーションです。

コンソールは既定で動きます。アドレスは起動時に表示され、任意のサブシステムに依存する ペイン——テレメトリ、データベース——は、それが設定されていれば現れ、されていなければ 何を設定すればよいかを表示します。

ペインごとに個別のキーがあるので、ひとつを止めることはコンソールを止めることでは ありません。

設定 効果
dev.console.enabled false にするとコンソールなしでループが動く
dev.console.port コンソールのポート。既定は 18081
dev.console.assets.enabled 静的ファイルのペイン
dev.console.data.enabled データペイン、ステートメントコンソール、クエリ実行
dev.console.storybook.enabled テンプレートの storybook
dev.console.overlay.enabled アプリケーションのページに重ねる失敗表示
dev.console.overlay.reload アプリケーションが差し替わったページのリロード
dev.console.launcher.enabled 同じページに浮かぶコンソールへのリンク
dev.console.launcher.corner どの隅に置くか。既定は bottom-left
dev.otel.enabled false にするとテレメトリのペインが消える

ランチャーの置き場所は左下です。右下はアプリケーション自身が浮かせたコントロールを 置く場所だからで、フレームワークがそこを取るわけにはいきません。とはいえ左下が 塞がっていることもあります。固定フッタ、自前のウィジェット——避けて使うのではなく、 動かしてください。pw init は隅の設定を popcornweb.toml に書き出すので、 開いてすぐ直せます。

[dev.console.launcher]
corner = "top-right"

4 つの隅は bottom-leftbottom-righttop-lefttop-right です。それ以外の値は この 4 つを挙げた設定エラーになります。打ち間違いが既定値として静かに読まれることは ありません。新しい隅は次の再起動から効きます。ファイルを編集すれば、その再起動は どのみち起きます。

ちょうど下にあるものを何度か押したい、という数分のためには、ホバーで現れるボタンで タブを閉じるまで隠せます。恒久的に消すなら dev.console.launcher.enabledfalse にしてください。

オーバーレイとランチャーの両方を外すことが、開発時のページを本番のページと バイト単位で同一にする方法です。どちらも付いていなければ、ブラウザが読み込むものは 何も配信されません。片方だけを外せばもう片方は動いたままです。設定がひとつではなく 2 つあるのはそのためです。

ポートは他の開発用リスナーと違い、予約ではなく固定です。ブックマークして一日中 戻ってくる面が、実行のたびに動くわけにはいきません。