模块作者指南

学习如何创建 Nuxt 模块以集成、增强或扩展任何 Nuxt 应用程序。

Nuxt 的配置钩子系统使得定制 Nuxt 的各个方面以及添加您可能需要的任何集成(Vue 插件、CMS、服务器路由、组件、日志记录等)成为可能。

Nuxt 模块是在开发模式下使用nuxt dev启动 Nuxt 或使用nuxt build构建生产项目时顺序运行的函数。通过模块,您可以封装、正确测试和共享自定义解决方案作为 npm 包,而无需向项目添加不必要的样板代码,也无需更改 Nuxt 本身。

快速开始

我们建议您使用我们的入门模板:

npm create nuxt -- -t module my-module

这将创建一个my-module项目,其中包含开发和发布模块所需的所有样板代码。

后续步骤

  1. 在您选择的 IDE 中打开my-module
  2. 使用您喜欢的包管理器安装依赖项
  3. 使用npm run dev:prepare准备本地文件进行开发
  4. 按照本文档了解有关 Nuxt 模块的更多信息

使用入门模板

了解如何使用模块入门模板执行基本任务。

观看 Vue School 关于 Nuxt 模块入门模板的视频。

如何开发

虽然您的模块源代码位于src目录中,但在大多数情况下,要开发一个模块,您需要一个 Nuxt 应用程序。这就是playground目录的作用。它是一个 Nuxt 应用程序,您可以对其进行修改,该应用程序已配置为与您的模块一起运行。

您可以像使用任何 Nuxt 应用程序一样与 playground 交互。

  • 使用npm run dev启动其开发服务器,当您在src目录中更改模块时,它应该会自动重新加载。
  • 使用npm run dev:build构建它
所有其他nuxt命令都可以针对playground目录使用(例如nuxt <COMMAND> playground)。您可以在package.json中随意声明其他dev:*脚本,以方便引用它们。

如何测试

模块入门模板带有一个基本的测试套件

  • 一个由ESLint支持的 Linter,运行它使用npm run lint
  • 一个由Vitest支持的测试运行器,运行它使用npm run testnpm run test:watch
您可以随意增强此默认测试策略以更好地满足您的需求。

如何构建

Nuxt 模块自带其自己的构建器,由@nuxt/module-builder提供。此构建器不需要您进行任何配置,支持 TypeScript,并确保您的资产正确打包以便分发到其他 Nuxt 应用程序。

您可以通过运行npm run prepack来构建您的模块。

虽然构建模块在某些情况下很有用,但大多数情况下您不需要自行构建它:playground在开发时会处理它,发布脚本在发布时也会为您提供支持。

如何发布

在将您的模块发布到 npm 之前,请确保您有一个npmjs.com帐户,并且您已使用npm login在本地进行身份验证。

虽然您可以通过提升版本并使用npm publish命令来发布模块,但模块入门模板附带了一个发布脚本,可帮助您确保将工作版本的模块发布到 npm 等。

要使用发布脚本,首先,提交所有更改(我们建议您遵循Conventional Commits以利用自动版本提升和变更日志更新),然后运行发布脚本npm run release

运行发布脚本时,将发生以下情况

  • 首先,它将通过以下方式运行您的测试套件
    • 运行 Linter (npm run lint)
    • 运行单元、集成和端到端测试 (npm run test)
    • 构建模块 (npm run prepack)
  • 然后,如果您的测试套件运行良好,它将通过以下方式发布您的模块
    • 根据您的 Conventional Commits 提升模块版本并生成变更日志
    • 将模块发布到 npm(为此目的,模块将再次构建,以确保其更新的版本号在发布的 artifact 中得到考虑)
    • 将表示新发布版本的 git 标签推送到您的 git 远程源
与所有其他脚本一样,您可以随意调整package.json中默认的release脚本,以更好地满足您的需求。

开发模块

Nuxt 模块附带各种强大的 API 和模式,允许它们以几乎任何可能的方式更改 Nuxt 应用程序。本节教您如何利用这些功能。

模块解剖

我们可以考虑两种 Nuxt 模块

在这两种情况下,它们的结构都相似。

模块定义

使用入门模板时,您的模块定义可在src/module.ts找到。

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

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

export default function (inlineOptions, nuxt) {
  // You can do whatever you like here..
  console.log(inlineOptions.token) // `123`
  console.log(nuxt.options.dev) // `true` or `false`
  nuxt.hook('ready', (nuxt) => {
    console.log('Nuxt is ready')
  })
}

您可以使用Nuxt Kit提供的更高级别的defineNuxtModule助手获取此函数的类型提示支持。

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule((options, nuxt) => {
  nuxt.hook('pages:extend', (pages) => {
    console.log(`Discovered ${pages.length} pages`)
  })
})

然而,**我们不推荐**使用这种低级函数定义。相反,为了定义模块,**我们推荐**使用带有meta属性的对象语法来标识您的模块,尤其是在发布到 npm 时。

这个助手通过实现模块所需的许多常见模式,使编写 Nuxt 模块更加直接,保证了未来的兼容性,并改善了模块作者和用户的使用体验。

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  meta: {
    // Usually the npm package name of your module
    name: '@nuxtjs/example',
    // The key in `nuxt.config` that holds your module options
    configKey: 'sample',
    // Compatibility constraints
    compatibility: {
      // Semver version of supported nuxt versions
      nuxt: '>=3.0.0',
    },
  },
  // Default configuration options for your module, can also be a function returning those
  defaults: {},
  // Shorthand sugar to register Nuxt hooks
  hooks: {},
  // Configuration for other modules - this does not ensure the module runs before
  // your module, but it allows you to change the other module's configuration before it runs
  moduleDependencies: {
    'some-module': {
      // You can specify a version constraint for the module. If the user has a different
      // version installed, Nuxt will throw an error on startup.
      version: '>=2',
      // By default moduleDependencies will be added to the list of modules to be installed
      // by Nuxt unless `optional` is set.
      optional: true,
      // Any configuration that should override `nuxt.options`.
      overrides: {},
      // Any configuration that should be set. It will override module defaults but
      // will not override any configuration set in `nuxt.options`.
      defaults: {},
    },
  },
  // The function holding your module logic, it can be asynchronous
  setup (moduleOptions, nuxt) {
    // ...
  },
})

最终,defineNuxtModule返回一个包装函数,该函数具有较低级别的(inlineOptions, nuxt)模块签名。此包装函数在调用您的setup函数之前应用默认值和其他必要步骤。

  • 支持defaultsmeta.configKey以自动合并模块选项
  • 类型提示和自动类型推断
  • 添加基本 Nuxt 2 兼容性的填充
  • 使用从meta.namemeta.configKey计算的唯一键确保模块只安装一次。
  • 自动注册 Nuxt 钩子
  • 根据模块元数据自动检查兼容性问题
  • 为 Nuxt 内部使用公开getOptionsgetMeta
  • 只要模块使用最新版本@nuxt/kit中的defineNuxtModule,就确保向后和向前兼容性
  • 与模块构建工具链集成

运行时目录

使用入门模板时,运行时目录位于src/runtime

模块,就像 Nuxt 配置中的所有内容一样,不包含在您的应用程序运行时中。但是,您可能希望您的模块提供或将运行时代码注入到安装它的应用程序中。这就是运行时目录允许您执行的操作。

在运行时目录中,您可以提供与 Nuxt 应用程序相关的任何类型的资产

服务器引擎,Nitro

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

或您想要注入用户 Nuxt 应用程序的任何其他类型的资产

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

然后,您将能够从您的模块定义中将所有这些资产注入到应用程序中。

菜谱部分了解有关资产注入的更多信息。
已发布的模块无法利用其运行时目录中的资产自动导入。相反,它们必须从#imports或类似方式显式导入它们。

确实,出于性能原因,node_modules中的文件(已发布模块最终将位于的位置)未启用自动导入。

工具

模块带有一套第一方工具来帮助您开发它们。

@nuxt/module-builder

Nuxt 模块构建器是一个零配置构建工具,负责构建和发布您的模块的所有繁重工作。它确保您的模块构建工件与 Nuxt 应用程序的适当兼容性。

@nuxt/kit

Nuxt Kit提供了可组合的实用程序,可帮助您的模块与 Nuxt 应用程序交互。建议尽可能使用 Nuxt Kit 实用程序而不是手动替代方案,以确保模块具有更好的兼容性和代码可读性。

文档 > 4 X > 指南 > 深入 > 工具包中阅读更多内容。

@nuxt/test-utils

Nuxt Test Utils是一个实用程序集合,可帮助在模块测试中设置和运行 Nuxt 应用程序。

秘诀

在这里查找用于编写模块的常见模式。

修改 Nuxt 配置

Nuxt 配置可以被模块读取和修改。这是一个启用实验性功能的模块示例。

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    // We create the `experimental` object if it doesn't exist yet
    nuxt.options.experimental ||= {}
    nuxt.options.experimental.componentIslands = true
  },
})

当您需要处理更复杂的配置更改时,您应该考虑使用defu.

观看 Vue School 关于修改 Nuxt 配置的视频。

向运行时公开选项

由于模块不属于应用程序运行时的一部分,它们的选项也不属于。但是,在许多情况下,您可能需要在运行时代码中访问其中一些模块选项。我们建议使用 Nuxt 的runtimeConfig公开所需的配置。

import { defineNuxtModule } from '@nuxt/kit'
import { defu } from 'defu'

export default defineNuxtModule({
  setup (options, nuxt) {
    nuxt.options.runtimeConfig.public.myModule = defu(nuxt.options.runtimeConfig.public.myModule, {
      foo: options.foo,
    })
  },
})

请注意,我们使用defu来扩展用户提供的公共运行时配置,而不是覆盖它。

然后,您可以在插件、组件、应用程序中像访问任何其他运行时配置一样访问您的模块选项。

import { useRuntimeConfig } from '@nuxt/kit'

const options = useRuntimeConfig().public.myModule
请注意不要在公共运行时配置中暴露任何敏感的模块配置,例如私有 API 密钥,因为它们最终会出现在公共捆绑包中。
文档 > 4 X > 指南 > 深入 > 运行时配置中阅读更多内容。
观看 Vue School 关于传递和公开 Nuxt 模块选项的视频。

使用addPlugin注入插件

插件是模块添加运行时逻辑的常用方式。您可以使用addPlugin实用程序从您的模块中注册它们。

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

export default defineNuxtModule({
  setup (options, nuxt) {
    // Create resolver to resolve relative paths
    const resolver = createResolver(import.meta.url)

    addPlugin(resolver.resolve('./runtime/plugin'))
  },
})
文档 > 4 X > 指南 > 深入 > 工具包中阅读更多内容。

使用addComponent注入 Vue 组件

如果您的模块应该提供 Vue 组件,您可以使用addComponent实用程序将它们添加为 Nuxt 解析的自动导入。

import { addComponent, createResolver, defineNuxtModule, useRuntimeConfig } from '@nuxt/kit'

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

    // From the runtime directory
    addComponent({
      name: 'MySuperComponent', // name of the component to be used in vue templates
      export: 'MySuperComponent', // (optional) if the component is a named (rather than default) export
      filePath: resolver.resolve('runtime/components/MySuperComponent.vue'),
    })

    // From a library
    addComponent({
      name: 'MyAwesomeComponent', // name of the component to be used in vue templates
      export: 'MyAwesomeComponent', // (optional) if the component is a named (rather than default) export
      filePath: '@vue/awesome-components',
    })
  },
})

或者,您可以使用addComponentsDir添加整个目录。

import { addComponentsDir, defineNuxtModule } from '@nuxt/kit'

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

    addComponentsDir({
      path: resolver.resolve('runtime/components'),
    })
  },
})

使用addImportsaddImportsDir注入可组合项

如果您的模块应该提供可组合项,您可以使用addImports实用程序将它们添加为 Nuxt 解析的自动导入。

import { addImports, createResolver, defineNuxtModule } from '@nuxt/kit'

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

    addImports({
      name: 'useComposable', // name of the composable to be used
      as: 'useComposable',
      from: resolver.resolve('runtime/composables/useComposable'), // path of composable
    })
  },
})

或者,您可以使用addImportsDir添加整个目录。

import { addImportsDir, createResolver, defineNuxtModule } from '@nuxt/kit'

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

    addImportsDir(resolver.resolve('runtime/composables'))
  },
})

使用addServerHandler注入服务器路由

import { addServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'

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

    addServerHandler({
      route: '/api/hello',
      handler: resolver.resolve('./runtime/server/api/hello/index.get'),
    })
  },
})

您还可以添加动态服务器路由。

import { addServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'

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

    addServerHandler({
      route: '/api/hello/:name',
      handler: resolver.resolve('./runtime/server/api/hello/[name].get'),
    })
  },
})

注入其他资产

如果您的模块应该提供其他类型的资产,它们也可以被注入。这是一个简单的示例模块,通过 Nuxt 的css数组注入样式表。

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

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

    nuxt.options.css.push(resolver.resolve('./runtime/style.css'))
  },
})

以及一个更高级的示例,通过NitropublicAssets选项公开一个资产文件夹。

import { createResolver, defineNuxtModule } from '@nuxt/kit'

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

    nuxt.hook('nitro:config', (nitroConfig) => {
      nitroConfig.publicAssets ||= []
      nitroConfig.publicAssets.push({
        dir: resolver.resolve('./runtime/public'),
        maxAge: 60 * 60 * 24 * 365, // 1 year
      })
    })
  },
})

在模块中使用其他模块

如果您的模块依赖于其他模块,您可以使用 Nuxt Kit 的installModule实用程序添加它们。例如,如果您想在模块中使用 Nuxt Tailwind,您可以如下添加它

import { createResolver, defineNuxtModule, installModule } from '@nuxt/kit'

export default defineNuxtModule<ModuleOptions>({
  async setup (options, nuxt) {
    const resolver = createResolver(import.meta.url)

    // We can inject our CSS file which includes Tailwind's directives
    nuxt.options.css.push(resolver.resolve('./runtime/assets/styles.css'))

    await installModule('@nuxtjs/tailwindcss', {
      // module configuration
      exposeConfig: true,
      config: {
        darkMode: 'class',
        content: {
          files: [
            resolver.resolve('./runtime/components/**/*.{vue,mjs,ts}'),
            resolver.resolve('./runtime/*.{mjs,js,ts}'),
          ],
        },
      },
    })
  },
})

使用钩子

生命周期钩子允许您扩展 Nuxt 的几乎所有方面。模块可以以编程方式或通过其定义中的hooks映射来挂接到它们。

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

export default defineNuxtModule({
  // Hook to the `app:error` hook through the `hooks` map
  hooks: {
    'app:error': (err) => {
      console.info(`This error happened: ${err}`)
    },
  },
  setup (options, nuxt) {
    // Programmatically hook to the `pages:extend` hook
    nuxt.hook('pages:extend', (pages) => {
      console.info(`Discovered ${pages.length} pages`)
    })
  },
})
文档 > 4 X > API > 高级 > 钩子中阅读更多内容。
观看 Vue School 关于在模块中使用 Nuxt 生命周期钩子的视频。
模块清理

如果您的模块打开、处理或启动了一个观察器,您应该在 Nuxt 生命周期完成后关闭它。close钩子可用于此目的。
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    nuxt.hook('close', async (nuxt) => {
      // Your custom code here
    })
  },
})
自定义钩子

模块还可以定义和调用自己的钩子,这是使您的模块可扩展的强大模式。

如果您希望其他模块能够订阅您模块的钩子,您应该在modules:done钩子中调用它们。这确保了所有其他模块都有机会在自己的setup函数中进行设置并向您的钩子注册其监听器。

// my-module/module.ts
import { defineNuxtModule } from '@nuxt/kit'

export interface ModuleHooks {
  'my-module:custom-hook': (payload: { foo: string }) => void
}

export default defineNuxtModule({
  setup (options, nuxt) {
    // Call your hook in `modules:done`
    nuxt.hook('modules:done', async () => {
      const payload = { foo: 'bar' }
      await nuxt.callHook('my-module:custom-hook', payload)
    })
  },
})

添加模板/虚拟文件

如果您需要添加一个可以导入到用户应用程序中的虚拟文件,您可以使用addTemplate实用程序。

import { addTemplate, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    // The file is added to Nuxt's internal virtual file system and can be imported from '#build/my-module-feature.mjs'
    addTemplate({
      filename: 'my-module-feature.mjs',
      getContents: () => 'export const myModuleFeature = () => "hello world !"',
    })
  },
})

对于服务器,您应该改用addServerTemplate实用程序。

import { addServerTemplate, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    // The file is added to Nitro's virtual file system and can be imported in the server code from 'my-server-module.mjs'
    addServerTemplate({
      filename: 'my-server-module.mjs',
      getContents: () => 'export const myServerModule = () => "hello world !"',
    })
  },
})

添加类型声明

您可能还希望向用户的项目添加类型声明(例如,增强 Nuxt 接口或提供您自己的全局类型)。为此,Nuxt 提供了addTypeTemplate实用程序,该实用程序既可以将模板写入磁盘,又可以在生成的nuxt.d.ts文件中添加对它的引用。

如果您的模块应该增强 Nuxt 处理的类型,您可以使用addTypeTemplate来执行此操作。

import { addTemplate, addTypeTemplate, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    addTypeTemplate({
      filename: 'types/my-module.d.ts',
      getContents: () => `// Generated by my-module
        interface MyModuleNitroRules {
          myModule?: { foo: 'bar' }
        }
        declare module 'nitropack/types' {
          interface NitroRouteRules extends MyModuleNitroRules {}
          interface NitroRouteConfig extends MyModuleNitroRules {}
        }
        export {}`,
    })
  },
})

如果您需要更细粒度的控制,您可以使用prepare:types钩子注册一个回调来注入您的类型。

const template = addTemplate({ /* template options */ })
nuxt.hook('prepare:types', ({ references }) => {
  references.push({ path: template.dst })
})
更新模板

如果您需要更新模板/虚拟文件,可以使用updateTemplates实用程序,如下所示

nuxt.hook('builder:watch', (event, path) => {
  if (path.includes('my-module-feature.config')) {
    // This will reload the template that you registered
    updateTemplates({ filter: t => t.filename === 'my-module-feature.mjs' })
  }
})

测试

测试有助于确保您的模块在各种设置下按预期工作。在本节中,了解如何对模块执行各种类型的测试。

单元和集成

我们仍在讨论和探索如何简化 Nuxt 模块的单元和集成测试。

查看此 RFC 加入讨论.

端到端

Nuxt Test Utils是帮助您以端到端方式测试模块的首选库。以下是其采用的工作流程:

  1. test/fixtures/*内部创建一个 Nuxt 应用程序作为“夹具”
  2. 在您的测试文件中使用此夹具设置 Nuxt
  3. 使用@nuxt/test-utils中的实用程序与夹具交互(例如,获取页面)
  4. 执行与此夹具相关的检查(例如,“HTML 包含……”)
  5. 重复

实际上,夹具

test/fixtures/ssr/nuxt.config.ts
// 1. Create a Nuxt application to be used as a "fixture"
import MyModule from '../../../src/module'

export default defineNuxtConfig({
  ssr: true,
  modules: [
    MyModule,
  ],
})

及其测试

test/rendering.ts
import { describe, expect, it } from 'vitest'
import { fileURLToPath } from 'node:url'
import { $fetch, setup } from '@nuxt/test-utils/e2e'

describe('ssr', async () => {
  // 2. Setup Nuxt with this fixture inside your test file
  await setup({
    rootDir: fileURLToPath(new URL('./fixtures/ssr', import.meta.url)),
  })

  it('renders the index page', async () => {
    // 3. Interact with the fixture using utilities from `@nuxt/test-utils`
    const html = await $fetch('/')

    // 4. Perform checks related to this fixture
    expect(html).toContain('<div>ssr</div>')
  })
})

// 5. Repeat
describe('csr', async () => { /* ... */ })
这样的工作流程示例可在模块入门模板.

使用 Playground 和外部进行手动 QA

在开发模块时拥有一个 playground Nuxt 应用程序来测试您的模块非常有用。模块入门模板为此集成了一个

您可以使用其他 Nuxt 应用程序(不属于模块存储库的应用程序)在本地测试您的模块。为此,您可以使用npm pack命令或您的包管理器等效命令,从您的模块创建 tarball。然后,在您的测试项目中,您可以将您的模块添加到package.json包中,如下所示:"my-module": "file:/path/to/tarball.tgz"

之后,您应该能够像在任何常规项目中一样引用my-module

最佳实践

能力越大,责任越大。虽然模块功能强大,但在编写模块时请牢记以下最佳实践,以保持应用程序高性能和出色的开发体验。

异步模块

正如我们所见,Nuxt 模块可以是异步的。例如,您可能希望开发一个需要获取一些 API 或调用异步函数的模块。

然而,请注意异步行为,因为 Nuxt 会等待您的模块设置完毕,然后才能转到下一个模块并启动开发服务器、构建过程等。最好将耗时的逻辑推迟到 Nuxt 钩子。

如果您的模块设置时间超过1 秒,Nuxt 将发出警告。

始终为公开的接口添加前缀

Nuxt 模块应为任何公开的配置、插件、API、可组合项或组件提供明确的前缀,以避免与其他模块和内部冲突。

理想情况下,您应该以模块的名称为它们添加前缀(例如,如果您的模块名为nuxt-foo,则公开<FooButton>useFooBar(),而不是<Button>useBar())。

使用生命周期钩子进行一次性设置

当您的模块需要执行一次性设置任务(如生成配置文件、设置数据库或安装依赖项)时,请使用生命周期钩子,而不是在主setup函数中运行逻辑。

import { addServerHandler, defineNuxtModule } from 'nuxt/kit'
import semver from 'semver'

export default defineNuxtModule({
  meta: {
    name: 'my-database-module',
    version: '1.0.0',
  },
  async onInstall (nuxt) {
    // One-time setup: create database schema, generate config files, etc.
    await generateDatabaseConfig(nuxt.options.rootDir)
  },
  async onUpgrade (options, nuxt, previousVersion) {
    // Handle version-specific migrations
    if (semver.lt(previousVersion, '1.0.0')) {
      await migrateLegacyData()
    }
  },
  setup (options, nuxt) {
    // Regular setup logic that runs on every build
    addServerHandler({ /* ... */ })
  },
})

这种模式可以防止每次构建时进行不必要的工作,并提供更好的开发体验。有关更多详细信息,请参阅生命周期钩子文档

支持 TypeScript

Nuxt 具有一流的 TypeScript 集成,可提供最佳的开发体验。

即使不直接使用 TypeScript,公开类型和使用 TypeScript 开发模块也会使开发人员受益。

避免使用 CommonJS 语法

Nuxt 依赖于原生 ESM。请阅读原生 ES 模块以获取更多信息。

文档模块用法

考虑在 readme 文件中记录模块用法

  • 为什么要使用这个模块?
  • 如何使用这个模块?
  • 这个模块是做什么的?

链接到集成网站和文档总是一个好主意。

提供 StackBlitz 演示或样板

一个好的做法是使用您的模块和StackBlitz创建一个最小的复现,并将其添加到您的模块 readme 中。

这不仅为模块的潜在用户提供了一种快速简便的实验方式,还为他们在遇到问题时构建最小复现并发送给您提供了一种简便方法。

不要使用特定的 Nuxt 版本进行宣传

Nuxt、Nuxt Kit 和其他新工具在设计时都考虑了向前和向后兼容性。

请使用“X for Nuxt”而不是“X for Nuxt 3”,以避免生态系统碎片化,并优先使用meta.compatibility来设置 Nuxt 版本约束。

坚持使用入门模板默认值

模块入门模板带有一套默认的工具和配置(例如 ESLint 配置)。如果您计划开源您的模块,坚持这些默认值可确保您的模块与其他社区模块共享一致的编码风格,使其他人更容易贡献。

生态系统

Nuxt 模块生态系统每月 NPM 下载量超过 1500 万次,提供扩展功能以及与各种工具的集成。您可以成为这个生态系统的一部分!

观看 Vue School 关于 Nuxt 模块类型的视频。

模块类型

官方模块是带有@nuxt/前缀(作用域)的模块(例如@nuxt/content)。它们由 Nuxt 团队积极开发和维护。与框架一样,我们非常欢迎社区贡献,以帮助改进它们!

社区模块是带有@nuxtjs/前缀(作用域)的模块(例如@nuxtjs/tailwindcss)。它们是经过验证的模块,由社区成员创建和维护。同样,欢迎任何人贡献。

第三方和其他社区模块是(通常)以nuxt-为前缀的模块。任何人都可以创建它们,使用此前缀可以使这些模块在 npm 上被发现。这是起草和尝试想法的最佳起点!

私人或个人模块是为您自己的用例或公司制作的模块。它们无需遵循任何命名规则即可与 Nuxt 配合使用,并且通常在 npm 组织下进行作用域(例如@my-company/nuxt-auth

列出您的社区模块

欢迎将任何社区模块列在模块列表中。要列出,请在 nuxt/modules存储库中开一个 issue。Nuxt 团队可以帮助您在列出之前应用最佳实践。

加入nuxt-modules@nuxtjs/

通过将您的模块移至nuxt-modules,总会有其他人提供帮助,这样我们就可以齐心协力,打造一个完美的解决方案。

如果您有一个已经发布并正在运行的模块,并且希望将其转移到nuxt-modules在 nuxt/modules 中开一个 issue.

通过加入nuxt-modules,我们可以将您的社区模块重命名到@nuxtjs/作用域下,并为其文档提供子域(例如my-module.nuxtjs.org)。