mirror of
https://github.com/nuxt/nuxt.git
synced 2024-12-01 18:07:22 +00:00
Merge branch 'main' into patch-21
This commit is contained in:
commit
09489b9d7a
@ -136,7 +136,9 @@ nuxt.config.ts
|
|||||||
1. Move your `assets/`, `components/`, `composables/`, `layouts/`, `middleware/`, `pages/`, `plugins/` and `utils/` folders under it, as well as `app.vue`, `error.vue`, `app.config.ts`. If you have an `app/router-options.ts` or `app/spa-loading-template.html`, these paths remain the same.
|
1. Move your `assets/`, `components/`, `composables/`, `layouts/`, `middleware/`, `pages/`, `plugins/` and `utils/` folders under it, as well as `app.vue`, `error.vue`, `app.config.ts`. If you have an `app/router-options.ts` or `app/spa-loading-template.html`, these paths remain the same.
|
||||||
1. Make sure your `nuxt.config.ts`, `modules/`, `public/` and `server/` folders remain outside the `app/` folder, in the root of your project.
|
1. Make sure your `nuxt.config.ts`, `modules/`, `public/` and `server/` folders remain outside the `app/` folder, in the root of your project.
|
||||||
|
|
||||||
However, migration is _not required_. If you wish to keep your current folder structure, Nuxt should auto-detect it. (If it does not, please raise an issue.) You can also force a v3 folder structure with the following configuration:
|
However, migration is _not required_. If you wish to keep your current folder structure, Nuxt should auto-detect it. (If it does not, please raise an issue.) The one exception is that if you _already_ have a custom `srcDir`. In this case, you should be aware that your `modules/`, `public/` and `server/` folders will be resolved from your `rootDir` rather than from your custom `srcDir`. You can override this by configuring `dir.modules`, `dir.public` and `serverDir` if you need to.
|
||||||
|
|
||||||
|
You can also force a v3 folder structure with the following configuration:
|
||||||
|
|
||||||
```ts [nuxt.config.ts]
|
```ts [nuxt.config.ts]
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
|
@ -3,7 +3,7 @@ import { performance } from 'node:perf_hooks'
|
|||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { applyDefaults } from 'untyped'
|
import { applyDefaults } from 'untyped'
|
||||||
import { dirname } from 'pathe'
|
import { dirname } from 'pathe'
|
||||||
import type { ModuleDefinition, ModuleOptions, ModuleSetupReturn, Nuxt, NuxtModule, NuxtOptions, ResolvedNuxtTemplate } from '@nuxt/schema'
|
import type { ModuleDefinition, ModuleOptions, ModuleSetupInstallResult, ModuleSetupReturn, Nuxt, NuxtModule, NuxtOptions, ResolvedModuleOptions, ResolvedNuxtTemplate } from '@nuxt/schema'
|
||||||
import { logger } from '../logger'
|
import { logger } from '../logger'
|
||||||
import { nuxtCtx, tryUseNuxt, useNuxt } from '../context'
|
import { nuxtCtx, tryUseNuxt, useNuxt } from '../context'
|
||||||
import { checkNuxtCompatibility, isNuxt2 } from '../compatibility'
|
import { checkNuxtCompatibility, isNuxt2 } from '../compatibility'
|
||||||
@ -13,28 +13,53 @@ import { compileTemplate, templateUtils } from '../internal/template'
|
|||||||
* Define a Nuxt module, automatically merging defaults with user provided options, installing
|
* 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.
|
* 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>): NuxtModule<OptionsT> {
|
export function defineNuxtModule<TOptions extends ModuleOptions> (definition: ModuleDefinition<TOptions> | NuxtModule<TOptions>): NuxtModule<TOptions>
|
||||||
if (typeof definition === 'function') { return defineNuxtModule({ setup: definition }) }
|
|
||||||
|
export function defineNuxtModule<TOptions extends ModuleOptions> (): {
|
||||||
|
with: <TOptionsDefaults extends Partial<TOptions>> (
|
||||||
|
definition: ModuleDefinition<TOptions, TOptionsDefaults> | NuxtModule<TOptions, TOptionsDefaults>
|
||||||
|
) => NuxtModule<TOptions, TOptionsDefaults>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function defineNuxtModule<TOptions extends ModuleOptions> (definition?: ModuleDefinition<TOptions> | NuxtModule<TOptions>) {
|
||||||
|
if (definition) {
|
||||||
|
return _defineNuxtModule(definition)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
with: <TOptionsDefaults extends Partial<TOptions>>(
|
||||||
|
definition: ModuleDefinition<TOptions, TOptionsDefaults> | NuxtModule<TOptions, TOptionsDefaults>,
|
||||||
|
) => _defineNuxtModule(definition),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _defineNuxtModule<TOptions extends ModuleOptions, TOptionsDefaults extends Partial<TOptions>> (definition: ModuleDefinition<TOptions, TOptionsDefaults> | NuxtModule<TOptions, TOptionsDefaults>): NuxtModule<TOptions, TOptionsDefaults> {
|
||||||
|
if (typeof definition === 'function') { return _defineNuxtModule<TOptions, TOptionsDefaults>({ setup: definition }) }
|
||||||
|
|
||||||
// Normalize definition and meta
|
// Normalize definition and meta
|
||||||
const module: ModuleDefinition<OptionsT> & Required<Pick<ModuleDefinition<OptionsT>, 'meta'>> = defu(definition, { meta: {} })
|
const module: ModuleDefinition<TOptions, TOptionsDefaults> & Required<Pick<ModuleDefinition<TOptions, TOptionsDefaults>, 'meta'>> = defu(definition, { meta: {} })
|
||||||
if (module.meta.configKey === undefined) {
|
|
||||||
module.meta.configKey = module.meta.name
|
module.meta.configKey ||= module.meta.name
|
||||||
}
|
|
||||||
|
|
||||||
// Resolves module options from inline options, [configKey] in nuxt.config, defaults and schema
|
// Resolves module options from inline options, [configKey] in nuxt.config, defaults and schema
|
||||||
async function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) {
|
async function getOptions (inlineOptions?: Partial<TOptions>, nuxt: Nuxt = useNuxt()): Promise<ResolvedModuleOptions<TOptions, TOptionsDefaults>> {
|
||||||
const configKey = module.meta.configKey || module.meta.name!
|
const nuxtConfigOptionsKey = 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
|
const nuxtConfigOptions: Partial<TOptions> = nuxtConfigOptionsKey && nuxtConfigOptionsKey in nuxt.options ? nuxt.options[<keyof NuxtOptions> nuxtConfigOptionsKey] : {}
|
||||||
|
|
||||||
|
const optionsDefaults: TOptionsDefaults = module.defaults instanceof Function ? module.defaults(nuxt) : module.defaults ?? <TOptionsDefaults> {}
|
||||||
|
|
||||||
|
let options: ResolvedModuleOptions<TOptions, TOptionsDefaults> = defu(inlineOptions, nuxtConfigOptions, optionsDefaults)
|
||||||
|
|
||||||
if (module.schema) {
|
if (module.schema) {
|
||||||
_options = await applyDefaults(module.schema, _options) as OptionsT
|
options = await applyDefaults(module.schema, options) as any
|
||||||
}
|
}
|
||||||
return Promise.resolve(_options)
|
|
||||||
|
return Promise.resolve(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module format is always a simple function
|
// Module format is always a simple function
|
||||||
async function normalizedModule (this: any, inlineOptions: OptionsT, nuxt: Nuxt) {
|
async function normalizedModule (this: any, inlineOptions: Partial<TOptions>, nuxt: Nuxt): Promise<ModuleSetupReturn> {
|
||||||
if (!nuxt) {
|
if (!nuxt) {
|
||||||
nuxt = tryUseNuxt() || this.nuxt /* invoked by nuxt 2 */
|
nuxt = tryUseNuxt() || this.nuxt /* invoked by nuxt 2 */
|
||||||
}
|
}
|
||||||
@ -87,7 +112,7 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
|||||||
if (res === false) { return false }
|
if (res === false) { return false }
|
||||||
|
|
||||||
// Return module install result
|
// Return module install result
|
||||||
return defu(res, <ModuleSetupReturn> {
|
return defu(res, <ModuleSetupInstallResult> {
|
||||||
timings: {
|
timings: {
|
||||||
setup: setupTime,
|
setup: setupTime,
|
||||||
},
|
},
|
||||||
@ -98,7 +123,7 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
|||||||
normalizedModule.getMeta = () => Promise.resolve(module.meta)
|
normalizedModule.getMeta = () => Promise.resolve(module.meta)
|
||||||
normalizedModule.getOptions = getOptions
|
normalizedModule.getOptions = getOptions
|
||||||
|
|
||||||
return normalizedModule as NuxtModule<OptionsT>
|
return <NuxtModule<TOptions, TOptionsDefaults>> normalizedModule
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Nuxt 2 compatibility shims --
|
// -- Nuxt 2 compatibility shims --
|
||||||
|
@ -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>()
|
||||||
@ -28,7 +31,7 @@ export async function installModule (moduleToInstall: string | NuxtModule, inlin
|
|||||||
isNuxt2()
|
isNuxt2()
|
||||||
// @ts-expect-error Nuxt 2 `moduleContainer` is not typed
|
// @ts-expect-error Nuxt 2 `moduleContainer` is not typed
|
||||||
? await nuxtModule.call(nuxt.moduleContainer, inlineOptions, nuxt)
|
? await nuxtModule.call(nuxt.moduleContainer, inlineOptions, nuxt)
|
||||||
: await nuxtModule(inlineOptions, nuxt)
|
: await nuxtModule(inlineOptions || {}, nuxt)
|
||||||
) ?? {}
|
) ?? {}
|
||||||
if (res === false /* setup aborted */) {
|
if (res === false /* setup aborted */) {
|
||||||
return
|
return
|
||||||
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import type { Nuxt, NuxtTemplate, NuxtTypeTemplate, ResolvedNuxtTemplate, TSRefe
|
|||||||
import { withTrailingSlash } from 'ufo'
|
import { withTrailingSlash } from 'ufo'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import type { TSConfig } from 'pkg-types'
|
import type { TSConfig } from 'pkg-types'
|
||||||
|
import { gte } from 'semver'
|
||||||
import { readPackageJSON } from 'pkg-types'
|
import { readPackageJSON } from 'pkg-types'
|
||||||
|
|
||||||
import { tryResolveModule } from './internal/esm'
|
import { tryResolveModule } from './internal/esm'
|
||||||
@ -122,6 +123,12 @@ export async function _generateTypes (nuxt: Nuxt) {
|
|||||||
.map(m => getDirectory(m.entryPath)),
|
.map(m => getDirectory(m.entryPath)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const isV4 = nuxt.options.future?.compatibilityVersion === 4
|
||||||
|
|
||||||
|
const hasTypescriptVersionWithModulePreserve = await readPackageJSON('typescript', { url: nuxt.options.modulesDir })
|
||||||
|
.then(r => r?.version && gte(r.version, '5.4.0'))
|
||||||
|
.catch(() => isV4)
|
||||||
|
|
||||||
// https://www.totaltypescript.com/tsconfig-cheat-sheet
|
// https://www.totaltypescript.com/tsconfig-cheat-sheet
|
||||||
const tsConfig: TSConfig = defu(nuxt.options.typescript?.tsConfig, {
|
const tsConfig: TSConfig = defu(nuxt.options.typescript?.tsConfig, {
|
||||||
compilerOptions: {
|
compilerOptions: {
|
||||||
@ -136,11 +143,11 @@ export async function _generateTypes (nuxt: Nuxt) {
|
|||||||
verbatimModuleSyntax: true,
|
verbatimModuleSyntax: true,
|
||||||
/* Strictness */
|
/* Strictness */
|
||||||
strict: nuxt.options.typescript?.strict ?? true,
|
strict: nuxt.options.typescript?.strict ?? true,
|
||||||
noUncheckedIndexedAccess: nuxt.options.future?.compatibilityVersion === 4,
|
noUncheckedIndexedAccess: isV4,
|
||||||
forceConsistentCasingInFileNames: true,
|
forceConsistentCasingInFileNames: true,
|
||||||
noImplicitOverride: true,
|
noImplicitOverride: true,
|
||||||
/* If NOT transpiling with TypeScript: */
|
/* If NOT transpiling with TypeScript: */
|
||||||
module: 'preserve',
|
module: hasTypescriptVersionWithModulePreserve ? 'preserve' : 'es2022',
|
||||||
noEmit: true,
|
noEmit: true,
|
||||||
/* If your code runs in the DOM: */
|
/* If your code runs in the DOM: */
|
||||||
lib: [
|
lib: [
|
||||||
|
@ -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>),
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { Defu } from 'defu'
|
||||||
import type { NuxtHooks } from './hooks'
|
import type { NuxtHooks } from './hooks'
|
||||||
import type { Nuxt } from './nuxt'
|
import type { Nuxt } from './nuxt'
|
||||||
import type { NuxtCompatibility } from './compatibility'
|
import type { NuxtCompatibility } from './compatibility'
|
||||||
@ -26,8 +27,7 @@ export interface ModuleMeta {
|
|||||||
/** The options received. */
|
/** The options received. */
|
||||||
export type ModuleOptions = Record<string, any>
|
export type ModuleOptions = Record<string, any>
|
||||||
|
|
||||||
/** Optional result for nuxt modules */
|
export type ModuleSetupInstallResult = {
|
||||||
export interface ModuleSetupReturn {
|
|
||||||
/**
|
/**
|
||||||
* Timing information for the initial setup
|
* Timing information for the initial setup
|
||||||
*/
|
*/
|
||||||
@ -39,19 +39,37 @@ export interface ModuleSetupReturn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Awaitable<T> = T | Promise<T>
|
type Awaitable<T> = T | Promise<T>
|
||||||
type _ModuleSetupReturn = Awaitable<void | false | ModuleSetupReturn>
|
|
||||||
|
|
||||||
/** Input module passed to defineNuxtModule. */
|
type Prettify<T> = {
|
||||||
export interface ModuleDefinition<T extends ModuleOptions = ModuleOptions> {
|
[K in keyof T]: T[K];
|
||||||
|
} & {}
|
||||||
|
|
||||||
|
export type ModuleSetupReturn = Awaitable<false | void | ModuleSetupInstallResult>
|
||||||
|
|
||||||
|
export type ResolvedModuleOptions<TOptions extends ModuleOptions, TOptionsDefaults extends Partial<TOptions>> = Prettify<
|
||||||
|
Defu<
|
||||||
|
Partial<TOptions>,
|
||||||
|
[Partial<TOptions>, TOptionsDefaults]
|
||||||
|
>
|
||||||
|
>
|
||||||
|
|
||||||
|
/** Module definition passed to 'defineNuxtModule(...)' or 'defineNuxtModule().with(...)'. */
|
||||||
|
export interface ModuleDefinition<
|
||||||
|
TOptions extends ModuleOptions,
|
||||||
|
TOptionsDefaults extends Partial<TOptions> = Partial<TOptions>,
|
||||||
|
> {
|
||||||
meta?: ModuleMeta
|
meta?: ModuleMeta
|
||||||
defaults?: T | ((nuxt: Nuxt) => T)
|
defaults?: TOptionsDefaults | ((nuxt: Nuxt) => TOptionsDefaults)
|
||||||
schema?: T
|
schema?: TOptions
|
||||||
hooks?: Partial<NuxtHooks>
|
hooks?: Partial<NuxtHooks>
|
||||||
setup?: (this: void, resolvedOptions: T, nuxt: Nuxt) => _ModuleSetupReturn
|
setup?: (this: void, resolvedOptions: ResolvedModuleOptions<TOptions, TOptionsDefaults>, nuxt: Nuxt) => ModuleSetupReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NuxtModule<T extends ModuleOptions = ModuleOptions> {
|
export interface NuxtModule<
|
||||||
(this: void, inlineOptions: T, nuxt: Nuxt): _ModuleSetupReturn
|
TOptions extends ModuleOptions = ModuleOptions,
|
||||||
getOptions?: (inlineOptions?: T, nuxt?: Nuxt) => Promise<T>
|
TOptionsDefaults extends Partial<TOptions> = Partial<TOptions>,
|
||||||
|
> {
|
||||||
|
(this: void, resolvedOptions: ResolvedModuleOptions<TOptions, TOptionsDefaults>, nuxt: Nuxt): ModuleSetupReturn
|
||||||
|
getOptions?: (inlineOptions?: Partial<TOptions>, nuxt?: Nuxt) => Promise<ResolvedModuleOptions<TOptions, TOptionsDefaults>>
|
||||||
getMeta?: () => Promise<ModuleMeta>
|
getMeta?: () => Promise<ModuleMeta>
|
||||||
}
|
}
|
||||||
|
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',
|
||||||
[
|
[
|
||||||
|
18
test/fixtures/basic-types/types.ts
vendored
18
test/fixtures/basic-types/types.ts
vendored
@ -5,6 +5,7 @@ import type { NavigationFailure, RouteLocationNormalized, RouteLocationRaw, Rout
|
|||||||
|
|
||||||
import type { AppConfig, RuntimeValue, UpperSnakeCase } from 'nuxt/schema'
|
import type { AppConfig, RuntimeValue, UpperSnakeCase } from 'nuxt/schema'
|
||||||
import { defineNuxtConfig } from 'nuxt/config'
|
import { defineNuxtConfig } from 'nuxt/config'
|
||||||
|
import { defineNuxtModule } from 'nuxt/kit'
|
||||||
import { callWithNuxt, isVue3 } from '#app'
|
import { callWithNuxt, isVue3 } from '#app'
|
||||||
import type { NuxtError } from '#app'
|
import type { NuxtError } from '#app'
|
||||||
import type { NavigateToOptions } from '#app/composables/router'
|
import type { NavigateToOptions } from '#app/composables/router'
|
||||||
@ -242,6 +243,23 @@ describe('modules', () => {
|
|||||||
// @ts-expect-error we want to ensure we throw type error on invalid key
|
// @ts-expect-error we want to ensure we throw type error on invalid key
|
||||||
defineNuxtConfig({ undeclaredKey: { other: false } })
|
defineNuxtConfig({ undeclaredKey: { other: false } })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('correctly typed resolved options in defineNuxtModule setup using `.with()`', () => {
|
||||||
|
defineNuxtModule<{
|
||||||
|
foo?: string
|
||||||
|
baz: number
|
||||||
|
}>().with({
|
||||||
|
defaults: {
|
||||||
|
foo: 'bar',
|
||||||
|
},
|
||||||
|
setup: (resolvedOptions) => {
|
||||||
|
expectTypeOf(resolvedOptions).toEqualTypeOf<{
|
||||||
|
foo: string
|
||||||
|
baz?: number | undefined
|
||||||
|
}>()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('nuxtApp', () => {
|
describe('nuxtApp', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user