以下是模块作者常用的一些模式。
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 的 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
插件是模块添加运行时逻辑的常见方式。您可以使用 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'))
},
})
如果您的模块应提供 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/app/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/app/components'),
})
},
})
app/ 文件夹中的组件、页面、组合式函数和其他文件,都需要放在 runtime/app/ 中。这将确保它们可以被正确地进行类型检查。如果您的模块应提供组合式函数,您可以使用 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: 'useMyComposable', // optional alias that will be available for the consuming apps
from: resolver.resolve('runtime/app/composables/useComposable'), // path of composable
})
},
})
可以以数组形式传递多个条目
import { addImports, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
addImports([
{ name: 'useFirstComposable', from: resolver.resolve('runtime/composables/useFirstComposable') },
{ name: 'useSecondComposable', from: resolver.resolve('runtime/composables/useSecondComposable') },
])
},
})
或者,您可以使用 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'))
},
})
app/ 文件夹中的组件、页面、组合式函数和其他文件,都需要放在 runtime/app/ 中。这将确保它们可以被正确地进行类型检查。import { addServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
addServerHandler({
route: '/api/_my-module/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/_my-module/hello/:name',
handler: resolver.resolve('./runtime/server/api/hello/[name].get'),
})
// Or using a catch all route
addServerHandler({
route: '/api/_my-module/files/**:path',
handler: resolver.resolve('./runtime/server/api/files/[...path].get'),
})
},
})
/api/auth、/api/login 或 /api/user。如果您的模块应提供其他类型的资产,也可以注入它们。这是一个简单的示例模块,通过 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'))
},
})
以及一个更高级的示例,通过 Nitro 的 publicAssets 选项暴露一个资产文件夹
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
})
})
},
})
如果您的模块依赖于其他模块,您可以使用 moduleDependencies 选项来指定它们。这提供了一种更健壮的方式来处理带有版本约束和配置合并的模块依赖关系
import { createResolver, defineNuxtModule } from '@nuxt/kit'
const resolver = createResolver(import.meta.url)
export default defineNuxtModule<ModuleOptions>({
meta: {
name: 'my-module',
},
moduleDependencies: {
'@nuxtjs/tailwindcss': {
// You can specify a version constraint for the module
version: '>=6',
// Any configuration that should override `nuxt.options`
overrides: {
exposeConfig: true,
},
// Any configuration that should be set. It will override module defaults but
// will not override any configuration set in `nuxt.options`
defaults: {
config: {
darkMode: 'class',
content: {
files: [
resolver.resolve('./runtime/components/**/*.{vue,mjs,ts}'),
resolver.resolve('./runtime/*.{mjs,js,ts}'),
],
},
},
},
},
},
setup (options, nuxt) {
// We can inject our CSS file which includes Tailwind's directives
nuxt.options.css.push(resolver.resolve('./runtime/assets/styles.css'))
},
})
moduleDependencies 选项取代了已弃用的 installModule 函数,并确保了正确的设置顺序和配置合并。