模組作者指南

學習如何建立 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)。