mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 23:22:02 +00:00
refactor(nuxt, kit): improve type strictness (#6685)
This commit is contained in:
parent
cdc75373d4
commit
e1e39b7e79
@ -11,7 +11,7 @@ export function isIgnored (pathname: string): boolean {
|
|||||||
|
|
||||||
// Happens with CLI reloads
|
// Happens with CLI reloads
|
||||||
if (!nuxt) {
|
if (!nuxt) {
|
||||||
return null
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nuxt._ignore) {
|
if (!nuxt._ignore) {
|
||||||
@ -28,5 +28,5 @@ export function isIgnored (pathname: string): boolean {
|
|||||||
if (relativePath.startsWith('..')) {
|
if (relativePath.startsWith('..')) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return relativePath && nuxt._ignore.ignores(relativePath)
|
return !!(relativePath && nuxt._ignore.ignores(relativePath))
|
||||||
}
|
}
|
||||||
|
@ -85,10 +85,10 @@ export function requireModulePkg (id: string, opts: RequireModuleOptions = {}) {
|
|||||||
/** Resolve the path of a module. */
|
/** Resolve the path of a module. */
|
||||||
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
||||||
return normalize(_require.resolve(id, {
|
return normalize(_require.resolve(id, {
|
||||||
paths: [].concat(
|
paths: ([] as string[]).concat(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.__NUXT_PREPATHS__,
|
global.__NUXT_PREPATHS__,
|
||||||
opts.paths,
|
opts.paths || [],
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.__NUXT_PATHS__
|
global.__NUXT_PATHS__
|
||||||
@ -100,8 +100,8 @@ export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
|||||||
export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}): string | null {
|
export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}): string | null {
|
||||||
try {
|
try {
|
||||||
return resolveModule(path, opts)
|
return resolveModule(path, opts)
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
if (error.code !== 'MODULE_NOT_FOUND') {
|
if (error?.code !== 'MODULE_NOT_FOUND') {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,11 @@ export function parallel<T, R> (
|
|||||||
return Promise.all(tasks.map(fn))
|
return Promise.all(tasks.map(fn))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function chainFn (base, fn) {
|
export function chainFn<Fn> (base: Fn, fn: Fn): Fn {
|
||||||
if (typeof fn !== 'function') {
|
if (typeof fn !== 'function') {
|
||||||
return base
|
return base
|
||||||
}
|
}
|
||||||
return function (...args) {
|
return function (this: any, ...args: any[]) {
|
||||||
if (typeof base !== 'function') {
|
if (typeof base !== 'function') {
|
||||||
return fn.apply(this, args)
|
return fn.apply(this, args)
|
||||||
}
|
}
|
||||||
@ -38,5 +38,5 @@ export function chainFn (base, fn) {
|
|||||||
return baseResult
|
return baseResult
|
||||||
}
|
}
|
||||||
return fnResult
|
return fnResult
|
||||||
}
|
} as unknown as Fn
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ import { useNuxt } from './context'
|
|||||||
import { logger } from './logger'
|
import { logger } from './logger'
|
||||||
import { addTemplate } from './template'
|
import { addTemplate } from './template'
|
||||||
|
|
||||||
export function addLayout (tmpl: NuxtTemplate, name?: string) {
|
export function addLayout (this: any, template: NuxtTemplate, name?: string) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
const { filename, src } = addTemplate(tmpl)
|
const { filename, src } = addTemplate(template)
|
||||||
const layoutName = kebabCase(name || parse(tmpl.filename).name).replace(/["']/g, '')
|
const layoutName = kebabCase(name || parse(filename).name).replace(/["']/g, '')
|
||||||
|
|
||||||
if (isNuxt2(nuxt)) {
|
if (isNuxt2(nuxt)) {
|
||||||
// Nuxt 2 adds layouts in options
|
// Nuxt 2 adds layouts in options
|
||||||
|
@ -7,7 +7,7 @@ import { NuxtConfigSchema } from '@nuxt/schema'
|
|||||||
export interface LoadNuxtConfigOptions extends LoadConfigOptions<NuxtConfig> {}
|
export interface LoadNuxtConfigOptions extends LoadConfigOptions<NuxtConfig> {}
|
||||||
|
|
||||||
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
|
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
|
||||||
const { config: nuxtConfig, configFile, layers, cwd } = await loadConfig<NuxtConfig>({
|
const result = await loadConfig<NuxtConfig>({
|
||||||
name: 'nuxt',
|
name: 'nuxt',
|
||||||
configFile: 'nuxt.config',
|
configFile: 'nuxt.config',
|
||||||
rcFile: '.nuxtrc',
|
rcFile: '.nuxtrc',
|
||||||
@ -15,6 +15,8 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
|
|||||||
globalRc: true,
|
globalRc: true,
|
||||||
...opts
|
...opts
|
||||||
})
|
})
|
||||||
|
const { configFile, layers = [], cwd } = result
|
||||||
|
const nuxtConfig = result.config!
|
||||||
|
|
||||||
// Fill config
|
// Fill config
|
||||||
nuxtConfig.rootDir = nuxtConfig.rootDir || cwd
|
nuxtConfig.rootDir = nuxtConfig.rootDir || cwd
|
||||||
@ -25,7 +27,7 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
|
|||||||
for (const layer of layers) {
|
for (const layer of layers) {
|
||||||
layer.config = layer.config || {}
|
layer.config = layer.config || {}
|
||||||
layer.config.rootDir = layer.config.rootDir ?? layer.cwd
|
layer.config.rootDir = layer.config.rootDir ?? layer.cwd
|
||||||
layer.config.srcDir = resolve(layer.config.rootDir, layer.config.srcDir)
|
layer.config.srcDir = resolve(layer.config.rootDir!, layer.config.srcDir!)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter layers
|
// Filter layers
|
||||||
|
@ -29,7 +29,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
|||||||
|
|
||||||
const nearestNuxtPkg = await Promise.all(['nuxt3', 'nuxt', 'nuxt-edge']
|
const nearestNuxtPkg = await Promise.all(['nuxt3', 'nuxt', 'nuxt-edge']
|
||||||
.map(pkg => resolvePackageJSON(pkg, { url: opts.cwd }).catch(() => null)))
|
.map(pkg => resolvePackageJSON(pkg, { url: opts.cwd }).catch(() => null)))
|
||||||
.then(r => r.filter(Boolean).sort((a, b) => b.length - a.length)[0])
|
.then(r => (r.filter(Boolean) as string[]).sort((a, b) => b.length - a.length)[0])
|
||||||
if (!nearestNuxtPkg) {
|
if (!nearestNuxtPkg) {
|
||||||
throw new Error(`Cannot find any nuxt version from ${opts.cwd}`)
|
throw new Error(`Cannot find any nuxt version from ${opts.cwd}`)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { relative } from 'pathe'
|
import { relative } from 'pathe'
|
||||||
import type { Nuxt, NuxtPluginTemplate, NuxtTemplate, ModuleContainer } from '@nuxt/schema'
|
import type { Nuxt, ModuleContainer } from '@nuxt/schema'
|
||||||
import { chainFn } from '../internal/task'
|
import { chainFn } from '../internal/task'
|
||||||
import { addTemplate } from '../template'
|
import { addTemplate } from '../template'
|
||||||
import { addLayout } from '../layout'
|
import { addLayout } from '../layout'
|
||||||
@ -12,11 +12,10 @@ import { installModule } from './install'
|
|||||||
const MODULE_CONTAINER_KEY = '__module_container__'
|
const MODULE_CONTAINER_KEY = '__module_container__'
|
||||||
|
|
||||||
export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer {
|
export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer {
|
||||||
if (nuxt[MODULE_CONTAINER_KEY]) {
|
// @ts-ignore
|
||||||
return nuxt[MODULE_CONTAINER_KEY]
|
if (nuxt[MODULE_CONTAINER_KEY]) { return nuxt[MODULE_CONTAINER_KEY] }
|
||||||
}
|
|
||||||
|
|
||||||
async function requireModule (moduleOpts) {
|
async function requireModule (moduleOpts: any) {
|
||||||
let src, inlineOptions
|
let src, inlineOptions
|
||||||
if (typeof moduleOpts === 'string') {
|
if (typeof moduleOpts === 'string') {
|
||||||
src = moduleOpts
|
src = moduleOpts
|
||||||
@ -35,7 +34,7 @@ export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer {
|
|||||||
await installModule(src, inlineOptions)
|
await installModule(src, inlineOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
nuxt[MODULE_CONTAINER_KEY] = <ModuleContainer>{
|
const container: ModuleContainer = {
|
||||||
nuxt,
|
nuxt,
|
||||||
options: nuxt.options,
|
options: nuxt.options,
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer {
|
|||||||
|
|
||||||
addServerMiddleware,
|
addServerMiddleware,
|
||||||
|
|
||||||
addTemplate (template: string | NuxtTemplate) {
|
addTemplate (template) {
|
||||||
if (typeof template === 'string') {
|
if (typeof template === 'string') {
|
||||||
template = { src: template }
|
template = { src: template }
|
||||||
}
|
}
|
||||||
@ -57,15 +56,15 @@ export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer {
|
|||||||
return addTemplate(template)
|
return addTemplate(template)
|
||||||
},
|
},
|
||||||
|
|
||||||
addPlugin (pluginTemplate: NuxtPluginTemplate): NuxtPluginTemplate {
|
addPlugin (pluginTemplate) {
|
||||||
return addPluginTemplate(pluginTemplate)
|
return addPluginTemplate(pluginTemplate)
|
||||||
},
|
},
|
||||||
|
|
||||||
addLayout (tmpl: NuxtTemplate, name?: string) {
|
addLayout (tmpl, name) {
|
||||||
return addLayout(tmpl, name)
|
return addLayout(tmpl, name)
|
||||||
},
|
},
|
||||||
|
|
||||||
addErrorLayout (dst: string) {
|
addErrorLayout (dst) {
|
||||||
const relativeBuildDir = relative(nuxt.options.rootDir, nuxt.options.buildDir)
|
const relativeBuildDir = relative(nuxt.options.rootDir, nuxt.options.buildDir)
|
||||||
nuxt.options.ErrorPage = `~/${relativeBuildDir}/${dst}`
|
nuxt.options.ErrorPage = `~/${relativeBuildDir}/${dst}`
|
||||||
},
|
},
|
||||||
@ -93,5 +92,9 @@ export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
nuxt[MODULE_CONTAINER_KEY] = container
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
return nuxt[MODULE_CONTAINER_KEY]
|
return nuxt[MODULE_CONTAINER_KEY]
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { promises as fsp } from 'node:fs'
|
|||||||
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 { Nuxt, NuxtTemplate, NuxtModule, ModuleOptions, ModuleDefinition } from '@nuxt/schema'
|
import type { Nuxt, NuxtModule, ModuleOptions, ModuleDefinition, NuxtOptions, ResolvedNuxtTemplate } from '@nuxt/schema'
|
||||||
import { logger } from '../logger'
|
import { logger } from '../logger'
|
||||||
import { useNuxt, nuxtCtx, tryUseNuxt } from '../context'
|
import { useNuxt, nuxtCtx, tryUseNuxt } from '../context'
|
||||||
import { isNuxt2, checkNuxtCompatibility } from '../compatibility'
|
import { isNuxt2, checkNuxtCompatibility } from '../compatibility'
|
||||||
@ -31,9 +31,9 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
|||||||
|
|
||||||
// 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
|
||||||
function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) {
|
function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) {
|
||||||
const configKey = definition.meta.configKey || definition.meta.name
|
const configKey = definition.meta!.configKey || definition.meta!.name!
|
||||||
const _defaults = definition.defaults instanceof Function ? definition.defaults(nuxt) : definition.defaults
|
const _defaults = definition.defaults instanceof Function ? definition.defaults(nuxt) : definition.defaults
|
||||||
let _options = defu(inlineOptions, nuxt.options[configKey], _defaults) as OptionsT
|
let _options = defu(inlineOptions, nuxt.options[configKey as keyof NuxtOptions], _defaults) as OptionsT
|
||||||
if (definition.schema) {
|
if (definition.schema) {
|
||||||
_options = applyDefaults(definition.schema, _options) as OptionsT
|
_options = applyDefaults(definition.schema, _options) as OptionsT
|
||||||
}
|
}
|
||||||
@ -41,13 +41,13 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Module format is always a simple function
|
// Module format is always a simple function
|
||||||
async function normalizedModule (inlineOptions: OptionsT, nuxt: Nuxt) {
|
async function normalizedModule (this: any, inlineOptions: OptionsT, nuxt: Nuxt) {
|
||||||
if (!nuxt) {
|
if (!nuxt) {
|
||||||
nuxt = tryUseNuxt() || this.nuxt /* invoked by nuxt 2 */
|
nuxt = tryUseNuxt() || this.nuxt /* invoked by nuxt 2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid duplicate installs
|
// Avoid duplicate installs
|
||||||
const uniqueKey = definition.meta.name || definition.meta.configKey
|
const uniqueKey = definition.meta!.name || definition.meta!.configKey
|
||||||
if (uniqueKey) {
|
if (uniqueKey) {
|
||||||
nuxt.options._requiredModules = nuxt.options._requiredModules || {}
|
nuxt.options._requiredModules = nuxt.options._requiredModules || {}
|
||||||
if (nuxt.options._requiredModules[uniqueKey]) {
|
if (nuxt.options._requiredModules[uniqueKey]) {
|
||||||
@ -58,10 +58,10 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check compatibility constraints
|
// Check compatibility constraints
|
||||||
if (definition.meta.compatibility) {
|
if (definition.meta!.compatibility) {
|
||||||
const issues = await checkNuxtCompatibility(definition.meta.compatibility, nuxt)
|
const issues = await checkNuxtCompatibility(definition.meta!.compatibility, nuxt)
|
||||||
if (issues.length) {
|
if (issues.length) {
|
||||||
logger.warn(`Module \`${definition.meta.name}\` is disabled due to incompatibility issues:\n${issues.toString()}`)
|
logger.warn(`Module \`${definition.meta!.name}\` is disabled due to incompatibility issues:\n${issues.toString()}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call setup
|
// Call setup
|
||||||
await definition.setup?.call(null, _options, nuxt)
|
await definition.setup?.call(null as any, _options, nuxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define getters for options and meta
|
// Define getters for options and meta
|
||||||
@ -92,11 +92,13 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
|
|||||||
const NUXT2_SHIMS_KEY = '__nuxt2_shims_key__'
|
const NUXT2_SHIMS_KEY = '__nuxt2_shims_key__'
|
||||||
function nuxt2Shims (nuxt: Nuxt) {
|
function nuxt2Shims (nuxt: Nuxt) {
|
||||||
// Avoid duplicate install and only apply to Nuxt2
|
// Avoid duplicate install and only apply to Nuxt2
|
||||||
|
// @ts-ignore
|
||||||
if (!isNuxt2(nuxt) || nuxt[NUXT2_SHIMS_KEY]) { return }
|
if (!isNuxt2(nuxt) || nuxt[NUXT2_SHIMS_KEY]) { return }
|
||||||
|
// @ts-ignore
|
||||||
nuxt[NUXT2_SHIMS_KEY] = true
|
nuxt[NUXT2_SHIMS_KEY] = true
|
||||||
|
|
||||||
// Allow using nuxt.hooks
|
// Allow using nuxt.hooks
|
||||||
// @ts-ignore Nuxt 2 extends hookable
|
// @ts-expect-error Nuxt 2 extends hookable
|
||||||
nuxt.hooks = nuxt
|
nuxt.hooks = nuxt
|
||||||
|
|
||||||
// Allow using useNuxt()
|
// Allow using useNuxt()
|
||||||
@ -106,7 +108,7 @@ function nuxt2Shims (nuxt: Nuxt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Support virtual templates with getContents() by writing them to .nuxt directory
|
// Support virtual templates with getContents() by writing them to .nuxt directory
|
||||||
let virtualTemplates: NuxtTemplate[]
|
let virtualTemplates: ResolvedNuxtTemplate[]
|
||||||
nuxt.hook('builder:prepared', (_builder, buildOptions) => {
|
nuxt.hook('builder:prepared', (_builder, buildOptions) => {
|
||||||
virtualTemplates = buildOptions.templates.filter(t => t.getContents)
|
virtualTemplates = buildOptions.templates.filter(t => t.getContents)
|
||||||
for (const template of virtualTemplates) {
|
for (const template of virtualTemplates) {
|
||||||
|
@ -10,7 +10,12 @@ export async function installModule (moduleToInstall: string | NuxtModule, _inli
|
|||||||
const { nuxtModule, inlineOptions } = await normalizeModule(moduleToInstall, _inlineOptions)
|
const { nuxtModule, inlineOptions } = await normalizeModule(moduleToInstall, _inlineOptions)
|
||||||
|
|
||||||
// Call module
|
// Call module
|
||||||
await nuxtModule.call(useModuleContainer(), inlineOptions, nuxt)
|
await nuxtModule.call(
|
||||||
|
// Provide this context for backwards compatibility with Nuxt 2
|
||||||
|
useModuleContainer() as any,
|
||||||
|
inlineOptions,
|
||||||
|
nuxt
|
||||||
|
)
|
||||||
|
|
||||||
nuxt.options._installedModules = nuxt.options._installedModules || []
|
nuxt.options._installedModules = nuxt.options._installedModules || []
|
||||||
nuxt.options._installedModules.push({
|
nuxt.options._installedModules.push({
|
||||||
|
@ -73,7 +73,7 @@ export function addPluginTemplate (plugin: NuxtPluginTemplate | string, opts: Ad
|
|||||||
const normalizedPlugin: NuxtPlugin = typeof plugin === 'string'
|
const normalizedPlugin: NuxtPlugin = typeof plugin === 'string'
|
||||||
? { src: plugin }
|
? { src: plugin }
|
||||||
// Update plugin src to template destination
|
// Update plugin src to template destination
|
||||||
: { ...plugin, src: addTemplate(plugin).dst }
|
: { ...plugin, src: addTemplate(plugin).dst! }
|
||||||
|
|
||||||
return addPlugin(normalizedPlugin, opts)
|
return addPlugin(normalizedPlugin, opts)
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ export function resolveAlias (path: string, alias?: Record<string, string>): str
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Resolver {
|
export interface Resolver {
|
||||||
resolve(...path): string
|
resolve(...path: string[]): string
|
||||||
resolvePath(path: string, opts?: ResolvePathOptions): Promise<string>
|
resolvePath(path: string, opts?: ResolvePathOptions): Promise<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { existsSync } from 'node:fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { basename, parse, resolve } from 'pathe'
|
import { basename, parse, resolve } from 'pathe'
|
||||||
import hash from 'hash-sum'
|
import hash from 'hash-sum'
|
||||||
import type { NuxtTemplate } from '@nuxt/schema'
|
import type { NuxtTemplate, ResolvedNuxtTemplate } from '@nuxt/schema'
|
||||||
import { useNuxt } from './context'
|
import { useNuxt } from './context'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders given template using lodash template during build into the project buildDir
|
* Renders given template using lodash template during build into the project buildDir
|
||||||
*/
|
*/
|
||||||
export function addTemplate (_template: NuxtTemplate | string) {
|
export function addTemplate (_template: NuxtTemplate<any> | string) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
|
|
||||||
// Noprmalize template
|
// Normalize template
|
||||||
const template = normalizeTemplate(_template)
|
const template = normalizeTemplate(_template)
|
||||||
|
|
||||||
// Remove any existing template with the same filename
|
// Remove any existing template with the same filename
|
||||||
@ -26,7 +26,7 @@ export function addTemplate (_template: NuxtTemplate | string) {
|
|||||||
/**
|
/**
|
||||||
* Normalize a nuxt template object
|
* Normalize a nuxt template object
|
||||||
*/
|
*/
|
||||||
export function normalizeTemplate (template: NuxtTemplate | string): NuxtTemplate {
|
export function normalizeTemplate (template: NuxtTemplate<any> | string): ResolvedNuxtTemplate<any> {
|
||||||
if (!template) {
|
if (!template) {
|
||||||
throw new Error('Invalid template: ' + JSON.stringify(template))
|
throw new Error('Invalid template: ' + JSON.stringify(template))
|
||||||
}
|
}
|
||||||
@ -69,5 +69,5 @@ export function normalizeTemplate (template: NuxtTemplate | string): NuxtTemplat
|
|||||||
template.dst = resolve(nuxt.options.buildDir, template.filename)
|
template.dst = resolve(nuxt.options.buildDir, template.filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
return template
|
return template as ResolvedNuxtTemplate<any>
|
||||||
}
|
}
|
||||||
|
11
packages/kit/tsconfig.json
Normal file
11
packages/kit/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"./src/**/*.ts",
|
||||||
|
"./test/**/*.ts"
|
||||||
|
]
|
||||||
|
}
|
@ -34,7 +34,7 @@ export const clearError = async (options: { redirect?: string } = {}) => {
|
|||||||
error.value = null
|
error.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isNuxtError = (err?: string | object): err is NuxtError => err && typeof err === 'object' && ('__nuxt_error' in err)
|
export const isNuxtError = (err?: string | object): err is NuxtError => !!(err && typeof err === 'object' && ('__nuxt_error' in err))
|
||||||
|
|
||||||
export const createError = (err: string | Partial<NuxtError>): NuxtError => {
|
export const createError = (err: string | Partial<NuxtError>): NuxtError => {
|
||||||
const _err: NuxtError = _createError(err)
|
const _err: NuxtError = _createError(err)
|
||||||
|
@ -80,7 +80,7 @@ interface _NuxtApp {
|
|||||||
message: string
|
message: string
|
||||||
description: string
|
description: string
|
||||||
data?: any
|
data?: any
|
||||||
}
|
} | null
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,9 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx
|
|||||||
if (s.hasChanged()) {
|
if (s.hasChanged()) {
|
||||||
return {
|
return {
|
||||||
code: s.toString(),
|
code: s.toString(),
|
||||||
map: sourcemap && s.generateMap({ source: id, includeContent: true })
|
map: sourcemap
|
||||||
|
? s.generateMap({ source: id, includeContent: true })
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,9 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
|
|||||||
if (s.hasChanged()) {
|
if (s.hasChanged()) {
|
||||||
return {
|
return {
|
||||||
code: s.toString(),
|
code: s.toString(),
|
||||||
map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
|
map: options.sourcemap
|
||||||
|
? s.generateMap({ source: id, includeContent: true })
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import { TreeShakeTemplatePlugin } from './tree-shake'
|
|||||||
|
|
||||||
const isPureObjectOrString = (val: any) => (!Array.isArray(val) && typeof val === 'object') || typeof val === 'string'
|
const isPureObjectOrString = (val: any) => (!Array.isArray(val) && typeof val === 'object') || typeof val === 'string'
|
||||||
const isDirectory = (p: string) => { try { return statSync(p).isDirectory() } catch (_e) { return false } }
|
const isDirectory = (p: string) => { try { return statSync(p).isDirectory() } catch (_e) { return false } }
|
||||||
function compareDirByPathLength ({ path: pathA }, { path: pathB }) {
|
function compareDirByPathLength ({ path: pathA }: { path: string}, { path: pathB }: { path: string}) {
|
||||||
return pathB.split(/[\\/]/).filter(Boolean).length - pathA.split(/[\\/]/).filter(Boolean).length
|
return pathB.split(/[\\/]/).filter(Boolean).length - pathA.split(/[\\/]/).filter(Boolean).length
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
dirs: []
|
dirs: []
|
||||||
},
|
},
|
||||||
setup (componentOptions, nuxt) {
|
setup (componentOptions, nuxt) {
|
||||||
let componentDirs = []
|
let componentDirs: ComponentsDir[] = []
|
||||||
const context = {
|
const context = {
|
||||||
components: [] as Component[]
|
components: [] as Component[]
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
: context.components
|
: context.components
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizeDirs = (dir: any, cwd: string) => {
|
const normalizeDirs = (dir: any, cwd: string): ComponentsDir[] => {
|
||||||
if (Array.isArray(dir)) {
|
if (Array.isArray(dir)) {
|
||||||
return dir.map(dir => normalizeDirs(dir, cwd)).flat().sort(compareDirByPathLength)
|
return dir.map(dir => normalizeDirs(dir, cwd)).flat().sort(compareDirByPathLength)
|
||||||
}
|
}
|
||||||
@ -48,14 +48,14 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
if (typeof dir === 'string') {
|
if (typeof dir === 'string') {
|
||||||
return {
|
return [
|
||||||
path: resolve(cwd, resolveAlias(dir))
|
{ path: resolve(cwd, resolveAlias(dir)) }
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
const dirs = (dir.dirs || [dir]).map(dir => typeof dir === 'string' ? { path: dir } : dir).filter(_dir => _dir.path)
|
const dirs: ComponentsDir[] = (dir.dirs || [dir]).map((dir: any): ComponentsDir => typeof dir === 'string' ? { path: dir } : dir).filter((_dir: ComponentsDir) => _dir.path)
|
||||||
return dirs.map(_dir => ({
|
return dirs.map(_dir => ({
|
||||||
..._dir,
|
..._dir,
|
||||||
path: resolve(cwd, resolveAlias(_dir.path))
|
path: resolve(cwd, resolveAlias(_dir.path))
|
||||||
@ -113,7 +113,7 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
// components.d.ts
|
// components.d.ts
|
||||||
addTemplate({ ...componentsTypeTemplate, options: { getComponents } })
|
addTemplate({ ...componentsTypeTemplate, options: { getComponents } })
|
||||||
// components.plugin.mjs
|
// components.plugin.mjs
|
||||||
addPluginTemplate({ ...componentsPluginTemplate, options: { getComponents } })
|
addPluginTemplate({ ...componentsPluginTemplate, options: { getComponents } } as any)
|
||||||
// components.server.mjs
|
// components.server.mjs
|
||||||
addTemplate({ ...componentsTemplate, filename: 'components.server.mjs', options: { getComponents, mode: 'server' } })
|
addTemplate({ ...componentsTemplate, filename: 'components.server.mjs', options: { getComponents, mode: 'server' } })
|
||||||
// components.client.mjs
|
// components.client.mjs
|
||||||
@ -121,12 +121,12 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
|
|
||||||
nuxt.hook('vite:extendConfig', (config, { isClient }) => {
|
nuxt.hook('vite:extendConfig', (config, { isClient }) => {
|
||||||
const mode = isClient ? 'client' : 'server'
|
const mode = isClient ? 'client' : 'server'
|
||||||
config.resolve.alias['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
;(config.resolve!.alias as any)['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
||||||
})
|
})
|
||||||
nuxt.hook('webpack:config', (configs) => {
|
nuxt.hook('webpack:config', (configs) => {
|
||||||
for (const config of configs) {
|
for (const config of configs) {
|
||||||
const mode = config.name === 'server' ? 'server' : 'client'
|
const mode = config.name === 'server' ? 'server' : 'client'
|
||||||
config.resolve.alias['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
;(config.resolve!.alias as any)['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -58,12 +58,12 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
|
|||||||
*
|
*
|
||||||
* @example third-components/index.vue -> third-component
|
* @example third-components/index.vue -> third-component
|
||||||
* if not take the filename
|
* if not take the filename
|
||||||
* @example thid-components/Awesome.vue -> Awesome
|
* @example third-components/Awesome.vue -> Awesome
|
||||||
*/
|
*/
|
||||||
let fileName = basename(filePath, extname(filePath))
|
let fileName = basename(filePath, extname(filePath))
|
||||||
|
|
||||||
const global = /\.(global)$/.test(fileName) || dir.global
|
const global = /\.(global)$/.test(fileName) || dir.global
|
||||||
const mode = fileName.match(/(?<=\.)(client|server)(\.global)?$/)?.[1] as 'client' | 'server' || 'all'
|
const mode = (fileName.match(/(?<=\.)(client|server)(\.global)?$/)?.[1] || 'all') as 'client' | 'server' | 'all'
|
||||||
fileName = fileName.replace(/(\.(client|server))?(\.global)?$/, '')
|
fileName = fileName.replace(/(\.(client|server))?(\.global)?$/, '')
|
||||||
|
|
||||||
if (fileName.toLowerCase() === 'index') {
|
if (fileName.toLowerCase() === 'index') {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { isAbsolute, relative } from 'pathe'
|
import { isAbsolute, relative } from 'pathe'
|
||||||
import type { Component, Nuxt } from '@nuxt/schema'
|
import type { Component, Nuxt, NuxtPluginTemplate, NuxtTemplate } from '@nuxt/schema'
|
||||||
import { genDynamicImport, genExport, genObjectFromRawEntries } from 'knitwork'
|
import { genDynamicImport, genExport, genObjectFromRawEntries } from 'knitwork'
|
||||||
|
|
||||||
export interface ComponentsTemplateContext {
|
export interface ComponentsTemplateContext {
|
||||||
@ -25,9 +25,9 @@ const createImportMagicComments = (options: ImportMagicCommentsOptions) => {
|
|||||||
].filter(Boolean).join(', ')
|
].filter(Boolean).join(', ')
|
||||||
}
|
}
|
||||||
|
|
||||||
export const componentsPluginTemplate = {
|
export const componentsPluginTemplate: NuxtPluginTemplate<ComponentsTemplateContext> = {
|
||||||
filename: 'components.plugin.mjs',
|
filename: 'components.plugin.mjs',
|
||||||
getContents ({ options }: ComponentsTemplateContext) {
|
getContents ({ options }) {
|
||||||
const globalComponents = options.getComponents().filter(c => c.global === true)
|
const globalComponents = options.getComponents().filter(c => c.global === true)
|
||||||
|
|
||||||
return `import { defineAsyncComponent } from 'vue'
|
return `import { defineAsyncComponent } from 'vue'
|
||||||
@ -50,9 +50,9 @@ export default defineNuxtPlugin(nuxtApp => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const componentsTemplate = {
|
export const componentsTemplate: NuxtTemplate<ComponentsTemplateContext> = {
|
||||||
// components.[server|client].mjs'
|
// components.[server|client].mjs'
|
||||||
getContents ({ options }: ComponentsTemplateContext) {
|
getContents ({ options }) {
|
||||||
return [
|
return [
|
||||||
'import { defineAsyncComponent } from \'vue\'',
|
'import { defineAsyncComponent } from \'vue\'',
|
||||||
...options.getComponents(options.mode).flatMap((c) => {
|
...options.getComponents(options.mode).flatMap((c) => {
|
||||||
@ -69,9 +69,9 @@ export const componentsTemplate = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const componentsTypeTemplate = {
|
export const componentsTypeTemplate: NuxtTemplate<ComponentsTemplateContext> = {
|
||||||
filename: 'components.d.ts',
|
filename: 'components.d.ts',
|
||||||
getContents: ({ options, nuxt }: ComponentsTemplateContext) => {
|
getContents: ({ options, nuxt }) => {
|
||||||
const buildDir = nuxt.options.buildDir
|
const buildDir = nuxt.options.buildDir
|
||||||
const componentTypes = options.getComponents().map(c => [
|
const componentTypes = options.getComponents().map(c => [
|
||||||
c.pascalName,
|
c.pascalName,
|
||||||
|
@ -31,7 +31,7 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat
|
|||||||
regexpMap.set(components, new RegExp(`(${clientOnlyComponents.join('|')})`, 'g'))
|
regexpMap.set(components, new RegExp(`(${clientOnlyComponents.join('|')})`, 'g'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const COMPONENTS_RE = regexpMap.get(components)
|
const COMPONENTS_RE = regexpMap.get(components)!
|
||||||
const s = new MagicString(code)
|
const s = new MagicString(code)
|
||||||
|
|
||||||
// Do not render client-only slots on SSR, but preserve attributes
|
// Do not render client-only slots on SSR, but preserve attributes
|
||||||
@ -40,7 +40,9 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat
|
|||||||
if (s.hasChanged()) {
|
if (s.hasChanged()) {
|
||||||
return {
|
return {
|
||||||
code: s.toString(),
|
code: s.toString(),
|
||||||
map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
|
map: options.sourcemap
|
||||||
|
? s.generateMap({ source: id, includeContent: true })
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ export const vueAppPatterns = (nuxt: Nuxt) => [
|
|||||||
[/^(nuxt3|nuxt)$/, '`nuxt3`/`nuxt` cannot be imported directly. Instead, import runtime Nuxt composables from `#app` or `#imports`.'],
|
[/^(nuxt3|nuxt)$/, '`nuxt3`/`nuxt` cannot be imported directly. Instead, import runtime Nuxt composables from `#app` or `#imports`.'],
|
||||||
[/^((|~|~~|@|@@)\/)?nuxt\.config(\.|$)/, 'Importing directly from a `nuxt.config` file is not allowed. Instead, use runtime config or a module.'],
|
[/^((|~|~~|@|@@)\/)?nuxt\.config(\.|$)/, 'Importing directly from a `nuxt.config` file is not allowed. Instead, use runtime config or a module.'],
|
||||||
[/(^|node_modules\/)@vue\/composition-api/],
|
[/(^|node_modules\/)@vue\/composition-api/],
|
||||||
...nuxt.options.modules.filter(m => typeof m === 'string').map((m: string) =>
|
...nuxt.options.modules.filter(m => typeof m === 'string').map((m: any) =>
|
||||||
[new RegExp(`^${escapeRE(m)}$`), 'Importing directly from module entry points is not allowed.']),
|
[new RegExp(`^${escapeRE(m as string)}$`), 'Importing directly from module entry points is not allowed.']),
|
||||||
...[/(^|node_modules\/)@nuxt\/kit/, /^nitropack/]
|
...[/(^|node_modules\/)@nuxt\/kit/, /^nitropack/]
|
||||||
.map(i => [i, 'This module cannot be imported in the Vue part of your app.']),
|
.map(i => [i, 'This module cannot be imported in the Vue part of your app.']),
|
||||||
[new RegExp(escapeRE(resolve(nuxt.options.srcDir, (nuxt.options.dir as any).server || 'server')) + '\\/(api|routes|middleware|plugins)\\/'), 'Importing from server is not allowed in the Vue part of your app.']
|
[new RegExp(escapeRE(resolve(nuxt.options.srcDir, (nuxt.options.dir as any).server || 'server')) + '\\/(api|routes|middleware|plugins)\\/'), 'Importing from server is not allowed in the Vue part of your app.']
|
||||||
@ -31,10 +31,11 @@ export const ImportProtectionPlugin = createUnplugin(function (options: ImportPr
|
|||||||
name: 'nuxt:import-protection',
|
name: 'nuxt:import-protection',
|
||||||
enforce: 'pre',
|
enforce: 'pre',
|
||||||
resolveId (id, importer) {
|
resolveId (id, importer) {
|
||||||
|
if (!importer) { return }
|
||||||
if (importersToExclude.some(p => typeof p === 'string' ? importer === p : p.test(importer))) { return }
|
if (importersToExclude.some(p => typeof p === 'string' ? importer === p : p.test(importer))) { return }
|
||||||
|
|
||||||
const invalidImports = options.patterns.filter(([pattern]) => pattern instanceof RegExp ? pattern.test(id) : pattern === id)
|
const invalidImports = options.patterns.filter(([pattern]) => pattern instanceof RegExp ? pattern.test(id) : pattern === id)
|
||||||
let matched: boolean
|
let matched = false
|
||||||
for (const match of invalidImports) {
|
for (const match of invalidImports) {
|
||||||
cache[id] = cache[id] || new Map()
|
cache[id] = cache[id] || new Map()
|
||||||
const [pattern, warning] = match
|
const [pattern, warning] = match
|
||||||
|
@ -35,13 +35,15 @@ export const TreeShakePlugin = createUnplugin((options: TreeShakePluginOptions)
|
|||||||
const s = new MagicString(code)
|
const s = new MagicString(code)
|
||||||
const strippedCode = stripLiteral(code)
|
const strippedCode = stripLiteral(code)
|
||||||
for (const match of strippedCode.matchAll(COMPOSABLE_RE) || []) {
|
for (const match of strippedCode.matchAll(COMPOSABLE_RE) || []) {
|
||||||
s.overwrite(match.index, match.index + match[0].length, `${match[1]} /*#__PURE__*/ false && ${match[2]}`)
|
s.overwrite(match.index!, match.index! + match[0].length, `${match[1]} /*#__PURE__*/ false && ${match[2]}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s.hasChanged()) {
|
if (s.hasChanged()) {
|
||||||
return {
|
return {
|
||||||
code: s.toString(),
|
code: s.toString(),
|
||||||
map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
|
map: options.sourcemap
|
||||||
|
? s.generateMap({ source: id, includeContent: true })
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
if (!vm) { return }
|
if (!vm) { return }
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
head.removeHeadObjs(headObj)
|
head.removeHeadObjs(headObj as any)
|
||||||
head.updateDOM()
|
head.updateDOM()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ export default defineNuxtModule({
|
|||||||
// Check for router options
|
// Check for router options
|
||||||
const routerOptionsFiles = (await Promise.all(nuxt.options._layers.map(
|
const routerOptionsFiles = (await Promise.all(nuxt.options._layers.map(
|
||||||
async layer => await findPath(resolve(layer.config.srcDir, 'app/router.options'))
|
async layer => await findPath(resolve(layer.config.srcDir, 'app/router.options'))
|
||||||
))).filter(Boolean)
|
))).filter(Boolean) as string[]
|
||||||
|
|
||||||
const configRouterOptions = genObjectFromRawEntries(Object.entries(nuxt.options.router.options)
|
const configRouterOptions = genObjectFromRawEntries(Object.entries(nuxt.options.router.options)
|
||||||
.map(([key, value]) => [key, genString(value as string)]))
|
.map(([key, value]) => [key, genString(value as string)]))
|
||||||
|
@ -20,8 +20,8 @@ describe('auto-imports:transform', () => {
|
|||||||
|
|
||||||
const transformPlugin = TransformPlugin.raw({ ctx, options: { transform: { exclude: [/node_modules/] } } }, { framework: 'rollup' })
|
const transformPlugin = TransformPlugin.raw({ ctx, options: { transform: { exclude: [/node_modules/] } } }, { framework: 'rollup' })
|
||||||
const transform = async (source: string) => {
|
const transform = async (source: string) => {
|
||||||
const { code } = await transformPlugin.transform.call({ error: null, warn: null }, source, '') || { code: null }
|
const result = await transformPlugin.transform!.call({ error: null, warn: null } as any, source, '')
|
||||||
return code
|
return typeof result === 'string' ? result : result?.code
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should correct inject', async () => {
|
it('should correct inject', async () => {
|
||||||
@ -29,13 +29,13 @@ describe('auto-imports:transform', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should ignore existing imported', async () => {
|
it('should ignore existing imported', async () => {
|
||||||
expect(await transform('import { ref } from "foo"; const a = ref(0)')).to.equal(null)
|
expect(await transform('import { ref } from "foo"; const a = ref(0)')).to.equal(undefined)
|
||||||
expect(await transform('import { computed as ref } from "foo"; const a = ref(0)')).to.equal(null)
|
expect(await transform('import { computed as ref } from "foo"; const a = ref(0)')).to.equal(undefined)
|
||||||
expect(await transform('import ref from "foo"; const a = ref(0)')).to.equal(null)
|
expect(await transform('import ref from "foo"; const a = ref(0)')).to.equal(undefined)
|
||||||
expect(await transform('import { z as ref } from "foo"; const a = ref(0)')).to.equal(null)
|
expect(await transform('import { z as ref } from "foo"; const a = ref(0)')).to.equal(undefined)
|
||||||
expect(await transform('let ref = () => {}; const a = ref(0)')).to.equal(null)
|
expect(await transform('let ref = () => {}; const a = ref(0)')).to.equal(undefined)
|
||||||
expect(await transform('let { ref } = Vue; const a = ref(0)')).to.equal(null)
|
expect(await transform('let { ref } = Vue; const a = ref(0)')).to.equal(undefined)
|
||||||
expect(await transform('let [\ncomputed,\nref\n] = Vue; const a = ref(0); const b = ref(0)')).to.equal(null)
|
expect(await transform('let [\ncomputed,\nref\n] = Vue; const a = ref(0); const b = ref(0)')).to.equal(undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should ignore comments', async () => {
|
it('should ignore comments', async () => {
|
||||||
@ -48,7 +48,7 @@ describe('auto-imports:transform', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should exclude files from transform', async () => {
|
it('should exclude files from transform', async () => {
|
||||||
expect(await transform('excluded')).toEqual(null)
|
expect(await transform('excluded')).toEqual(undefined)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ describe('auto-imports:nuxt', () => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
it(`should register ${name} globally`, () => {
|
it(`should register ${name} globally`, () => {
|
||||||
expect(defaultPresets.find(a => a.from === '#app').imports).to.include(name)
|
expect(defaultPresets.find(a => a.from === '#app')!.imports).to.include(name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -176,7 +176,7 @@ describe('auto-imports:vue', () => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
it(`should register ${name} globally`, () => {
|
it(`should register ${name} globally`, () => {
|
||||||
expect(defaultPresets.find(a => a.from === 'vue').imports).toContain(name)
|
expect(defaultPresets.find(a => a.from === 'vue')!.imports).toContain(name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -304,7 +304,7 @@ describe('pages:generateRouteKey', () => {
|
|||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{ description: 'should handle overrides', override: 'key', route: getRouteProps(), output: 'key' },
|
{ description: 'should handle overrides', override: 'key', route: getRouteProps(), output: 'key' },
|
||||||
{ description: 'should handle overrides', override: route => route.meta.key as string, route: getRouteProps(), output: 'route-meta-key' },
|
{ description: 'should handle overrides', override: (route: any) => route.meta.key as string, route: getRouteProps(), output: 'route-meta-key' },
|
||||||
{ description: 'should handle overrides', override: false as any, route: getRouteProps(), output: false },
|
{ description: 'should handle overrides', override: false as any, route: getRouteProps(), output: false },
|
||||||
{
|
{
|
||||||
description: 'should key dynamic routes without keys',
|
description: 'should key dynamic routes without keys',
|
||||||
|
@ -4,7 +4,7 @@ import { expect, it, vi } from 'vitest'
|
|||||||
import { scanComponents } from '../src/components/scan'
|
import { scanComponents } from '../src/components/scan'
|
||||||
|
|
||||||
const fixtureDir = resolve(__dirname, 'fixture')
|
const fixtureDir = resolve(__dirname, 'fixture')
|
||||||
const rFixture = (...p) => resolve(fixtureDir, ...p)
|
const rFixture = (...p: string[]) => resolve(fixtureDir, ...p)
|
||||||
|
|
||||||
vi.mock('@nuxt/kit', () => ({
|
vi.mock('@nuxt/kit', () => ({
|
||||||
isIgnored: () => false
|
isIgnored: () => false
|
||||||
@ -108,6 +108,7 @@ const srcDir = rFixture('.')
|
|||||||
it('components:scanComponents', async () => {
|
it('components:scanComponents', async () => {
|
||||||
const scannedComponents = await scanComponents(dirs, srcDir)
|
const scannedComponents = await scanComponents(dirs, srcDir)
|
||||||
for (const c of scannedComponents) {
|
for (const c of scannedComponents) {
|
||||||
|
// @ts-ignore
|
||||||
delete c.filePath
|
delete c.filePath
|
||||||
}
|
}
|
||||||
expect(scannedComponents).deep.eq(expectedComponents)
|
expect(scannedComponents).deep.eq(expectedComponents)
|
||||||
|
@ -9,7 +9,7 @@ import type { NuxtTemplate, Nuxt, NuxtApp } from './nuxt'
|
|||||||
import type { Preset as ImportPreset, Import } from 'unimport'
|
import type { Preset as ImportPreset, Import } from 'unimport'
|
||||||
import type { NuxtConfig, NuxtOptions } from './config'
|
import type { NuxtConfig, NuxtOptions } from './config'
|
||||||
import type { Nitro, NitroConfig } from 'nitropack'
|
import type { Nitro, NitroConfig } from 'nitropack'
|
||||||
import type { Component, ComponentsDir, ScanDir, ComponentsOptions } from './components'
|
import type { Component, ComponentsOptions } from './components'
|
||||||
import { NuxtCompatibility, NuxtCompatibilityIssues } from '..'
|
import { NuxtCompatibility, NuxtCompatibilityIssues } from '..'
|
||||||
|
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ export interface NuxtHooks {
|
|||||||
|
|
||||||
// Components
|
// Components
|
||||||
'components:dirs': (dirs: ComponentsOptions['dirs']) => HookResult
|
'components:dirs': (dirs: ComponentsOptions['dirs']) => HookResult
|
||||||
'components:extend': (components: (Component | ComponentsDir | ScanDir)[]) => HookResult
|
'components:extend': (components: Component[]) => HookResult
|
||||||
|
|
||||||
// @nuxt/builder
|
// @nuxt/builder
|
||||||
'build:before':
|
'build:before':
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NuxtHooks } from './hooks'
|
import { NuxtHooks } from './hooks'
|
||||||
import type { Nuxt, NuxtTemplate } from "./nuxt"
|
import type { Nuxt, NuxtPluginTemplate, NuxtTemplate } from "./nuxt"
|
||||||
import type { NuxtCompatibility } from './compatibility'
|
import type { NuxtCompatibility } from './compatibility'
|
||||||
|
|
||||||
export interface ModuleMeta {
|
export interface ModuleMeta {
|
||||||
@ -58,6 +58,9 @@ export interface ModuleContainer {
|
|||||||
/** Renders given template using lodash template during build into the project buildDir (`.nuxt`).*/
|
/** Renders given template using lodash template during build into the project buildDir (`.nuxt`).*/
|
||||||
addTemplate(template: string | NuxtTemplate): NuxtTemplate
|
addTemplate(template: string | NuxtTemplate): NuxtTemplate
|
||||||
|
|
||||||
|
/** Registers a custom plugin. */
|
||||||
|
addPlugin(template: NuxtPluginTemplate): NuxtPluginTemplate
|
||||||
|
|
||||||
/** Registers a custom layout. If its name is 'error' it will override the default error layout. */
|
/** Registers a custom layout. If its name is 'error' it will override the default error layout. */
|
||||||
addLayout(tmpl: NuxtTemplate, name: string): any
|
addLayout(tmpl: NuxtTemplate, name: string): any
|
||||||
|
|
||||||
|
@ -34,15 +34,20 @@ export interface NuxtTemplate<Options = Record<string, any>> {
|
|||||||
/** The target filename once the template is copied into the Nuxt buildDir */
|
/** The target filename once the template is copied into the Nuxt buildDir */
|
||||||
filename?: string
|
filename?: string
|
||||||
/** An options object that will be accessible within the template via `<% options %>` */
|
/** An options object that will be accessible within the template via `<% options %>` */
|
||||||
options?: Record<string, any>
|
options?: Options
|
||||||
/** The resolved path to the source file to be template */
|
/** The resolved path to the source file to be template */
|
||||||
src?: string
|
src?: string
|
||||||
/** Provided compile option instead of src */
|
/** Provided compile option instead of src */
|
||||||
getContents?: (data: Record<string, any>) => string | Promise<string>
|
getContents?: (data: Options) => string | Promise<string>
|
||||||
/** Write to filesystem */
|
/** Write to filesystem */
|
||||||
write?: boolean
|
write?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ResolvedNuxtTemplate<Options = Record<string, any>> extends NuxtTemplate<Options> {
|
||||||
|
filename: string
|
||||||
|
dst: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface NuxtPlugin {
|
export interface NuxtPlugin {
|
||||||
/** @deprecated use mode */
|
/** @deprecated use mode */
|
||||||
ssr?: boolean
|
ssr?: boolean
|
||||||
@ -63,5 +68,5 @@ export interface NuxtApp {
|
|||||||
configs: string[]
|
configs: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
type _TemplatePlugin = Omit<NuxtPlugin, 'src'> & NuxtTemplate
|
type _TemplatePlugin<Options> = Omit<NuxtPlugin, 'src'> & NuxtTemplate<Options>
|
||||||
export interface NuxtPluginTemplate extends _TemplatePlugin { }
|
export interface NuxtPluginTemplate<Options = Record<string, any>> extends _TemplatePlugin<Options> { }
|
||||||
|
Loading…
Reference in New Issue
Block a user