Nuxtはどうやってfile-based routingを実現しているか2
趣旨
勝手に続編を作ってしまいすいません🙇
元の記事ではNuxtのfile-based routingを実現するためのコアな部分(routerに渡すroutesの解決方法と、作成したrouterをvueに適用する処理を行うpluginの実装部分)が分かりやすく解説されており参考になります。元の記事でのfile-based routingを実現するpluginの定義周りの解説に加えて、定義されたpluginをNuxtがどのように処理してブラウザが読み込めるようにしているのかをこの記事ではまとめていきたいと思います。
↓元の記事はこちら
全体感について
かなり大雑把な全体感ですが、nuxtのコアなinterfaceとしてNuxtとNuxtAppが存在し、ユーザーの設定等を解決して作成されるNuxtと、そのNuxtから作成されるNuxtAppに分かれています。NuxtAppには実際にユーザーのアプリケーション上で動くコードに関わるプロパティが定義されており、NuxtAppがgenerateAppによって処理される事によって動的にコードが生成されます。ユーザーのアプリケーション上で動くコードは当然アプリケーションによって違うものの、最終的にはブラウザに読み込める形として文字列として生成する必要があり、その部分をNuxtAppが吸収する形となっています。
nuxiがloadNuxtを呼び出す
nuxi dev
でnuxiが実行されると、nuxiはloadNuxtを呼び出してNuxtを作成します。
こちらがnuxiがloadNuxtを実行する部分です。
loadNuxtの返り値はPromise<Nuxt>になっており、このNuxtは後でbuildNuxtに渡すために使用されます。
installModuleでnuxt.options.pluginsにrouterを追加
loadNuxtを実行するとinstallModuleも実行され、ここでpagesModuleが実行されます。
pagesModuleではaddPluginが呼び出されており、ここでnuxt.options.pluginにrouterのpluginが追加されます。
nuxiがbuildNuxtを呼び出す
nuxiはloadNuxtによって読み込んだNuxtをbuildNuxtに渡します。
generateAppでnuxt.options.pluginsに定義されているpluginsをまとめてexportするコードを生成
buildNuxtではcreateAppでNuxtからNuxtAppを作成し、作成したNuxtAppをgenerateAppに渡します。
generateAppではNuxtAppをresolveAppで解決します。
resolveAppでaddPluginによってnuxt.options.pluginsに追加されたpluginがapp.pluginsに追加されます。
generateAppで生成されるplugins.client.mjsというコードは、app.plugins定義されているpluginsの中でclient側で読み込む必要のあるpluginを全てimportできるようなコードとなっています。
entry.tsでvueAppを作成しpluginを適用する
エントリーポイントの16行目でpluginsを読み込み、83行目でpluginを適用しています。
ところで、generateAppで生成したpluginsをまとめてエクスポートするコードのファイル名はplugins.client.mjs
だったはずですが、どうして#build/plugins
でimportできるのでしょうか?
#buildの部分はエイリアスで解決できそうですが、.clientの部分は厳しそうです。
その答えはNuxtが追加しているviteのpluginにあり、ここで#build/plugins
という同じmodule specifierでもclientとserverのpluginsを分けて読み込む仕組みが実現されています。
まとめ
どちらかというと「どうやってfile-based routingを実現しているか」というより、デフォルトで定義されているプラグインやユーザーによって定義されるプラグインをどのようにブラウザに実行させているのかという抽象的な内容になってしまいましたが、元の記事がこの記事を書くきっかけとなったので、このタイトルにさせてもらいます。
また、まだまだ未完成で日本語版も出来ていませんが、Nuxtをstep by stepで実装するchibinuxtの方も実装中なので、興味があればそちらの方もよろしくお願いします。
Discussion