Nuxt 是如何工作的?
本指南旨在帮助你更好地理解 Nuxt 的内部结构,以便在其基础上开发新方案和模块集成。
Nuxt 接口(Nuxt Interface)
当你使用 nuxi dev
启动开发模式,或使用 nuxi build
构建生产应用时,Nuxt 会创建一个通用上下文,在内部称为 nuxt
。
这个上下文包含与 nuxt.config
文件合并后的标准化配置选项、一些内部状态,以及一个强大的 钩子系统,该系统由 unjs/hookable 提供支持,使不同组件能够相互通信。你可以将其视为 构建核心(Builder Core)。
该上下文可以通过 Nuxt Kit 的组合式 API 全局访问。因此,每个进程只允许运行一个 Nuxt 实例。
要扩展 Nuxt 接口并挂载到构建流程的不同阶段,我们可以使用 Nuxt 模块。
更多细节可查看 源代码。
NuxtApp 接口
当在浏览器或服务端渲染页面时,会创建一个共享上下文,称为 nuxtApp
。
该上下文包含 Vue 实例、运行时钩子,以及一些内部状态,比如 ssrContext 和用于水合的 payload。你可以将其视为 运行时核心(Runtime Core)。
你可以在 Nuxt 插件、<script setup>
或 Vue 的组合式函数中,通过 useNuxtApp()
访问该上下文。
在浏览器端可以全局访问,但在服务端不允许这么做,以避免用户间共享上下文。
由于当上下文不可用时,useNuxtApp
会抛出异常,如果你的组合式函数并不总是需要 nuxtApp
,可以改用 tryUseNuxtApp
,它在无法访问时会返回 null
而非抛出异常。
要扩展 nuxtApp
接口、挂载到运行时阶段或访问上下文,我们可以使用 Nuxt 插件。
关于该接口的更多信息,请查看 Nuxt App。
nuxtApp
拥有以下属性:
const nuxtApp = {
vueApp, // 全局 Vue 应用实例:https://vuejs.org/api/application.html#application-api
versions, // 包含 Nuxt 和 Vue 版本的对象
// 以下方法可用于调用和注册运行时 NuxtApp 钩子
// 源码:https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/nuxt.ts#L18
hooks,
hook,
callHook,
// 以下仅在服务端可访问
ssrContext: {
url,
req,
res,
runtimeConfig,
noSSR,
},
// 该对象会被字符串化并从服务端传递到客户端
payload: {
serverRendered: true,
data: {},
state: {}
}
provide: (name: string, value: any) => void
}
更多细节可查看 源代码。
运行时上下文 vs 构建时上下文
Nuxt 使用 Node.js 构建并打包项目,但也有运行时部分。
虽然这两部分都可以扩展,但运行时上下文是与构建时隔离的。因此,它们不应共享状态、代码或上下文(除了运行时配置)!
你可以通过 nuxt.config
和 Nuxt 模块 扩展构建时上下文,通过 Nuxt 插件 扩展运行时。
在构建生产环境应用时,nuxi build
会在 .output
目录中生成一个独立的构建结果,它不依赖于 nuxt.config
和 Nuxt 模块。