全文検索を実装したくてVercelに乗り換えた。今まではAlgolia使ってたけど、無料プランだと記事本文をインデックスに載せることができなくてタイトル検索のみだったけれど、どうしても全文検索を入れたかったのでどうやらServerless Functionsを無料で使えるVercelに乗り換えた。が、本当にこれ無料?というのを何度もLimitsのページを見て確認しているが多分無料。デプロイ回数とか1デプロイあたりの作成可能な数は制限されているが、多分大丈夫なはず。これ1関数内でexpressとかでいい感じにルーティングしちゃえばあんまり関係なくないか?
わりと細かい部分にハマった。前提としてこのブログのソース自体はghostで、先に記事をjsonとしてfetchした上でserverMiddlewareで記事を返すAPIサーバーを立てて、記事ページなどではそのAPIを読み出す実装をしている(逐一読み取る実装でも良かったけどビルド時に時間がかかりそうだったため。ちなみにgenerate前にfetchしてroutesでルーティングを返す時にpayloadを投げてやれば解決しそうなのでこれは問題解決の手法としては微妙である(実装したときは知らなかった))。vercel dev
はある程度フレームワークを読み取った上で/api
を読み取ってServerless functions化してくれるが、これがnuxt側のserverMiddlewareと競合するような形になる(なってるはず)なのでわちゃわちゃした。
別にvercel dev
は使わなくてもいいのだけれど、本番環境に近い形ではあるので動かして確認できるようにしたかった。ややこしいことに実際にhtml生成時に実行するnuxt-ts generate
は当然vercel dev
に依存しない形で実行されるので、ここも考慮する必要があった。が、これはvercelを使う以前からserverMiddlewareがgenerate時に実行されない問題はあったので、これはbuildModulesにgenerate前にserverMiddlewareに突っ込むものと同等のミドルウェアを持ったサーバーを立てる自作のモジュールを突っ込むことで対処した(これはフレームワーク側で対応してくれても良さそうだが…)。
話が逸れたが、ルーティングのナビゲーションに関して開発環境(SSR)(nuxt-ts
+vercel
)の2つ + ブラウザ側でのクライアントナビゲーションの3つがあって、ミドルウェアの追加周りではまった。結論としてはサーバーサイドとクライアントサイドでリクエストを送るときのbaseUrlを明示的に設定する必要があった。
export default {
http: {
baseURL: 'http://localhost:3000/api',
browserBaseURL: '/api'
}
}
http moduleを使った場合、こんな感じに。明示的にbaseURLを指定しいないと環境変数の兼ね合いのせいか無限にvercel1にリクエスト送ってそうな挙動だった(リクエストがいつまでも帰ってこずOOMエラーが出た)。baseURLは設定の柔軟性を考えたらあんまりlocalhost:3000
と書きたくなかったけれど、自分しかどうせやらんし変えるようなところでもないのでリテラルで記述。browserBaseURLは設定しないとbaseURLが使われてしまい、クライアントサイドでリクエストを送るときにビルドしたものでもlocalhostになってしまうのでホストを除いた記述で対応。
vercelのserverless functionsはいくつかexpressに似たヘルパー関数を提供してくれるようだが、NuxtのServer middlewareとの互換性を考えて使うのを辞めた。
というのを解決してようやく検索を実装した。fuse.jsを雑にぶちこんだだけ。Algoliaに比べてレスポンスは悪くなったが(Algoliaは早すぎる)、全文検索はできるようになって嬉しい。といっても検索ページを用意するわけでもなく簡素なフィルター機能であることには代わりはないが(検索ページはそのうち用意してもいいかも知れない)。
ちなみに私自身言うほど検索を使ってないので誰のためであるかは完全に不明である。
完全に技術記事になってしまった…。unsweets.logの方に書いてもいいけれどあちらはmarkdown with frontmatter形式で記事を書くのに若干敷居が高い。frontmatterの記述が嫌なのもあるが、どちらかといえば普段のエディタを開いて記事を編集してcommitするほうが抵抗あるのかも。早くPrismicあたりに移行してwebで記事をかけるようにするべきかな。