◆ fastify-cli でテンプレートからプロジェクトを作れる
  ◆ テンプレートでは @fastify/autoload を使うようになってる
◆ fastify-cli のコマンドからサーバーを起動できる
◆ autoload を使うと自動でフォルダ内のファイルをプラグインとして登録してくれる

これまで自作コードはプラグイン化せず Fastify を使っていたので プラグイン系のパッケージは使ってませんでした
ですが プラグイン化したほうが良さそうかなと思うことがあったのでこれらも使ってみることにしました

fastify-cli

まずは fastify-cli です

start

アプリの起動時に node コマンドを使わず 代わりに 「fastify start」 コマンドを使います

yarn fastify start app.js

app.js は Fastify のプラグイン関数をエクスポートする JavaScript ファイルです
サーバーを起動したりする部分は fastify-cli が中でやってくれるので ルートやフックなどの登録のみすれば良いようになっています
シンプルな例だとこれだけで動きます

[app.js]
export default async (fastify, opts) => {
fastify.get("/", async (request, reply) => {
return { ok: true }
})
}

eject

「fastify eject」 を実行すると server.js を作ってくれます
これが 「fastify start」 時に内部で実行している内容です
自分でサーバーの起動をカスタマイズしたい場合は server.js を作って編集してから このファイルを node コマンドで実行するようにすれば良いです

中でやってることは単純でほぼ普通に Fasitfy を起動するだけです
50 行もないコードです

特別なところは close-with-grace を使ってるくらいです
このライブラリでは SIGTERM と SIGINT シグナルを受けたり ハンドルされていないエラーが起きたときにサーバーを正常に終了してから Node.js プロセスを終了させるためのものです

また eject では package.json の type を見てくれません
CJS 用の server.js が出力されます
ESM 用が欲しいなら --esm オプションが必要です

yarn fastify eject --esm

generate

fastify-cli では用意されたプロジェクトテンプレートから新規プロジェクトを作ることもできます
「fastify generate」 コマンドでフォルダを指定します
ここでも ESM を使うなら --esm が必要です

mkdir fastify-generate-test
cd fastify-generate-test
yarn dlx fastify-cli generate . --esm
yarn install

作られたファイルはこうなりました

- .gitignore
- app.js
- package.json
- README.md
+ plugins/
- README.md
- sensible.js
- support.js
+ routes/
- README.md
- root.js
+ example/
- index.js
+ test/
- helper.js
+ plugins/
- support.test.js
+ routes/
- example.test.js
- root.test.js

いくつかのサンプルが用意されてます

app.js の中身はこうなってます

import path from 'path'
import AutoLoad from '@fastify/autoload'
import { fileURLToPath } from 'url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// Pass --options via CLI arguments in command to enable these options.
export const options = {}

export default async function (fastify, opts) {
// Place here your custom code!

// Do not touch the following lines

// This loads all plugins defined in plugins
// those should be support plugins that are reused
// through your application
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'plugins'),
options: Object.assign({}, opts)
})

// This loads all plugins defined in routes
// define your routes in one of these
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'routes'),
options: Object.assign({}, opts)
})
}

@fastify/autoload を使っていて plugins と routes フォルダを autoload するようなっています
基本は plugins と routes フォルダにファイルを追加して行けばよくて app.js は触れなくて良くなっています

@fastify/autoload

@fastify/autoload ではプラグインを自動でロードしてくれます
autoload というと PHP のクラスの仕組みが思い浮かぶかもですが あれとは違って 必要になったからロードするものではなく 最初に全部をロードします
指定のフォルダ内の全部のファイルが対象です

fastify-cli で生成したテンプレートだと plugins と routes フォルダが対象になっているのでこのフォルダ内の .js ファイルは全部ロードされます
フォルダも再帰的に探索されるので

plugins/plugin1.js
plugins/dir1/plugin2.js
plugins/dir1/plugin3.js
plugins/dir2/dir3/plugin4.js

があったときに plugin1.js ~ plugin4.js まで全部ロードされプラグインとして登録されます

例外的に フォルダ内に index.js があったときは index.js だけがロードされます
index.js 以外のファイルは index.js から自分で import するプラグイン以外のファイルとして扱われます

これらはデフォルトの動きなので 無視するパスなどを設定することは可能です

autoload のプラグインでは細かな使い方を指定されてはいないですが Fastify 公式の fastify-cli で生成されるテンプレートで用意されている方法に沿っておくのが無難でいいのかもしれませんね
plugins と routes フォルダを用意して それぞれ次のような使い分けです

plugins フォルダは カプセル化せず Fastify サーバー全体を対象に機能追加など拡張するプラグインを配置する場所です
export するとき fastify-plugin でラップします

routes フォルダはカプセル化を有効にして ルートを定義するプラグインを配置する場所です
ルートの定義だけでなく フックを登録したり それらで使うプラグインの登録もしたりします

fastify-cli と @fastify/autoload を使った例のプロジェクトも用意されています
fastify-example