app.js はこういうの
https://github.com/fastify/fastify-cli/blob/v6.1.1/templates/app-esm/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 CLI から使われるのみですが この app.js をプラグインとして使うこともできます
主にテストなどで使われます
https://github.com/fastify/fastify-cli/blob/v6.1.1/templates/app-esm/test/helper.js
テスト以外でも app のインスタンスを作ってそこからグローバルのプラグインで追加したメソッドを使うと便利かなと思ったのですが
import helper from "fastify-cli/helper.js"
const app = await helper.build([path_to_app_js], {})
app.foo()
これで foo が見つからないエラーでした
foo は plugins フォルダ内のプラグインで decorate しています
原因は Fastify のインスタンスに app.js のプラグインを register するときにカプセル化を有効にしていることでした
カプセル化されると app.js の内部では参照できますが 外側からは参照できません
app.js のデフォルトでは上のコードの通り プラグインの関数は fastify-plugin でラップされていません
ここはあまりいじることを想定されてないみたいですし ラップしないのが推奨なようです
実際 他のアプリと混ぜて同じサーバーで動かしたいときなどでは プラグイン全体をカプセル化して特定のプレフィックス以下に配置したいユースケースはありそうですし ラップしないのは正しい気がします
ですが 今回みたいにラップして 外側から参照できるようにカプセル化しないようにしたい場合もあります
となると app.js を使う側の Fastify CLI で fastify-plugin を通してほしいです
オプションで切り替えれるのかなと探したのですが そういうのはないようでした
https://github.com/fastify/fastify-cli/blob/v6.1.1/start.js#L149
現状だと仕方ないので app.js 側で fastify-plugin を通すしかなさそうです
他アプリと混ぜて使う想定がないなら常に fastify-plugin を通しても問題なさそうですが 環境変数を見て変えるということもできそうです
[app.js]
// 前略
const App = async function (fastify, opts) {
// 略
}
if (!process.env.ENCAPSULATE_APP) {
App = fp(App)
}
export default App