Nuxt 3 简介

nuxt3
Created 9/16/2022
Updated 3/7/2023

Nuxt 3 简介

Nuxt 是一个全栈开发框架,可以用它同时进行服务端和前端的开发。

参考

它主要整合以下技术构成其核心模块,提供一个更佳的开发环境:

  • Vue.js 作为 Nuxt 3 的前端框架,以实现视图的响应式和组件化
  • WebpackVite 作为打包工具,在开发环境提供模块热替换 HMR 功能,在生产环境提供打包功能
  • esbuild 作为转译器,所以可以使用最新的 JavaScript 语法进行开发
  • vue-router 实现客户端的路由导航
  • h3 管理 API endpoint 和 Middleware,实现服务器端的路由导航,也可以实现服务端渲染。h3 可以让部署满足多样性,例如无服务器、web workers、Node.js,并提供极佳的性能。更多与服务端相关的信息可以查看官方文档 Server EngineServer Directory

内部工作机制

Nuxt 保留极简的核心功能,同时提供了模块系统以便扩展,它可高度定制的特性可以让所构建的 web 应用适合各种场景。

以下是 Nuxt 的运行机制,主要是关于 Build Context 构造时上下文和 Runtime Context 运行时上下文,对其有初步的了解便于后续对 Nuxt 的核心进行扩展。

Nuxt 使用 Node.js 构建和打包应用时,会生成一个上下文 Build Context,而在应用运行时则会生成另一个上下文 Runtime Context,两个上下文都可以进行定制和扩展。

运行时上下文 Runtime Context 应该独立于构建时上下文 Build Context,所以除了运行时相关的配置参数 runtimeConfig,它们的状态、数据、函数方法等并不应该相互共享。

Nuxt Interface

当在终端中执行命令 nuxi dev 以开发模式(或执行命令 nuxi build 以生成模式)启动 Nuxt 时,会创建一个通用的上下文 context,它在内部被称为 nuxt,也称为 Nuxt Interface 接口

这个上下文 context 包含了(将默认值和 nuxt.config.ts 文件中的选项合并)经过标准化之后的配置选项 normalized options,一些内部状态 internal state,以及与构建相关的钩子函数 hook

💛 可以将它视为应用的 Builder Core 构造器的核心

Nuxt Interface 在(构建过程中 ❓)全局都可及的 globally available,可以通过 @nuxt/kit 模块包所导出的组合式 API useNuxt() 来获取。

注意

nuxt/kit 模块包所提供这些工具函数只能够在模块 module 中使用,并不能在运行时 runtime 中使用(包括组件、Vue 的组合式 API、网页页面、插件或服务端的路由中)

因为这个上下文是全局可及的,所以在构建 Nuxt 应用的每个进程中,只允许运行一个 Nuxt 实例。

可以通过构建 Nuxt Module 模块,使用相应的钩子函数在不同的构建过程中执行相应的操作 hook into different stages,来拓展这个上下文

提示

关于构建模块的细节,可以查看另一篇笔记《Nuxt 3 模块系统》


大致流程如下:

  1. 首先要在构建模块的项目中安装依赖包 @nuxt/kit
    package.json
    json
    {
      "dependencies": {
        "@nuxt/kit": "npm:@nuxt/kit-edge@latest"
      }
    }
    
  2. 然后就可以在项目中该模块所提供的 composable utilities 工具函数
    ts
    // 导入工具函数
    import { useNuxt } from '@nuxt/kit'
    
    // 获取上下文 nuxt
    const nuxt = useNuxt()
    
    注意

    nuxt/kit 是一个 esm-only 模块包,所以不能通过 require('@nuxt/kit') 方式导入,可以在 CommonJS 环境中使用动态导入

    js
    // This does NOT work!
    // const kit = require('@nuxt/kit')
    async function main() {
      const kit = await import('@nuxt/kit')
    }
    main()
    

NuxtApp Interface

在浏览器(或服务端)渲染页面时,则会生成一个共享上下文 shared context,称为 nuxtApp,也称为 NuxtApp Interface 接口

这个上下文 context 包含了 Vue 实例,运行时相关的钩子函数 hook,一些内部状态 internal state

该上下文对象具体包含以下属性:

ts
// refer to https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/nuxt.ts
const nuxtApp = {
  // the global Vue application
  // refer to https://vuejs.org/api/application.html#application-api
  vueApp,

  // an object containing Nuxt and Vue versions
  versions,

  // These let you call and add runtime NuxtApp hooks
  // https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/nuxt.ts#L18
  hooks,
  hook,
  callHook,

  // Only accessible on server-side
  ssrContext: {
    url,
    req,
    res,
    runtimeConfig,
    noSSR,
  },

  // This will be stringified and passed from server to client
  payload: {
    serverRendered: true,
    data: {},
    state: {}
  }

  provide: (name: string, value: any) => void
}

💛 可以将它视为应用的 Runtime Core 运行核心

NuxtApp Interface 可以通过组合式 API useNuxtApp() 来获取

说明

该组合式 API 在浏览器/前端全局都可以被调用,具体是在 Nuxt 插件中、<script setup> 代码块中,和 vue 的组合式 API 中使用。

vue
<script setup>
const nuxtApp = useNuxtApp()
</script>

该组合式 API 在服务器/后端也可以使用,但并不是全局可用,以避免在不同用户之间共享这个上下文 context 造成数据泄露。

在服务端渲染页面时,只能在 Nuxt 插件、<script setup> 代码块(或 setup 函数)、生命周期钩子函数中才可以使用 useNuxtApp 函数

可以通过构建 Nuxt Plugin 插件来拓展这个上下文,其中插件定义函数的第一个参数就是 nuxtApp

提示

关于构建插件的细节,可以查看另一篇笔记《Nuxt 3 插件》


常见的使用场景如下

ts
// 在 Nuxt Plugin 中定义一个 helper 工具函数
// 并添加到运行时上下文 nuxtApp 中
// 以便在 Nuxt 应用的其他地方使用
const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)

console.log(nuxtApp.$hello('name')) // Prints "Hello name!"

优化开发体验

Nuxt 3 以 Vue 3 作为前端框架,如果平时使用 Vue 的 SFC 进行开发(全称是 Single File Components 单文件组件,也就是 *.vue 文件),可以无缝过渡,即无需配置就可以在 Nuxt 中使用 SFC 进行开发。

Tip

Nuxt 3 是基于 Vue 3,支持 Composition API 组合式 API,而且也是原生支持 TypeScript

此外 Nuxt 还对开发体验细节进行了优化,例如:

  • 在项目中不需要创建 📄 main.js 文件(以创建 Vue 实例),因为 Nuxt 会在「后台」自动创建
  • 在 📁 components/ 目录下创建的 Vue 组件,Nuxt 会在打包项目自动导入所用的组件。所以在其他地方使用这些组件时,无需手动导入就可以直接使用,优化了开发体验。而且对于没有使用的组件,在生产环境中并不会对其进行打包,自动优化了生产的结果。
  • <script setup> 标签内使用 Vue 3 的响应式 API,例如 ref(),不需要导入,可以直接使用,因为 Nuxt 3 会在编译时自动导入这些 API,优化了开发体验
  • 基于 📁 pages/ 目录下的文件层级结构,Nuxt 3 会自动使用 Vue Router 创建相应的页面路由
  • 提供了多种数据获取的方法,对不同的场景进行优化
  • 无需进行额外的配置就可以得到对 Typescript 的支持
推荐

关于 Nuxt 3 开发体验 DX 更详细介绍可以查看另一篇笔记《Nuxt 3 特色功能》


Copyright © 2024 Ben

Theme BlogiNote

Icons from Icônes