この記事をおすすめしたい人
- Nuxt v3のフックで処理したい人
- フックがv2と変わり過ぎていて困惑している人
- つまりオレ
Nuxt v3の調査、フック編です。
ライフサイクルとかあまり分かってないんですが、力技でどうにか目的を達成するために力技でフック一覧を調べてみます。
基礎的な知識が欠落した人間が書いているので、詳しい人にはあまり役に立たないかも。
フックの種類
Nuxt v3のフックは3種類あって、処理するモジュール?で区別されてるっぽい?
そういうのがよく分からない僕みたいな人間にとって最も重要なのは、それぞれ定義する場所が違う点です。 書き方も違います。
あとは発生するタイミングがけっこう明確に分かれてました。
Nuxt Hooks (build time)
ビルド時に発生するフックで一覧はこちら。
後で出て来ますが、これらはページ表示よりもかなり早い段階、「npm run dev」を実行して準備している間に発生しました。
Nuxtフックの定義はnuxt.config.tsに書きます(超重要)。
export default defineNuxtConfig({
hooks: {
'modules:before': () => {
console.log('modules:before')
},
}
})
App Hooks (runtime)
ページ表示時前半に発生するフックで一覧はこちら。
Appフックの定義はpluginsフォルダに作ったプラグインに書きます(超重要)。 自動インポートされます。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('page:loading:start', () => console.log('page:loading:start'))
})
Nitro App Hooks (runtime, server-side)
ページ表示時後半に発生するフックで一覧はこちら。
Nitroフックの定義はserverフォルダ内のpluginsフォルダに作ったサーバプラグインに書きます(超重要)。 自動インポートされます。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
console.log('render:html')
})
})
ビルド時のフック発生順序
各フックでconsole.logして発生順を調べました。 フックの処理の具体例があまりないので、これでアタリをつけて引数の中身見たりして目的を達成しようと思います。
ビルド時に発生というだけあって、序盤はNuxtフックばかりが発生しました。
重複を省いて発生順序順にこんな↓感じでした。
modules:before
kit:compatibility
pages:routerOptions
imports:sources
imports:context
imports:dirs
imports:extend
builder:generateApp
modules:done
schema:extend
schema:resolved
nitro:config
nitro:init
ready
listen
prepare:types
app:resolve
components:dirs
app:templates
pages:extend
components:extend
app:templatesGenerated
build:before
vite:extend
vite:extendConfig
vite:configResolved
vite:serverCreated
server:devHandler
build:manifest
build:done
schema:beforeWrite
schema:written
nitro:build:before
今回の調査の目的にあまり関係ない部分だったので、これ以上は調べていません。
ページ表示時のフック発生順序
先にAppフックから4つが実行されます。
page:loading:start
app:created
vue:setup
app:rendered
その次にNitroフックが4つ実行されて終わりでした。
render:html
render:response
beforeResponse
afterResponse
今回の調査の目的はAMP用に展開済みのスタイルシートをひとまとめにすることだったんですが、afterResponseの段階でもlink rel=”stylesheet”の状態で、詰まってしまいました。 まぁ最後がafterResponseと分かったのはよかったです。
エラーが発生した場合はafterResponseは発生せずにerrorが発生するので、beforeResponseでどうにか処理か?
ちょっと詳しく調べたフック
Nitroフックのみいくらか調べました。
render:html
ページのHTMLレンダリング開始時?に発生するフックですたぶん。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
})
})
引数のhtmlは生のHTMLではなくて、headとかbodyの中身がバラバラになったオブジェクト↓になっていました。
{
island: false,
htmlAttrs: [],
head: [],
bodyAttrs: [],
bodyPrepend: [],
body: [],
bodyAppend: []
}
ここで内容を変えれば以降のHTMLが書き換わります。
第二引数についてはNuxtの方ではeventが設定されていて、Nitroの方ではそもそもこのフック自体が消えています。
実際にeventを参照するとundefinedで怒られたので、引数はhtmlだけなのかも。 そんでNitroがアップデートしたらこのフック自体消えるのかも?
render:response
render:htmlの次に呼ばれるフックです。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:response', (response, { event }) => {
})
})
引数のresponseはこの↓ようなオブジェクトになっていて、
{
body: '<!DOCTYPE html><html></html>',
statusCode: 200,
statusMessage: undefined,
headers: {
'content-type': 'text/html;charset=utf-8',
'x-powered-by': 'Nuxt'
}
}
bodyにはHTML全体が入っています。 ここに代入すればHTMLが書き換わります。
このフックはNitroにもあって引数eventが書かれているんですがundefinedでした。
beforeResponse
render:responseの次に呼ばれるフックです。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook("beforeResponse", (event, { body }) => {
})
})
bodyの方にHTMLが入っています。 書き換えは不可? 空にしても表示されるHTMLは元のままでした。
eventの方にはH3Eventという型のオブジェクトが入っていました。 中身は見てないです。
afterResponse
beforeResponseの次に呼ばれるフックです。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook("afterResponse", (event, { body }) => {
})
})
引数はbeforeResponseと同じで、bodyが書き換え不可っぽいのも同じでした。
Nuxt.js v3の目次
- 第1回 インストール方法とかフォルダ構成の違いとか
- 第2回 nuxt.config.jsの書き方の違い
- 第3回 注意が必要そうなモジュール
- 第4回 コンポーネントのscriptの書き方がめっちゃ変わった
- 第5回 trailingSlashに手動で対応
- 第6回 injectの代用品を3つ紹介
- 第7回 v-forとv-ifの併用の代替案
- 第8回 defineNuxtComponentは救世主!
- 第9回 composablesがめっちゃ強いかもしれない
- 第10回 手動でAMPに対応する
- 第11回 フック一覧を簡単に調べた(このページ)
- 第12回 axiosの代用品(useFetch、$fetch、useAsyncData)