mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 23:22:02 +00:00
feat(kit,nuxt,vite,webpack): add toArray
util (#24857)
This commit is contained in:
parent
cf1a698ed8
commit
a2ef3091e8
@ -1,6 +1,7 @@
|
||||
import type { Configuration as WebpackConfig, WebpackPluginInstance } from 'webpack'
|
||||
import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
|
||||
import { useNuxt } from './context'
|
||||
import { toArray } from './utils'
|
||||
|
||||
export interface ExtendConfigOptions {
|
||||
/**
|
||||
@ -108,11 +109,7 @@ export function addWebpackPlugin (pluginOrGetter: WebpackPluginInstance | Webpac
|
||||
const plugin = typeof pluginOrGetter === 'function' ? pluginOrGetter() : pluginOrGetter
|
||||
|
||||
config.plugins = config.plugins || []
|
||||
if (Array.isArray(plugin)) {
|
||||
config.plugins[method](...plugin)
|
||||
} else {
|
||||
config.plugins[method](plugin)
|
||||
}
|
||||
config.plugins[method](...toArray(plugin))
|
||||
}, options)
|
||||
}
|
||||
|
||||
@ -125,11 +122,7 @@ export function addVitePlugin (pluginOrGetter: VitePlugin | VitePlugin[] | (() =
|
||||
const plugin = typeof pluginOrGetter === 'function' ? pluginOrGetter() : pluginOrGetter
|
||||
|
||||
config.plugins = config.plugins || []
|
||||
if (Array.isArray(plugin)) {
|
||||
config.plugins[method](...plugin)
|
||||
} else {
|
||||
config.plugins[method](plugin)
|
||||
}
|
||||
config.plugins[method](...toArray(plugin))
|
||||
}, options)
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,13 @@ import type { Import } from 'unimport'
|
||||
import type { ImportPresetWithDeprecation } from '@nuxt/schema'
|
||||
import { useNuxt } from './context'
|
||||
import { assertNuxtCompatibility } from './compatibility'
|
||||
import { toArray } from './utils'
|
||||
|
||||
export function addImports (imports: Import | Import[]) {
|
||||
assertNuxtCompatibility({ bridge: true })
|
||||
|
||||
useNuxt().hook('imports:extend', (_imports) => {
|
||||
_imports.push(...(Array.isArray(imports) ? imports : [imports]))
|
||||
_imports.push(...toArray(imports))
|
||||
})
|
||||
}
|
||||
|
||||
@ -15,7 +16,7 @@ export function addImportsDir (dirs: string | string[], opts: { prepend?: boolea
|
||||
assertNuxtCompatibility({ bridge: true })
|
||||
|
||||
useNuxt().hook('imports:dirs', (_dirs: string[]) => {
|
||||
for (const dir of (Array.isArray(dirs) ? dirs : [dirs])) {
|
||||
for (const dir of toArray(dirs)) {
|
||||
_dirs[opts.prepend ? 'unshift' : 'push'](dir)
|
||||
}
|
||||
})
|
||||
@ -24,7 +25,7 @@ export function addImportsSources (presets: ImportPresetWithDeprecation | Import
|
||||
assertNuxtCompatibility({ bridge: true })
|
||||
|
||||
useNuxt().hook('imports:sources', (_presets: ImportPresetWithDeprecation[]) => {
|
||||
for (const preset of (Array.isArray(presets) ? presets : [presets])) {
|
||||
for (const preset of toArray(presets)) {
|
||||
_presets.push(preset)
|
||||
}
|
||||
})
|
||||
|
@ -5,6 +5,7 @@ import { genDynamicImport, genImport, genSafeVariableName } from 'knitwork'
|
||||
|
||||
import type { NuxtTemplate } from '@nuxt/schema'
|
||||
import { logger } from '../logger'
|
||||
import { toArray } from '../utils'
|
||||
|
||||
/** @deprecated */
|
||||
// TODO: Remove support for compiling ejs templates in v4
|
||||
@ -30,10 +31,7 @@ const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"{(.+)}"
|
||||
|
||||
/** @deprecated */
|
||||
const importSources = (sources: string | string[], { lazy = false } = {}) => {
|
||||
if (!Array.isArray(sources)) {
|
||||
sources = [sources]
|
||||
}
|
||||
return sources.map((src) => {
|
||||
return toArray(sources).map((src) => {
|
||||
if (lazy) {
|
||||
return `const ${genSafeVariableName(src)} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}`
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import type { Nitro, NitroDevEventHandler, NitroEventHandler } from 'nitropack'
|
||||
import type { Import } from 'unimport'
|
||||
import { normalize } from 'pathe'
|
||||
import { useNuxt } from './context'
|
||||
import { toArray } from './utils'
|
||||
|
||||
/**
|
||||
* normalize handler object
|
||||
@ -47,10 +48,8 @@ export function addServerPlugin (plugin: string) {
|
||||
*/
|
||||
export function addPrerenderRoutes (routes: string | string[]) {
|
||||
const nuxt = useNuxt()
|
||||
if (!Array.isArray(routes)) {
|
||||
routes = [routes]
|
||||
}
|
||||
routes = routes.filter(Boolean)
|
||||
|
||||
routes = toArray(routes).filter(Boolean)
|
||||
if (!routes.length) {
|
||||
return
|
||||
}
|
||||
@ -90,11 +89,8 @@ export function addServerImports (imports: Import[]) {
|
||||
const nuxt = useNuxt()
|
||||
nuxt.hook('nitro:config', (config) => {
|
||||
config.imports = config.imports || {}
|
||||
if (Array.isArray(config.imports.imports)) {
|
||||
config.imports.imports.push(...imports)
|
||||
} else {
|
||||
config.imports.imports = [config.imports.imports, ...imports]
|
||||
}
|
||||
config.imports.imports = config.imports.imports || []
|
||||
config.imports.imports.push(...imports)
|
||||
})
|
||||
}
|
||||
|
||||
@ -103,7 +99,7 @@ export function addServerImports (imports: Import[]) {
|
||||
*/
|
||||
export function addServerImportsDir (dirs: string | string[], opts: { prepend?: boolean } = {}) {
|
||||
const nuxt = useNuxt()
|
||||
const _dirs = Array.isArray(dirs) ? dirs : [dirs]
|
||||
const _dirs = toArray(dirs)
|
||||
nuxt.hook('nitro:config', (config) => {
|
||||
config.imports = config.imports || {}
|
||||
config.imports.dirs = config.imports.dirs || []
|
||||
@ -120,7 +116,7 @@ export function addServerScanDir (dirs: string | string[], opts: { prepend?: boo
|
||||
nuxt.hook('nitro:config', (config) => {
|
||||
config.scanDirs = config.scanDirs || []
|
||||
|
||||
for (const dir of (Array.isArray(dirs) ? dirs : [dirs])) {
|
||||
for (const dir of toArray(dirs)) {
|
||||
config.scanDirs[opts.prepend ? 'unshift' : 'push'](dir)
|
||||
}
|
||||
})
|
||||
|
@ -4,6 +4,7 @@ import { defu } from 'defu'
|
||||
import { useNuxt } from './context'
|
||||
import { isNuxt2 } from './compatibility'
|
||||
import { logger } from './logger'
|
||||
import { toArray } from './utils'
|
||||
|
||||
export function extendPages (cb: NuxtHooks['pages:extend']) {
|
||||
const nuxt = useNuxt()
|
||||
@ -45,7 +46,7 @@ export interface AddRouteMiddlewareOptions {
|
||||
|
||||
export function addRouteMiddleware (input: NuxtMiddleware | NuxtMiddleware[], options: AddRouteMiddlewareOptions = {}) {
|
||||
const nuxt = useNuxt()
|
||||
const middlewares = Array.isArray(input) ? input : [input]
|
||||
const middlewares = toArray(input)
|
||||
nuxt.hook('app:resolve', (app) => {
|
||||
for (const middleware of middlewares) {
|
||||
const find = app.middleware.findIndex(item => item.name === middleware.name)
|
||||
|
@ -6,6 +6,7 @@ import { resolvePath as _resolvePath } from 'mlly'
|
||||
import { resolveAlias as _resolveAlias } from 'pathe/utils'
|
||||
import { tryUseNuxt } from './context'
|
||||
import { isIgnored } from './ignore'
|
||||
import { toArray } from './utils'
|
||||
|
||||
export interface ResolvePathOptions {
|
||||
/** Base for resolving paths from. Default is Nuxt rootDir. */
|
||||
@ -84,10 +85,7 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}):
|
||||
* Try to resolve first existing file in paths
|
||||
*/
|
||||
export async function findPath (paths: string | string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise<string | null> {
|
||||
if (!Array.isArray(paths)) {
|
||||
paths = [paths]
|
||||
}
|
||||
for (const path of paths) {
|
||||
for (const path of toArray(paths)) {
|
||||
const rPath = await resolvePath(path, opts)
|
||||
if (await existsSensitive(rPath)) {
|
||||
const _isDir = await isDirectory(rPath)
|
||||
|
3
packages/kit/src/utils.ts
Normal file
3
packages/kit/src/utils.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function toArray<T> (value: T | T[]): T[] {
|
||||
return Array.isArray(value) ? value : [value]
|
||||
}
|
@ -2,6 +2,7 @@ import { getCurrentInstance, onBeforeMount, onServerPrefetch, onUnmounted, ref,
|
||||
import type { Ref, WatchSource } from 'vue'
|
||||
import type { NuxtApp } from '../nuxt'
|
||||
import { useNuxtApp } from '../nuxt'
|
||||
import { toArray } from '../utils'
|
||||
import type { NuxtError} from './error';
|
||||
import { createError } from './error'
|
||||
import { onNuxtReady } from './ready'
|
||||
@ -378,7 +379,7 @@ export async function refreshNuxtData (keys?: string | string[]): Promise<void>
|
||||
|
||||
await new Promise<void>(resolve => onNuxtReady(resolve))
|
||||
|
||||
const _keys = keys ? Array.isArray(keys) ? keys : [keys] : undefined
|
||||
const _keys = keys ? toArray(keys) : undefined
|
||||
await useNuxtApp().hooks.callHookParallel('app:data:refresh', _keys)
|
||||
}
|
||||
|
||||
@ -389,7 +390,7 @@ export function clearNuxtData (keys?: string | string[] | ((key: string) => bool
|
||||
? _allKeys
|
||||
: typeof keys === 'function'
|
||||
? _allKeys.filter(keys)
|
||||
: Array.isArray(keys) ? keys : [keys]
|
||||
: toArray(keys)
|
||||
|
||||
for (const key of _keys) {
|
||||
if (key in nuxtApp.payload.data) {
|
||||
|
@ -227,8 +227,7 @@ function generateOptionSegments <_ResT, DataT, DefaultT>(opts: UseFetchOptions<_
|
||||
if (!obj) { continue }
|
||||
|
||||
const unwrapped: Record<string, string> = {}
|
||||
const iterator = Array.isArray(obj) ? obj : Object.entries(obj)
|
||||
for (const [key, value] of iterator) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
unwrapped[toValue(key)] = toValue(value)
|
||||
}
|
||||
segments.push(unwrapped)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Component } from 'vue'
|
||||
import type { RouteLocationRaw, Router } from '#vue-router'
|
||||
import { useNuxtApp } from '../nuxt'
|
||||
import { toArray } from '../utils'
|
||||
import { useRouter } from './router'
|
||||
|
||||
/**
|
||||
@ -11,7 +12,7 @@ export const preloadComponents = async (components: string | string[]) => {
|
||||
if (import.meta.server) { return }
|
||||
const nuxtApp = useNuxtApp()
|
||||
|
||||
components = Array.isArray(components) ? components : [components]
|
||||
components = toArray(components)
|
||||
await Promise.all(components.map(name => _loadAsyncComponent(nuxtApp.vueApp._context.components[name])))
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ import type { H3Event } from 'h3'
|
||||
import { setResponseStatus as _setResponseStatus, appendHeader, getRequestHeader, getRequestHeaders } from 'h3'
|
||||
import type { NuxtApp } from '../nuxt'
|
||||
import { useNuxtApp } from '../nuxt'
|
||||
import { toArray } from '../utils'
|
||||
|
||||
export function useRequestEvent (nuxtApp: NuxtApp = useNuxtApp()): H3Event {
|
||||
return nuxtApp.ssrContext?.event as H3Event
|
||||
@ -44,6 +45,6 @@ export function setResponseStatus (arg1: H3Event | number | undefined, arg2?: nu
|
||||
export function prerenderRoutes (path: string | string[]) {
|
||||
if (!import.meta.server || !import.meta.prerender) { return }
|
||||
|
||||
const paths = Array.isArray(path) ? path : [path]
|
||||
const paths = toArray(path)
|
||||
appendHeader(useRequestEvent(), 'x-nitro-prerender', paths.map(p => encodeURIComponent(p)).join(', '))
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { isRef, toRef } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
import { useNuxtApp } from '../nuxt'
|
||||
import { toArray } from '../utils'
|
||||
|
||||
const useStateKeyPrefix = '$s'
|
||||
/**
|
||||
@ -47,7 +48,7 @@ export function clearNuxtState (
|
||||
? _allKeys
|
||||
: typeof keys === 'function'
|
||||
? _allKeys.filter(keys)
|
||||
: Array.isArray(keys) ? keys : [keys]
|
||||
: toArray(keys)
|
||||
|
||||
for (const _key of _keys) {
|
||||
const key = useStateKeyPrefix + _key
|
||||
|
3
packages/nuxt/src/app/utils.ts
Normal file
3
packages/nuxt/src/app/utils.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function toArray<T> (value: T | T[]): T[] {
|
||||
return Array.isArray(value) ? value : [value]
|
||||
}
|
@ -16,6 +16,7 @@ import type { Nuxt, RuntimeConfig } from 'nuxt/schema'
|
||||
import { template as defaultSpaLoadingTemplate } from '@nuxt/ui-templates/templates/spa-loading-icon.mjs'
|
||||
import { version as nuxtVersion } from '../../package.json'
|
||||
import { distDir } from '../dirs'
|
||||
import { toArray } from '../utils'
|
||||
import { ImportProtectionPlugin } from './plugins/import-protection'
|
||||
|
||||
export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
|
||||
@ -333,7 +334,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
|
||||
|
||||
// Register nuxt protection patterns
|
||||
nitroConfig.rollupConfig!.plugins = await nitroConfig.rollupConfig!.plugins || []
|
||||
nitroConfig.rollupConfig!.plugins = Array.isArray(nitroConfig.rollupConfig!.plugins) ? nitroConfig.rollupConfig!.plugins : [nitroConfig.rollupConfig!.plugins]
|
||||
nitroConfig.rollupConfig!.plugins = toArray(nitroConfig.rollupConfig!.plugins)
|
||||
nitroConfig.rollupConfig!.plugins!.push(
|
||||
ImportProtectionPlugin.rollup({
|
||||
rootDir: nuxt.options.rootDir,
|
||||
|
@ -4,6 +4,7 @@ import { RouterView } from '#vue-router'
|
||||
import { defu } from 'defu'
|
||||
import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from '#vue-router'
|
||||
|
||||
import { toArray } from './utils'
|
||||
import type { RouterViewSlotProps } from './utils'
|
||||
import { generateRouteKey, wrapInKeepAlive } from './utils'
|
||||
import { RouteProvider } from '#app/components/route-provider'
|
||||
@ -127,14 +128,10 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
function _toArray (val: any) {
|
||||
return Array.isArray(val) ? val : (val ? [val] : [])
|
||||
}
|
||||
|
||||
function _mergeTransitionProps (routeProps: TransitionProps[]): TransitionProps {
|
||||
const _props: TransitionProps[] = routeProps.map(prop => ({
|
||||
...prop,
|
||||
onAfterLeave: _toArray(prop.onAfterLeave)
|
||||
onAfterLeave: prop.onAfterLeave ? toArray(prop.onAfterLeave) : undefined
|
||||
}))
|
||||
return defu(..._props as [TransitionProps, TransitionProps])
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { hasProtocol } from 'ufo'
|
||||
import { toArray } from '../utils'
|
||||
import { defineNuxtPlugin } from '#app/nuxt'
|
||||
import { useRouter } from '#app/composables/router'
|
||||
// @ts-expect-error virtual file
|
||||
@ -25,8 +26,8 @@ export default defineNuxtPlugin({
|
||||
if (hasProtocol(url)) { return }
|
||||
const route = router.resolve(url)
|
||||
if (!route) { return }
|
||||
const layout = route?.meta?.layout
|
||||
let middleware = Array.isArray(route?.meta?.middleware) ? route?.meta?.middleware : [route?.meta?.middleware]
|
||||
const layout = route.meta.layout
|
||||
let middleware = toArray(route.meta.middleware)
|
||||
middleware = middleware.filter(m => typeof m === 'string')
|
||||
|
||||
for (const name of middleware) {
|
||||
|
@ -13,6 +13,7 @@ import { isEqual, withoutBase } from 'ufo'
|
||||
|
||||
import type { PageMeta } from '../composables'
|
||||
|
||||
import { toArray } from '../utils'
|
||||
import type { Plugin, RouteMiddleware } from '#app'
|
||||
import { defineNuxtPlugin, useRuntimeConfig } from '#app/nuxt'
|
||||
import { clearError, showError, useError } from '#app/composables/error'
|
||||
@ -155,12 +156,8 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
||||
for (const component of to.matched) {
|
||||
const componentMiddleware = component.meta.middleware as MiddlewareDef | MiddlewareDef[]
|
||||
if (!componentMiddleware) { continue }
|
||||
if (Array.isArray(componentMiddleware)) {
|
||||
for (const entry of componentMiddleware) {
|
||||
middlewareEntries.add(entry)
|
||||
}
|
||||
} else {
|
||||
middlewareEntries.add(componentMiddleware)
|
||||
for (const entry of toArray(componentMiddleware)) {
|
||||
middlewareEntries.add(entry)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,3 +21,7 @@ export const generateRouteKey = (routeProps: RouterViewSlotProps, override?: str
|
||||
export const wrapInKeepAlive = (props: any, children: any) => {
|
||||
return { default: () => import.meta.client && props ? h(KeepAlive, props === true ? {} : props, children) : children }
|
||||
}
|
||||
|
||||
export function toArray<T> (value: T | T[]): T[] {
|
||||
return Array.isArray(value) ? value : [value]
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import type { CallExpression, ExpressionStatement, ObjectExpression, Program, Pr
|
||||
import type { NuxtPage } from 'nuxt/schema'
|
||||
|
||||
import { uniqueBy } from '../core/utils'
|
||||
import { toArray } from '../utils'
|
||||
|
||||
enum SegmentParserState {
|
||||
initial,
|
||||
@ -325,7 +326,7 @@ export function normalizeRoutes (routes: NuxtPage[], metaImports: Set<string> =
|
||||
metaImports.add(genImport(`${file}?macro=true`, [{ name: 'default', as: metaImportName }]))
|
||||
|
||||
let aliasCode = `${metaImportName}?.alias || []`
|
||||
const alias = Array.isArray(page.alias) ? page.alias : [page.alias].filter(Boolean)
|
||||
const alias = toArray(page.alias).filter(Boolean)
|
||||
if (alias.length) {
|
||||
aliasCode = `${JSON.stringify(alias)}.concat(${aliasCode})`
|
||||
}
|
||||
|
3
packages/nuxt/src/utils.ts
Normal file
3
packages/nuxt/src/utils.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function toArray<T> (value: T | T[]): T[] {
|
||||
return Array.isArray(value) ? value : [value]
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import type { ExternalsOptions } from 'externality'
|
||||
import { ExternalsDefaults, isExternal } from 'externality'
|
||||
import type { ViteDevServer } from 'vite'
|
||||
import { toArray } from '.'
|
||||
|
||||
export function createIsExternal (viteServer: ViteDevServer, rootDir: string, modulesDirs?: string[]) {
|
||||
const externalOpts: ExternalsOptions = {
|
||||
@ -8,7 +9,11 @@ export function createIsExternal (viteServer: ViteDevServer, rootDir: string, mo
|
||||
/virtual:/,
|
||||
/\.ts$/,
|
||||
...ExternalsDefaults.inline || [],
|
||||
...Array.isArray(viteServer.config.ssr.noExternal) ? viteServer.config.ssr.noExternal : []
|
||||
...(
|
||||
viteServer.config.ssr.noExternal && viteServer.config.ssr.noExternal !== true
|
||||
? toArray(viteServer.config.ssr.noExternal)
|
||||
: []
|
||||
)
|
||||
],
|
||||
external: [
|
||||
...viteServer.config.ssr.external || [],
|
||||
|
@ -24,3 +24,7 @@ export function matchWithStringOrRegex (value: string, matcher: string | RegExp)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
export function toArray<T> (value: T | T[]): T[] {
|
||||
return Array.isArray(value) ? value : [value]
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import type { Configuration } from 'webpack'
|
||||
import type { Nuxt, NuxtOptions } from '@nuxt/schema'
|
||||
import { logger } from '@nuxt/kit'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { toArray } from './index'
|
||||
|
||||
export interface WebpackConfigContext {
|
||||
nuxt: Nuxt
|
||||
@ -37,10 +38,7 @@ export function createWebpackConfigContext (nuxt: Nuxt): WebpackConfigContext {
|
||||
}
|
||||
|
||||
export function applyPresets (ctx: WebpackConfigContext, presets: WebpackConfigPresetItem | WebpackConfigPresetItem[]) {
|
||||
if (!Array.isArray(presets)) {
|
||||
presets = [presets]
|
||||
}
|
||||
for (const preset of presets) {
|
||||
for (const preset of toArray(presets)) {
|
||||
if (Array.isArray(preset)) {
|
||||
preset[0](ctx, preset[1])
|
||||
} else {
|
||||
|
3
packages/webpack/src/utils/index.ts
Normal file
3
packages/webpack/src/utils/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function toArray<T> (value: T | T[]): T[] {
|
||||
return Array.isArray(value) ? value : [value]
|
||||
}
|
Loading…
Reference in New Issue
Block a user