mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
feat(kit): support typed module options in installModule
(#26744)
This commit is contained in:
parent
ad82474894
commit
0d84300218
@ -1,5 +1,5 @@
|
||||
import { existsSync, promises as fsp, lstatSync } from 'node:fs'
|
||||
import type { ModuleMeta, Nuxt, NuxtModule } from '@nuxt/schema'
|
||||
import type { ModuleMeta, Nuxt, NuxtConfig, NuxtModule } from '@nuxt/schema'
|
||||
import { dirname, isAbsolute, join, resolve } from 'pathe'
|
||||
import { defu } from 'defu'
|
||||
import { isNuxt2 } from '../compatibility'
|
||||
@ -12,7 +12,10 @@ import { logger } from '../logger'
|
||||
const NODE_MODULES_RE = /[/\\]node_modules[/\\]/
|
||||
|
||||
/** Installs a module on a Nuxt instance. */
|
||||
export async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt: Nuxt = useNuxt()) {
|
||||
export async function installModule<
|
||||
T extends string | NuxtModule,
|
||||
Config extends Extract<NonNullable<NuxtConfig['modules']>[number], [T, any]>,
|
||||
> (moduleToInstall: T, inlineOptions?: [Config] extends [never] ? any : Config[1], nuxt: Nuxt = useNuxt()) {
|
||||
const { nuxtModule, buildTimeModuleMeta } = await loadNuxtModuleInstance(moduleToInstall, nuxt)
|
||||
|
||||
const localLayerModuleDirs = new Set<string>()
|
||||
@ -43,10 +46,16 @@ export async function installModule (moduleToInstall: string | NuxtModule, inlin
|
||||
}
|
||||
|
||||
nuxt.options._installedModules = nuxt.options._installedModules || []
|
||||
const entryPath = typeof moduleToInstall === 'string' ? resolveAlias(moduleToInstall) : undefined
|
||||
|
||||
if (typeof moduleToInstall === 'string' && entryPath !== moduleToInstall) {
|
||||
buildTimeModuleMeta.rawPath = moduleToInstall
|
||||
}
|
||||
|
||||
nuxt.options._installedModules.push({
|
||||
meta: defu(await nuxtModule.getMeta?.(), buildTimeModuleMeta),
|
||||
timings: res.timings,
|
||||
entryPath: typeof moduleToInstall === 'string' ? resolveAlias(moduleToInstall) : undefined,
|
||||
entryPath,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -156,21 +156,29 @@ export const schemaTemplate: NuxtTemplate = {
|
||||
|
||||
const relativeRoot = relative(resolve(nuxt.options.buildDir, 'types'), nuxt.options.rootDir)
|
||||
const getImportName = (name: string) => (name[0] === '.' ? './' + join(relativeRoot, name) : name).replace(/\.\w+$/, '')
|
||||
const modules = moduleInfo.map(meta => [genString(meta.configKey), getImportName(meta.importName)])
|
||||
const modules = moduleInfo.map(meta => [genString(meta.configKey), getImportName(meta.importName), meta])
|
||||
const privateRuntimeConfig = Object.create(null)
|
||||
for (const key in nuxt.options.runtimeConfig) {
|
||||
if (key !== 'public') {
|
||||
privateRuntimeConfig[key] = nuxt.options.runtimeConfig[key]
|
||||
}
|
||||
}
|
||||
return [
|
||||
'import { NuxtModule, RuntimeConfig } from \'nuxt/schema\'',
|
||||
'declare module \'nuxt/schema\' {',
|
||||
' interface NuxtConfig {',
|
||||
const moduleOptionsInterface = [
|
||||
...modules.map(([configKey, importName]) =>
|
||||
` [${configKey}]?: typeof ${genDynamicImport(importName, { wrapper: false })}.default extends NuxtModule<infer O> ? Partial<O> : Record<string, any>`,
|
||||
),
|
||||
modules.length > 0 ? ` modules?: (undefined | null | false | NuxtModule | string | [NuxtModule | string, Record<string, any>] | ${modules.map(([configKey, importName]) => `[${genString(importName)}, Exclude<NuxtConfig[${configKey}], boolean>]`).join(' | ')})[],` : '',
|
||||
modules.length > 0 ? ` modules?: (undefined | null | false | NuxtModule | string | [NuxtModule | string, Record<string, any>] | ${modules.map(([configKey, importName, meta]) => `[${genString(meta?.rawPath || importName)}, Exclude<NuxtConfig[${configKey}], boolean>]`).join(' | ')})[],` : '',
|
||||
]
|
||||
return [
|
||||
'import { NuxtModule, RuntimeConfig } from \'@nuxt/schema\'',
|
||||
'declare module \'@nuxt/schema\' {',
|
||||
' interface NuxtConfig {',
|
||||
moduleOptionsInterface,
|
||||
' }',
|
||||
'}',
|
||||
'declare module \'nuxt/schema\' {',
|
||||
' interface NuxtConfig {',
|
||||
moduleOptionsInterface,
|
||||
' }',
|
||||
generateTypes(await resolveSchema(privateRuntimeConfig as Record<string, JSValue>),
|
||||
{
|
||||
|
11
test/fixtures/basic-types/nuxt.config.ts
vendored
11
test/fixtures/basic-types/nuxt.config.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { addTypeTemplate } from 'nuxt/kit'
|
||||
import { addTypeTemplate, installModule } from 'nuxt/kit'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
experimental: {
|
||||
@ -54,6 +54,15 @@ export default defineNuxtConfig({
|
||||
filename: 'test.d.ts',
|
||||
getContents: () => 'declare type Fromage = "cheese"',
|
||||
})
|
||||
function _test () {
|
||||
installModule('~/modules/example', {
|
||||
typeTest (val) {
|
||||
// @ts-expect-error module type defines val as boolean
|
||||
const b: string = val
|
||||
return !!b
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
'./modules/test',
|
||||
[
|
||||
|
Loading…
Reference in New Issue
Block a user