---
title: "插件"
description: "Nuxt Kit 提供了一组工具来帮助你创建和使用插件。你可以通过这些函数将插件或插件模板添加到你的模块中。"
canonical_url: "https://nuxt.zhcndoc.com/docs/3.x/api/kit/plugins"
---
# 插件

> Nuxt Kit 提供了一组工具来帮助你创建和使用插件。你可以通过这些函数将插件或插件模板添加到你的模块中。

插件是自包含的代码，通常用于为 Vue 添加应用级功能。在 Nuxt 中，插件会自动从 `plugins/` 目录导入。然而，如果你需要在模块中附带插件，Nuxt Kit 提供了 `addPlugin` 和 `addPluginTemplate` 方法。这些工具允许你自定义插件配置，更好地满足你的需求。

## `addPlugin`

注册一个 Nuxt 插件并将其添加到插件数组中。

::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/injecting-plugins?friend=nuxt" target="_blank"}
观看 Vue School 关于 `addPlugin` 的视频教程。
::

### 用法

```ts twoslash
import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    const { resolve } = createResolver(import.meta.url)

    addPlugin({
      src: resolve('runtime/plugin.js'),
      mode: 'client',
    })
  },
})
```

### 类型

```ts
function addPlugin (plugin: NuxtPlugin | string, options?: AddPluginOptions): NuxtPlugin
```

### 参数

**`plugin`**：插件对象或插件路径字符串。若传入字符串，则会被转换为插件对象，`src` 属性设置为该字符串值。

若传入插件对象，则必须包含以下属性：

| 属性      | 类型                                         | 是否必需    | 描述                                                                                                                                                 |
| ------- | ------------------------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src`   | `string`                                   | `true`  | 插件文件的路径。                                                                                                                                           |
| `mode`  | `'all' \| 'server' \| 'client'`{lang="ts"} | `false` | 设置为 `'all'` 时，插件会包含在客户端和服务器端的构建中；设置为 `'server'` 时只包含在服务器端构建；设置为 `'client'` 时只包含在客户端构建。你也可以在指定 `src` 时使用 `.client` 和 `.server` 修饰符，使插件仅在客户端或服务器端使用。 |
| `order` | `number`                                   | `false` | 插件的执行顺序。用于更细粒度地控制插件顺序，仅建议高级用户使用。数字越小越先执行，用户插件默认顺序为 `0`。建议将 `order` 设置在 `-20`（在 Nuxt 插件之前运行的 `pre` 插件）到 `20`（在 Nuxt 插件之后运行的 `post` 插件）之间。           |

::warning
除非必要，避免使用 `order`。如果你只是想在 Nuxt 默认插件之后注册插件，请使用 `append`。
::

**`options`**：可选对象，包含以下属性：

| 属性       | 类型        | 是否必需    | 描述                                                      |
| -------- | --------- | ------- | ------------------------------------------------------- |
| `append` | `boolean` | `false` | 若为 `true`，插件将追加到插件数组末尾；若为 `false`，则会插入数组开头。默认为 `false`。 |

### 示例

::code-group
```ts [module.ts]
import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    const { resolve } = createResolver(import.meta.url)

    addPlugin({
      src: resolve('runtime/plugin.js'),
      mode: 'client',
    })
  },
})
```

```ts [runtime/plugin.ts]
export default defineNuxtPlugin((nuxtApp) => {
  const colorMode = useColorMode()

  nuxtApp.hook('app:mounted', () => {
    if (colorMode.preference !== 'dark') {
      colorMode.preference = 'dark'
    }
  })
})
```
::

## `addPluginTemplate`

添加一个模板并注册为 Nuxt 插件。此方法适用于需要在构建时生成代码的插件。

::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/injecting-plugin-templates?friend=nuxt" target="_blank"}
观看 Vue School 关于 `addPluginTemplate` 的视频教程。
::

### 用法

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

export default defineNuxtModule({
  setup (options) {
    addPluginTemplate({
      filename: 'module-plugin.mjs',
      getContents: () => `import { defineNuxtPlugin } from '#app/nuxt'
export default defineNuxtPlugin({
  name: 'module-plugin',
  setup (nuxtApp) {
    ${options.log ? 'console.log("Plugin install")' : ''}
  }
})`,
    })
  },
})
```

### 类型

```ts
function addPluginTemplate (pluginOptions: NuxtPluginTemplate, options?: AddPluginOptions): NuxtPlugin
```

### 参数

**`pluginOptions`**：插件模板对象，包含以下属性：

| 属性            | 类型                                                                    | 是否必需    | 描述                                                                                                                                                 |
| ------------- | --------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src`         | `string`                                                              | `false` | 模板文件路径。若未提供 `src`，则必须提供 `getContents`。                                                                                                             |
| `filename`    | `string`                                                              | `false` | 模板文件名。若未提供，将从 `src` 路径生成，此时 `src` 属性必填。                                                                                                            |
| `dst`         | `string`                                                              | `false` | 目标文件路径。若未提供，将基于 `filename` 路径和 Nuxt 的 `buildDir` 选项生成。                                                                                             |
| `mode`        | `'all' \| 'server' \| 'client'`{lang="ts"}                            | `false` | 设置为 `'all'` 时，插件会包含在客户端和服务器端的构建中；设置为 `'server'` 时只包含在服务器端构建；设置为 `'client'` 时只包含在客户端构建。你也可以在指定 `src` 时使用 `.client` 和 `.server` 修饰符，使插件仅在客户端或服务器端使用。 |
| `options`     | `Record<string, any>`{lang="ts"}                                      | `false` | 传递给模板的参数。                                                                                                                                          |
| `getContents` | `(data: Record<string, any>) => string \| Promise<string>`{lang="ts"} | `false` | 接收 `options` 对象的函数，返回字符串或解析为字符串的 Promise。如果提供了 `src`，该函数将被忽略。                                                                                      |
| `write`       | `boolean`                                                             | `false` | 若为 `true`，模板将被写入目标文件；否则只存在于虚拟文件系统中。                                                                                                                |
| `order`       | `number`                                                              | `false` | 插件的执行顺序。用于更细粒度地控制插件顺序，仅建议高级用户使用。数字越小越先执行，用户插件默认顺序为 `0`。建议将 `order` 设置在 `-20`（在 Nuxt 插件之前运行的 `pre` 插件）到 `20`（在 Nuxt 插件之后运行的 `post` 插件）之间。           |

::warning
动态插件生成推荐使用 `getContents`。除非必要，避免设置 `order`。
::

**`options`**：可选对象，包含以下属性：

| 属性       | 类型        | 是否必需    | 描述                                                      |
| -------- | --------- | ------- | ------------------------------------------------------- |
| `append` | `boolean` | `false` | 若为 `true`，插件将追加到插件数组末尾；若为 `false`，则会插入数组开头。默认为 `false`。 |

### 示例

#### 根据不同选项生成插件模板

当你需要在构建时动态生成插件代码时，使用 `addPluginTemplate`。它允许你基于传入的选项动态生成不同的插件内容。例如，Nuxt 内部使用此功能生成 Vue 应用配置。

```ts twoslash [module.ts]
import { addPluginTemplate, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (_, nuxt) {
    if (nuxt.options.vue.config && Object.values(nuxt.options.vue.config).some(v => v !== null && v !== undefined)) {
      addPluginTemplate({
        filename: 'vue-app-config.mjs',
        write: true,
        getContents: () => `import { defineNuxtPlugin } from '#app/nuxt'
export default defineNuxtPlugin({
  name: 'nuxt:vue-app-config',
  enforce: 'pre',
  setup (nuxtApp) {
    ${Object.keys(nuxt.options.vue.config!)
        .map(k => `nuxtApp.vueApp.config[${JSON.stringify(k)}] = ${JSON.stringify(nuxt.options.vue.config![k as 'idPrefix'])}`)
        .join('\n')
    }
  }
})`,
      })
    }
  },
})
```

这会根据提供的配置生成不同的插件代码。

::code-group
```ts [nuxt.config.ts]
export default defineNuxtConfig({
  vue: {
    config: {
      idPrefix: 'nuxt',
    },
  },
})
```

```ts [#build/vue-app-config.mjs]
import { defineNuxtPlugin } from '#app/nuxt'

export default defineNuxtPlugin({
  name: 'nuxt:vue-app-config',
  enforce: 'pre',
  setup (nuxtApp) {
    nuxtApp.vueApp.config.idPrefix = 'nuxt'
  },
})
```
::

#### 使用 EJS 模板生成插件

你也可以使用 EJS 模板生成插件。通过 `options` 属性传递参数，并在 EJS 模板内使用这些参数生成插件内容。

::code-group
```ts [module.ts]
import { addPluginTemplate, createResolver, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    const { resolve } = createResolver(import.meta.url)

    addPluginTemplate({
      src: resolve('templates/plugin.ejs'),
      filename: 'plugin.mjs',
      options: {
        ssr: nuxt.options.ssr,
      },
    })
  },
})
```

```ejs [templates/plugin.ejs]
import { VueFire, useSSRInitialState } from 'vuefire'
import { defineNuxtPlugin } from '#imports'

export default defineNuxtPlugin((nuxtApp) => {
  const firebaseApp = nuxtApp.$firebaseApp
  nuxtApp.vueApp.use(VueFire, { firebaseApp })

  <% if(options.ssr) { %>
  if (import.meta.server) {
    nuxtApp.payload.vuefire = useSSRInitialState(undefined, firebaseApp)
  } else if (nuxtApp.payload?.vuefire) {
    useSSRInitialState(nuxtApp.payload.vuefire, firebaseApp)
  }
  <% } %>
})
```
::

::warning
如果你将 `compatibilityVersion` 设置为 `4`，Nuxt 默认不再使用 `lodash.template` 来编译模板。你仍然可以通过开启 `experimental.compileTemplate` 选项启用该功能，但 EJS 模板的支持将在下一个大版本中被完全移除。
::

---

- [源码](https://github.com/nuxt/nuxt/blob/main/packages/kit/src/plugin.ts)


## Sitemap

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