モジュール作成者ガイド

Nuxtアプリケーションを統合、強化、または拡張するためのNuxtモジュールの作成方法を学びましょう。

Nuxtの設定フックシステムにより、Nuxtのあらゆる側面をカスタマイズし、必要な統合(Vueプラグイン、CMS、サーバールート、コンポーネント、ロギングなど)を追加できます。

Nuxtモジュールは、nuxt devを使用して開発モードでNuxtを開始したり、nuxt buildで本番用にプロジェクトを構築したりする際に、順次実行される関数です。モジュールを使用すると、プロジェクトに不要なボイラープレートを追加したり、Nuxt自体を変更したりすることなく、カスタムソリューションをnpmパッケージとしてカプセル化し、適切にテストし、共有できます。

クイックスタート

Nuxtモジュールを始めるには、弊社のスターターテンプレート:

npm create nuxt -- -t module my-module

を使用することをお勧めします。これにより、モジュールを開発および公開するために必要なすべてのボイラープレートを備えたmy-moduleプロジェクトが作成されます。

次のステップ

  1. お好みのIDEでmy-moduleを開きます。
  2. お気に入りのパッケージマネージャーを使用して依存関係をインストールします。
  3. npm run dev:prepareを使用して開発用のローカルファイルを準備します。
  4. このドキュメントを読んでNuxtモジュールについて詳しく学びましょう。

スターターの使用

モジュールスターターで基本的なタスクを実行する方法を学びましょう。

Nuxtモジュールスターターテンプレートに関するVue Schoolのビデオをご覧ください。

開発方法

モジュールのソースコードはsrcディレクトリ内にありますが、ほとんどの場合、モジュールを開発するにはNuxtアプリケーションが必要です。playgroundディレクトリはそのためです。これは、モジュールで実行するようにすでに設定されているNuxtアプリケーションです。

プレイグラウンドは、他のNuxtアプリケーションと同じように操作できます。

  • npm run devで開発サーバーを起動すると、srcディレクトリ内のモジュールに変更を加えるたびに自動的にリロードされます。
  • npm run dev:buildでビルドします。
他のすべてのnuxtコマンドはplaygroundディレクトリに対して使用できます(例:nuxt <COMMAND> playground)。便宜のために、package.json内に参照する追加のdev:*スクリプトを自由に宣言してください。

テスト方法

モジュールスターターには基本的なテストスイートが付属しています。

  • を搭載したリンターESLintnpm run lintで実行します。
  • を搭載したテストランナーVitestnpm run testまたはnpm 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でリリーススクリプトを実行します。

リリーススクリプトを実行すると、次のことが起こります。

  • まず、テストスイートが実行されます。
    • リンターの実行(npm run lint
    • 単体、統合、e2eテストの実行(npm run test
    • モジュールのビルド(npm run prepack
  • 次に、テストスイートがうまくいった場合、モジュールの公開に進みます。
    • Conventional Commitsに従って、モジュールのバージョンを上げ、変更ログを生成します。
    • npmにモジュールを公開します(この目的のために、公開される成果物に更新されたバージョン番号が考慮されるように、モジュールは再度ビルドされます)。
    • 新しく公開されたバージョンを表すgitタグをgitリモートオリジンにプッシュします。
他のスクリプトと同様に、package.json内のデフォルトのreleaseスクリプトを、ニーズに合わせて自由に調整してください。

モジュールの開発

Nuxtモジュールには、Nuxtアプリケーションをほぼあらゆる方法で変更できる、さまざまな強力なAPIとパターンが付属しています。このセクションでは、それらを活用する方法を学びます。

モジュールの構造

Nuxtモジュールには2種類あります。

どちらの場合も、その構造は似ています。

モジュール定義

スターターを使用する場合、モジュール定義は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`)
  })
})

ただし、この低レベルの関数定義の使用は推奨しません。代わりに、モジュールを定義するには、特にnpmに公開する場合は、モジュールを識別するためのmetaプロパティを持つオブジェクト構文を使用することを推奨します

このヘルパーは、モジュールに必要な多くの一般的なパターンを実装し、将来の互換性を保証し、モジュール作成者とユーザーの両方のエクスペリエンスを向上させることで、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.nameまたはmeta.configKeyから計算された一意のキーを使用して、モジュールが一度だけインストールされることを保証します。
  • Nuxtフックの自動登録
  • モジュールのメタデータに基づいて互換性の問題を自動的にチェック
  • Nuxtの内部使用のためにgetOptionsgetMetaを公開
  • モジュールが@nuxt/kitの最新バージョンからdefineNuxtModuleを使用している限り、下位および上位互換性を保証します。
  • モジュールビルダーツールとの統合

ランタイムディレクトリ

スターターを使用する場合、ランタイムディレクトリはsrc/runtimeにあります。

モジュールは、Nuxt設定内のすべてと同様に、アプリケーションのランタイムには含まれません。ただし、モジュールがインストールされているアプリケーションにランタイムコードを提供または注入したい場合があります。ランタイムディレクトリはそれを行うことを可能にします。

ランタイムディレクトリ内では、Nuxt Appに関連するあらゆる種類のアセットを提供できます。

サーバーエンジン、Nitroへ

  • APIルート
  • ミドルウェア
  • Nitroプラグイン

または、ユーザーのNuxtアプリケーションに注入したい他の種類のアセット

  • スタイルシート
  • 3Dモデル
  • 画像
  • など

そして、それらのすべてのアセットをモジュール定義からアプリケーションに注入できるようになります。

アセットの注入については、レシピセクションで詳しく学びましょう。
公開されたモジュールは、ランタイムディレクトリ内のアセットに対して自動インポートを利用できません。代わりに、#importsなどから明示的にインポートする必要があります。

実際、パフォーマンス上の理由から、node_modules(公開されたモジュールが最終的に存在する場所)内のファイルに対しては自動インポートが有効になっていません。

ツール

モジュールには、その開発を支援する一連の公式ツールが付属しています。

@nuxt/module-builder

Nuxtモジュールビルダーは、モジュールをビルドして出荷するためのすべての重労働を処理する、設定不要のビルドツールです。モジュールビルド成果物のNuxtアプリケーションとの適切な互換性を保証します。

@nuxt/kit

Nuxt Kitは、モジュールがNuxtアプリケーションと対話するのを助ける構成可能なユーティリティを提供します。モジュールの互換性とコードの可読性を向上させるために、可能な限り手動の代替手段よりもNuxt Kitユーティリティを使用することをお勧めします。

Docs > 4 X > Guide > Going Further > Kitで詳細をお読みください。

@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.

の使用を検討してください。Nuxt構成の変更に関するVue Schoolのビデオをご覧ください。

ランタイムへのオプションの公開

モジュールはアプリケーションのランタイムの一部ではないため、そのオプションも同様ではありません。ただし、多くの場合、ランタイムコード内でこれらのモジュールオプションの一部にアクセスする必要があるかもしれません。必要な設定は、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キーなど)を公開ランタイム設定に公開しないように注意してください。これらは公開バンドルに含まれることになります。
Docs > 4 X > Guide > Going Further > Runtime Configで詳細をお読みください。
Nuxtモジュールオプションの渡し方と公開方法に関するVue Schoolのビデオをご覧ください。

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'))
  },
})
Docs > 4 X > Guide > Going Further > Kitで詳細をお読みください。

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'),
    })
  },
})

addImportsおよびaddImportsDirでコンポーザブルを注入

モジュールがコンポーザブルを提供する場合、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`)
    })
  },
})
Docs > 4 X > API > Advanced > Hooksで詳細をお読みください。
モジュールでNuxtライフサイクルフックを使用する方法に関するVue Schoolのビデオをご覧ください。
モジュールのクリーンアップ

モジュールがウォッチャーを開いたり、処理したり、開始したりする場合、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 () => { /* ... */ })
このようなワークフローの例は、モジュールスターター.

にあります。プレイグラウンドと外部での手動QA

開発時にモジュールをテストするためのプレイグラウンドNuxtアプリケーションを持つことは非常に便利です。モジュールスターターにはその目的のために1つ統合されています

他の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に依存しています。詳細については、Native ES Modulesをお読みください。

モジュールの使用方法を文書化する

READMEファイルにモジュールの使用方法を文書化することを検討してください。

  • このモジュールを使用する理由は何ですか?
  • このモジュールをどのように使用しますか?
  • このモジュールは何をしますか?

統合ウェブサイトやドキュメントへのリンクは、常に良いアイデアです。

StackBlitzデモまたはボイラープレートを提供する

モジュールとStackBlitzで最小限の再現を作成し、それをモジュールのREADMEに追加することは良い習慣です。

これは、モジュールの潜在的なユーザーがモジュールをすばやく簡単に試せるだけでなく、問題が発生したときに送信できる最小限の再現を簡単に構築できる方法も提供します。

特定のNuxtバージョンを宣伝しない

Nuxt、Nuxt Kit、およびその他の新しいツールは、前方互換性と後方互換性の両方を念頭に置いて作成されています。

エコシステムの断片化を避けるため、「Nuxt 3用X」ではなく「Nuxt用X」を使用し、meta.compatibilityを使用してNuxtのバージョン制約を設定することを推奨します。

スターターのデフォルトを維持する

モジュールスターターには、デフォルトのツールと設定(例:ESLint設定)が付属しています。モジュールをオープンソース化する予定がある場合、これらのデフォルトを維持することで、他のコミュニティモジュールと一貫したコーディングスタイルを共有し、他の人が貢献しやすくなります。

エコシステム

Nuxtモジュールエコシステムは、月間1500万件以上のNPMダウンロードを誇り、あらゆる種類のツールとの拡張機能と統合を提供しています。あなたもこのエコシステムの一部になれます!

Nuxtモジュールタイプに関するVue Schoolのビデオをご覧ください。

モジュールの種類

公式モジュール@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)を提供できます。