理解模块结构

了解 Nuxt 模块的结构以及如何定义模块。

Nuxt 模块分为两种类型:

  • 已发布的模块通过 npm 进行分发——你可以在 Nuxt 官网 查看一些社区模块列表。
  • 「本地」模块存在于 Nuxt 项目内,可以是内联在 Nuxt 配置中 /docs/3.x/api/nuxt-config#modules,也可以在 modules 目录 中。

无论哪种情况,它们的工作方式都是相同的。

定义你的模块

使用起步模板时,你的模块定义位于 src/module.ts

模块定义是你模块的入口点。当你的模块在 Nuxt 配置中被引用时,Nuxt 会加载它。

在底层,Nuxt 模块定义是一个简单的(可能是异步的)函数,接受用户内联选项和一个用于与 Nuxt 交互的 nuxt 对象。

export default function (inlineOptions, nuxt) {
  // 你可以在这里做任何你想做的事情..
  console.log(inlineOptions.token) // `123`
  console.log(nuxt.options.dev) // `true` 或 `false`
  nuxt.hook('ready', (nuxt) => {
    console.log('Nuxt 已准备就绪')
  })
}

你可以使用 Nuxt Kit 提供的更高级别的 defineNuxtModule 辅助函数来获得该函数的类型提示。

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule((options, nuxt) => {
  nuxt.hook('pages:extend', (pages) => {
    console.log(`发现了 ${pages.length} 个页面`)
  })
})

但是,我们不推荐使用这种底层函数定义。相反,定义模块时,我们推荐使用带 meta 属性的对象语法来标识你的模块,尤其是在发布到 npm 时。

该辅助函数通过实现许多模块常用的模式,使编写 Nuxt 模块更简单,确保未来的兼容性,并提升模块作者和用户的体验。

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  meta: {
    // 通常是你的模块的 npm 包名称
    name: '@nuxtjs/example',
    // `nuxt.config` 中保存你的模块选项的键名
    configKey: 'sample',
    // 兼容性限制
    compatibility: {
      // 支持的 Nuxt 版本的语义化版本范围
      nuxt: '>=3.0.0',
    },
  },
  // 模块的默认配置选项,也可以是返回这些选项的函数
  defaults: {},
  // 注册 Nuxt 钩子的简写形式
  hooks: {},
  // 其它模块的配置 — 这不会确保其它模块在你的模块前运行,
  // 但可以让你在其运行前修改其配置
  moduleDependencies: {
    'some-module': {
      // 你可以指定模块的版本限制。如果用户安装了不同版本,
      // Nuxt 会在启动时报错。
      version: '>=2',
      // 默认情况下,moduleDependencies 会被加入 Nuxt 要安装的模块列表,
      // 除非设置了 `optional`。
      optional: true,
      // 任何应覆盖 `nuxt.options` 的配置。
      overrides: {},
      // 任何应设置的配置。它会覆盖模块默认值,
      // 但不会覆盖 `nuxt.options` 中设置的配置。
      defaults: {},
    },
  },
  // 包含你的模块逻辑的函数,可以是异步的
  setup (moduleOptions, nuxt) {
    // ...
  },
})

defineNuxtModule 返回一个包装函数,拥有底层 (inlineOptions, nuxt) 模块签名。该包装函数在调用你的 setup 函数前,会执行默认配置和其他必要步骤:

  • 支持自动合并模块选项的 defaultsmeta.configKey
  • 类型提示和自动类型推断
  • 确保模块仅安装一次,通过从 meta.namemeta.configKey 计算唯一键值
  • 自动注册 Nuxt 钩子
  • 基于模块元数据自动检查兼容性问题
  • 向 Nuxt 内部暴露 getOptionsgetMeta
  • 只要模块使用最新版本 @nuxt/kit 中的 defineNuxtModule,就保证向前及向后兼容
  • 与模块构建工具的集成

添加运行时代码

使用起步模板时,runtime 目录是 src/runtime/

模块和 Nuxt 配置中的所有内容一样,都不包含在你的应用运行时中。但是,你可能希望你的模块为它安装的应用提供或注入运行时代码。runtime 目录正是为了这点而设计的。

在 runtime 目录内,你可以提供任何与 Nuxt 应用相关的资产:

对于 服务器引擎 Nitro:

  • API 路由
  • 中间件
  • Nitro 插件

或者任何你想注入到用户 Nuxt 应用中的其它资产:

  • 样式表
  • 3D 模型
  • 图片
  • 等等

然后你就能从你的 模块定义 中注入所有这些资产到应用中。

教程章节 中了解更多关于资产注入的内容。
已发布模块无法利用其 runtime 目录中的资产的自动导入功能。相反,它们必须显式从 #imports 或类似路径导入这些资产。

为了性能考虑,自动导入功能不会启用 node_modules 目录(发布模块最终的存放位置)中的文件。