mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
feat(kit): allow direct function in defineNuxtModule
(#20763)
This commit is contained in:
parent
7e74e7c2fc
commit
c73bed8c6d
@ -127,7 +127,19 @@ export default function (inlineOptions, nuxt) {
|
||||
}
|
||||
```
|
||||
|
||||
Outside of short inline modules defined in `nuxt.config.ts`, **we do not recommend** using this low-level function definition. Instead, to define a module, **we recommend** using the higher-level `defineNuxtModule` helper provided by [Nuxt Kit](/docs/api/advanced/kit).
|
||||
You can get type-hint support for this function using the higher-level `defineNuxtModule` helper provided by [Nuxt Kit](/docs/api/advanced/kit).
|
||||
|
||||
```js
|
||||
import { defineNuxtModule } from '@nuxt/kit'
|
||||
|
||||
export default defineNuxtModule((options, nuxt) => {
|
||||
nuxt.hook('pages:extend', pages => {
|
||||
console.log(`Discovered ${pages.length} pages`)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
However, **we do not recommend** using this low-level function definition. Instead, to define a module, **we recommend** using the object-syntax with `meta` property to identify your module, especially when publishing to npm.
|
||||
|
||||
This helper makes writing Nuxt Module more straightforward by implementing many common patterns seen in modules, guaranteeing future compatibility, and improving your module author developer experience and the one of your module users.
|
||||
|
||||
|
@ -13,20 +13,22 @@ import { compileTemplate, templateUtils } from '../internal/template'
|
||||
* Define a Nuxt module, automatically merging defaults with user provided options, installing
|
||||
* any hooks that are provided, and calling an optional setup function for full control.
|
||||
*/
|
||||
export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: ModuleDefinition<OptionsT>): NuxtModule<OptionsT> {
|
||||
export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: ModuleDefinition<OptionsT> | NuxtModule<OptionsT>): NuxtModule<OptionsT> {
|
||||
if (typeof definition === 'function') { return defineNuxtModule({ setup: definition }) }
|
||||
|
||||
// Normalize definition and meta
|
||||
if (!definition.meta) { definition.meta = {} }
|
||||
if (definition.meta.configKey === undefined) {
|
||||
definition.meta.configKey = definition.meta.name
|
||||
const module: ModuleDefinition<OptionsT> & Required<Pick<ModuleDefinition<OptionsT>, 'meta'>> = defu(definition, { meta: {} })
|
||||
if (module.meta.configKey === undefined) {
|
||||
module.meta.configKey = module.meta.name
|
||||
}
|
||||
|
||||
// Resolves module options from inline options, [configKey] in nuxt.config, defaults and schema
|
||||
async function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) {
|
||||
const configKey = definition.meta!.configKey || definition.meta!.name!
|
||||
const _defaults = definition.defaults instanceof Function ? definition.defaults(nuxt) : definition.defaults
|
||||
const configKey = module.meta.configKey || module.meta.name!
|
||||
const _defaults = module.defaults instanceof Function ? module.defaults(nuxt) : module.defaults
|
||||
let _options = defu(inlineOptions, nuxt.options[configKey as keyof NuxtOptions], _defaults) as OptionsT
|
||||
if (definition.schema) {
|
||||
_options = await applyDefaults(definition.schema, _options) as OptionsT
|
||||
if (module.schema) {
|
||||
_options = await applyDefaults(module.schema, _options) as OptionsT
|
||||
}
|
||||
return Promise.resolve(_options)
|
||||
}
|
||||
@ -38,7 +40,7 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
||||
}
|
||||
|
||||
// Avoid duplicate installs
|
||||
const uniqueKey = definition.meta!.name || definition.meta!.configKey
|
||||
const uniqueKey = module.meta.name || module.meta.configKey
|
||||
if (uniqueKey) {
|
||||
nuxt.options._requiredModules = nuxt.options._requiredModules || {}
|
||||
if (nuxt.options._requiredModules[uniqueKey]) {
|
||||
@ -48,10 +50,10 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
||||
}
|
||||
|
||||
// Check compatibility constraints
|
||||
if (definition.meta!.compatibility) {
|
||||
const issues = await checkNuxtCompatibility(definition.meta!.compatibility, nuxt)
|
||||
if (module.meta.compatibility) {
|
||||
const issues = await checkNuxtCompatibility(module.meta.compatibility, nuxt)
|
||||
if (issues.length) {
|
||||
logger.warn(`Module \`${definition.meta!.name}\` is disabled due to incompatibility issues:\n${issues.toString()}`)
|
||||
logger.warn(`Module \`${module.meta.name}\` is disabled due to incompatibility issues:\n${issues.toString()}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -63,14 +65,14 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
||||
const _options = await getOptions(inlineOptions, nuxt)
|
||||
|
||||
// Register hooks
|
||||
if (definition.hooks) {
|
||||
nuxt.hooks.addHooks(definition.hooks)
|
||||
if (module.hooks) {
|
||||
nuxt.hooks.addHooks(module.hooks)
|
||||
}
|
||||
|
||||
// Call setup
|
||||
const key = `nuxt:module:${uniqueKey || (Math.round(Math.random() * 10000))}`
|
||||
const mark = performance.mark(key)
|
||||
const res = await definition.setup?.call(null as any, _options, nuxt) ?? {}
|
||||
const res = await module.setup?.call(null as any, _options, nuxt) ?? {}
|
||||
const perf = performance.measure(key, mark?.name) // TODO: remove when Node 14 reaches EOL
|
||||
const setupTime = perf ? Math.round((perf.duration * 100)) / 100 : 0 // TODO: remove when Node 14 reaches EOL
|
||||
|
||||
@ -93,7 +95,7 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
||||
}
|
||||
|
||||
// Define getters for options and meta
|
||||
normalizedModule.getMeta = () => Promise.resolve(definition.meta)
|
||||
normalizedModule.getMeta = () => Promise.resolve(module.meta)
|
||||
normalizedModule.getOptions = getOptions
|
||||
|
||||
return normalizedModule as NuxtModule<OptionsT>
|
||||
|
8
test/fixtures/basic/modules/functional.ts
vendored
Normal file
8
test/fixtures/basic/modules/functional.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { defineNuxtModule } from 'nuxt/kit'
|
||||
|
||||
export default defineNuxtModule(
|
||||
function (_, nuxt) {
|
||||
nuxt.options.optimization.treeShake.composables.server[nuxt.options.rootDir] = ['useClientOnlyComposable', 'setTitleToPink']
|
||||
nuxt.options.optimization.treeShake.composables.client[nuxt.options.rootDir] = ['useServerOnlyComposable']
|
||||
}
|
||||
)
|
4
test/fixtures/basic/nuxt.config.ts
vendored
4
test/fixtures/basic/nuxt.config.ts
vendored
@ -117,10 +117,6 @@ export default defineNuxtConfig({
|
||||
internalParent!.children = newPages
|
||||
})
|
||||
},
|
||||
function (_, nuxt) {
|
||||
nuxt.options.optimization.treeShake.composables.server[nuxt.options.rootDir] = ['useClientOnlyComposable', 'setTitleToPink']
|
||||
nuxt.options.optimization.treeShake.composables.client[nuxt.options.rootDir] = ['useServerOnlyComposable']
|
||||
},
|
||||
// To test falsy module values
|
||||
undefined
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user