Nuxt 是如何工作的?

Nuxt 是一个简洁但高度可定制的构建 Web 应用的框架。

本指南旨在帮助你更好地理解 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.configNuxt 模块 扩展构建时上下文,通过 Nuxt 插件 扩展运行时。

在构建生产环境应用时,nuxi build 会在 .output 目录中生成一个独立的构建结果,它不依赖于 nuxt.configNuxt 模块