---
title: "理解模块结构"
description: "了解 Nuxt 模块的结构以及如何定义模块。"
canonical_url: "https://nuxt.zhcndoc.com/docs/3.x/guide/modules/module-anatomy"
---
# 理解模块结构

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

Nuxt 模块分为两种类型：

- 已发布的模块分发在 npm 上——你可以在 [Nuxt 网站](https://nuxt.zhcndoc.com/modules) 上查看一些社区模块的列表。
- “本地”模块存在于 Nuxt 项目中，可以[内联在 Nuxt 配置中](https://nuxt.zhcndoc.com/docs/3.x/api/nuxt-config#modules-1)，也可以位于 [`modules` 目录](https://nuxt.zhcndoc.com/docs/3.x/directory-structure/modules) 中。

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

## 定义你的模块

::note
使用起步模板时，你的模块定义位于 `src/module.ts`。
::

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

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

```ts
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](https://nuxt.zhcndoc.com/docs/3.x/guide/going-further/kit) 提供的更高层级的 `defineNuxtModule` 辅助函数，为此函数获取类型提示。

```ts
import { defineNuxtModule } from '@nuxt/kit'

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

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

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

```ts
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` 函数前，会执行默认配置和其他必要步骤：

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

## 添加运行时代码

::note
使用起步模板时，runtime 目录是 `src/runtime/`。
::

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

在 runtime 目录中，你可以提供与 Nuxt 应用相关的任意类型资源：

- Vue 组件
- Composables
- [Nuxt 插件](https://nuxt.zhcndoc.com/docs/3.x/directory-structure/plugins)

对于 [服务器引擎](https://nuxt.zhcndoc.com/docs/3.x/guide/concepts/server-engine) Nitro，可以提供：

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

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

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

然后你就能从你的 [模块定义](#%E5%AE%9A%E4%B9%89%E4%BD%A0%E7%9A%84%E6%A8%A1%E5%9D%97) 中注入所有这些资产到应用中。

::tip
在[配方部分](https://nuxt.zhcndoc.com/docs/3.x/guide/modules/recipes-basics)了解有关资产注入的更多信息。
::

::warning
已发布模块无法利用其 runtime 目录中的资产的自动导入功能。相反，它们必须显式从 `#imports` 或类似路径导入这些资产。
:br :br
为了性能考虑，自动导入功能不会启用 node_modules 目录（发布模块最终的存放位置）中的文件。
::


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
