mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +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 { 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 { dirname, isAbsolute, join, resolve } from 'pathe'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { isNuxt2 } from '../compatibility'
|
import { isNuxt2 } from '../compatibility'
|
||||||
@ -12,7 +12,10 @@ import { logger } from '../logger'
|
|||||||
const NODE_MODULES_RE = /[/\\]node_modules[/\\]/
|
const NODE_MODULES_RE = /[/\\]node_modules[/\\]/
|
||||||
|
|
||||||
/** Installs a module on a Nuxt instance. */
|
/** 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 { nuxtModule, buildTimeModuleMeta } = await loadNuxtModuleInstance(moduleToInstall, nuxt)
|
||||||
|
|
||||||
const localLayerModuleDirs = new Set<string>()
|
const localLayerModuleDirs = new Set<string>()
|
||||||
@ -43,10 +46,16 @@ export async function installModule (moduleToInstall: string | NuxtModule, inlin
|
|||||||
}
|
}
|
||||||
|
|
||||||
nuxt.options._installedModules = nuxt.options._installedModules || []
|
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({
|
nuxt.options._installedModules.push({
|
||||||
meta: defu(await nuxtModule.getMeta?.(), buildTimeModuleMeta),
|
meta: defu(await nuxtModule.getMeta?.(), buildTimeModuleMeta),
|
||||||
timings: res.timings,
|
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 relativeRoot = relative(resolve(nuxt.options.buildDir, 'types'), nuxt.options.rootDir)
|
||||||
const getImportName = (name: string) => (name[0] === '.' ? './' + join(relativeRoot, name) : name).replace(/\.\w+$/, '')
|
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)
|
const privateRuntimeConfig = Object.create(null)
|
||||||
for (const key in nuxt.options.runtimeConfig) {
|
for (const key in nuxt.options.runtimeConfig) {
|
||||||
if (key !== 'public') {
|
if (key !== 'public') {
|
||||||
privateRuntimeConfig[key] = nuxt.options.runtimeConfig[key]
|
privateRuntimeConfig[key] = nuxt.options.runtimeConfig[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [
|
const moduleOptionsInterface = [
|
||||||
'import { NuxtModule, RuntimeConfig } from \'nuxt/schema\'',
|
|
||||||
'declare module \'nuxt/schema\' {',
|
|
||||||
' interface NuxtConfig {',
|
|
||||||
...modules.map(([configKey, importName]) =>
|
...modules.map(([configKey, importName]) =>
|
||||||
` [${configKey}]?: typeof ${genDynamicImport(importName, { wrapper: false })}.default extends NuxtModule<infer O> ? Partial<O> : Record<string, any>`,
|
` [${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>),
|
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({
|
export default defineNuxtConfig({
|
||||||
experimental: {
|
experimental: {
|
||||||
@ -54,6 +54,15 @@ export default defineNuxtConfig({
|
|||||||
filename: 'test.d.ts',
|
filename: 'test.d.ts',
|
||||||
getContents: () => 'declare type Fromage = "cheese"',
|
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',
|
'./modules/test',
|
||||||
[
|
[
|
||||||
|
Loading…
Reference in New Issue
Block a user