mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-24 14:45:15 +00:00
feat(nuxt): normalise component names to match nuxt pattern (#28745)
This commit is contained in:
parent
ed7f946ab8
commit
9cb34dd49b
@ -73,6 +73,7 @@ export default defineNuxtConfig({
|
|||||||
// resetAsyncDataToUndefined: true,
|
// resetAsyncDataToUndefined: true,
|
||||||
// templateUtils: true,
|
// templateUtils: true,
|
||||||
// relativeWatchPaths: true,
|
// relativeWatchPaths: true,
|
||||||
|
// normalizeComponentNames: false
|
||||||
// defaults: {
|
// defaults: {
|
||||||
// useAsyncData: {
|
// useAsyncData: {
|
||||||
// deep: true
|
// deep: true
|
||||||
@ -198,6 +199,43 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Normalized Component Names
|
||||||
|
|
||||||
|
🚦 **Impact Level**: Moderate
|
||||||
|
|
||||||
|
Vue will now generate component names that match the Nuxt pattern for component naming.
|
||||||
|
|
||||||
|
##### What Changed
|
||||||
|
|
||||||
|
By default, if you haven't set it manually, Vue will assign a component name that matches
|
||||||
|
the filename of the component.
|
||||||
|
|
||||||
|
```bash [Directory structure]
|
||||||
|
├─ components/
|
||||||
|
├─── SomeFolder/
|
||||||
|
├───── MyComponent.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case, the component name would be `MyComponent`, as far as Vue is concerned. If you wanted to use `<KeepAlive>` with it, or identify it in the Vue DevTools, you would need to use this name.
|
||||||
|
|
||||||
|
But in order to auto-import it, you would need to use `SomeFolderMyComponent`.
|
||||||
|
|
||||||
|
With this change, these two values will match, and Vue will generate a component name that matches the Nuxt pattern for component naming.
|
||||||
|
|
||||||
|
##### Migration Steps
|
||||||
|
|
||||||
|
Ensure that you use the updated name in any tests which use `findComponent` from `@vue/test-utils` and in any `<KeepAlive>` which depends on the name of your component.
|
||||||
|
|
||||||
|
Alternatively, for now, you can disable this behaviour with:
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
normalizeComponentNames: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
#### Shared Prerender Data
|
#### Shared Prerender Data
|
||||||
|
|
||||||
🚦 **Impact Level**: Medium
|
🚦 **Impact Level**: Medium
|
||||||
|
@ -390,3 +390,31 @@ In addition, any changes to files within `srcDir` will trigger a rebuild of the
|
|||||||
::note
|
::note
|
||||||
A maximum of 10 cache tarballs are kept.
|
A maximum of 10 cache tarballs are kept.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
## normalizeComponentNames
|
||||||
|
|
||||||
|
Ensure that auto-generated Vue component names match the full component name
|
||||||
|
you would use to auto-import the component.
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
experimental: {
|
||||||
|
normalizeComponentNames: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, if you haven't set it manually, Vue will assign a component name that matches
|
||||||
|
the filename of the component.
|
||||||
|
|
||||||
|
```bash [Directory structure]
|
||||||
|
├─ components/
|
||||||
|
├─── SomeFolder/
|
||||||
|
├───── MyComponent.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case, the component name would be `MyComponent`, as far as Vue is concerned. If you wanted to use `<KeepAlive>` with it, or identify it in the Vue DevTools, you would need to use this component.
|
||||||
|
|
||||||
|
But in order to auto-import it, you would need to use `SomeFolderMyComponent`.
|
||||||
|
|
||||||
|
By setting `experimental.normalizeComponentNames`, these two values match, and Vue will generate a component name that matches the Nuxt pattern for component naming.
|
||||||
|
@ -61,9 +61,12 @@ export default defineNuxtConfig({
|
|||||||
app: 'app'
|
app: 'app'
|
||||||
},
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
|
sharedPrerenderData: false,
|
||||||
compileTemplate: true,
|
compileTemplate: true,
|
||||||
|
resetAsyncDataToUndefined: true,
|
||||||
templateUtils: true,
|
templateUtils: true,
|
||||||
relativeWatchPaths: true,
|
relativeWatchPaths: true,
|
||||||
|
normalizeComponentNames: false
|
||||||
defaults: {
|
defaults: {
|
||||||
useAsyncData: {
|
useAsyncData: {
|
||||||
deep: true
|
deep: true
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import { existsSync, statSync, writeFileSync } from 'node:fs'
|
import { existsSync, statSync, writeFileSync } from 'node:fs'
|
||||||
import { isAbsolute, join, normalize, relative, resolve } from 'pathe'
|
import { isAbsolute, join, normalize, relative, resolve } from 'pathe'
|
||||||
import { addPluginTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, logger, resolveAlias, resolvePath, updateTemplates } from '@nuxt/kit'
|
import { addBuildPlugin, addPluginTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, logger, resolveAlias, resolvePath, updateTemplates } from '@nuxt/kit'
|
||||||
import type { Component, ComponentsDir, ComponentsOptions } from 'nuxt/schema'
|
import type { Component, ComponentsDir, ComponentsOptions } from 'nuxt/schema'
|
||||||
|
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../dirs'
|
||||||
import { clientFallbackAutoIdPlugin } from './client-fallback-auto-id'
|
|
||||||
import { componentNamesTemplate, componentsIslandsTemplate, componentsMetadataTemplate, componentsPluginTemplate, componentsTypeTemplate } from './templates'
|
import { componentNamesTemplate, componentsIslandsTemplate, componentsMetadataTemplate, componentsPluginTemplate, componentsTypeTemplate } from './templates'
|
||||||
import { scanComponents } from './scan'
|
import { scanComponents } from './scan'
|
||||||
import { loaderPlugin } from './loader'
|
|
||||||
import { TreeShakeTemplatePlugin } from './tree-shake'
|
import { ClientFallbackAutoIdPlugin } from './plugins/client-fallback-auto-id'
|
||||||
import { componentsChunkPlugin, islandsTransform } from './islandsTransform'
|
import { LoaderPlugin } from './plugins/loader'
|
||||||
import { createTransformPlugin } from './transform'
|
import { componentsChunkPlugin, islandsTransform } from './plugins/islands-transform'
|
||||||
|
import { createTransformPlugin } from './plugins/transform'
|
||||||
|
import { TreeShakeTemplatePlugin } from './plugins/tree-shake'
|
||||||
|
import { ComponentNamePlugin } from './plugins/component-names'
|
||||||
|
|
||||||
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 { return false } }
|
const isDirectory = (p: string) => { try { return statSync(p).isDirectory() } catch { return false } }
|
||||||
@ -42,6 +44,11 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
: context.components
|
: context.components
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nuxt.options.experimental.normalizeComponentNames) {
|
||||||
|
addBuildPlugin(ComponentNamePlugin({ sourcemap: !!nuxt.options.sourcemap.client, getComponents }), { server: false })
|
||||||
|
addBuildPlugin(ComponentNamePlugin({ sourcemap: !!nuxt.options.sourcemap.server, getComponents }), { client: false })
|
||||||
|
}
|
||||||
|
|
||||||
const normalizeDirs = (dir: any, cwd: string, options?: { priority?: number }): ComponentsDir[] => {
|
const normalizeDirs = (dir: any, cwd: string, options?: { priority?: number }): ComponentsDir[] => {
|
||||||
if (Array.isArray(dir)) {
|
if (Array.isArray(dir)) {
|
||||||
return dir.map(dir => normalizeDirs(dir, cwd, options)).flat().sort(compareDirByPathLength)
|
return dir.map(dir => normalizeDirs(dir, cwd, options)).flat().sort(compareDirByPathLength)
|
||||||
@ -127,14 +134,14 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
addTemplate(componentsMetadataTemplate)
|
addTemplate(componentsMetadataTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
const unpluginServer = createTransformPlugin(nuxt, getComponents, 'server')
|
const TransformPluginServer = createTransformPlugin(nuxt, getComponents, 'server')
|
||||||
const unpluginClient = createTransformPlugin(nuxt, getComponents, 'client')
|
const TransformPluginClient = createTransformPlugin(nuxt, getComponents, 'client')
|
||||||
|
|
||||||
addVitePlugin(() => unpluginServer.vite(), { server: true, client: false })
|
addVitePlugin(() => TransformPluginServer.vite(), { server: true, client: false })
|
||||||
addVitePlugin(() => unpluginClient.vite(), { server: false, client: true })
|
addVitePlugin(() => TransformPluginClient.vite(), { server: false, client: true })
|
||||||
|
|
||||||
addWebpackPlugin(() => unpluginServer.webpack(), { server: true, client: false })
|
addWebpackPlugin(() => TransformPluginServer.webpack(), { server: true, client: false })
|
||||||
addWebpackPlugin(() => unpluginClient.webpack(), { server: false, client: true })
|
addWebpackPlugin(() => TransformPluginClient.webpack(), { server: false, client: true })
|
||||||
|
|
||||||
// Do not prefetch global components chunks
|
// Do not prefetch global components chunks
|
||||||
nuxt.hook('build:manifest', (manifest) => {
|
nuxt.hook('build:manifest', (manifest) => {
|
||||||
@ -223,12 +230,12 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
if (nuxt.options.experimental.clientFallback) {
|
if (nuxt.options.experimental.clientFallback) {
|
||||||
config.plugins.push(clientFallbackAutoIdPlugin.vite({
|
config.plugins.push(ClientFallbackAutoIdPlugin.vite({
|
||||||
sourcemap: !!nuxt.options.sourcemap[mode],
|
sourcemap: !!nuxt.options.sourcemap[mode],
|
||||||
rootDir: nuxt.options.rootDir,
|
rootDir: nuxt.options.rootDir,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
config.plugins.push(loaderPlugin.vite({
|
config.plugins.push(LoaderPlugin.vite({
|
||||||
sourcemap: !!nuxt.options.sourcemap[mode],
|
sourcemap: !!nuxt.options.sourcemap[mode],
|
||||||
getComponents,
|
getComponents,
|
||||||
mode,
|
mode,
|
||||||
@ -292,12 +299,12 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
if (nuxt.options.experimental.clientFallback) {
|
if (nuxt.options.experimental.clientFallback) {
|
||||||
config.plugins.push(clientFallbackAutoIdPlugin.webpack({
|
config.plugins.push(ClientFallbackAutoIdPlugin.webpack({
|
||||||
sourcemap: !!nuxt.options.sourcemap[mode],
|
sourcemap: !!nuxt.options.sourcemap[mode],
|
||||||
rootDir: nuxt.options.rootDir,
|
rootDir: nuxt.options.rootDir,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
config.plugins.push(loaderPlugin.webpack({
|
config.plugins.push(LoaderPlugin.webpack({
|
||||||
sourcemap: !!nuxt.options.sourcemap[mode],
|
sourcemap: !!nuxt.options.sourcemap[mode],
|
||||||
getComponents,
|
getComponents,
|
||||||
mode,
|
mode,
|
||||||
|
@ -3,7 +3,7 @@ import type { ComponentsOptions } from '@nuxt/schema'
|
|||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import { isAbsolute, relative } from 'pathe'
|
import { isAbsolute, relative } from 'pathe'
|
||||||
import { hash } from 'ohash'
|
import { hash } from 'ohash'
|
||||||
import { isVue } from '../core/utils'
|
import { isVue } from '../../core/utils'
|
||||||
|
|
||||||
interface LoaderOptions {
|
interface LoaderOptions {
|
||||||
sourcemap?: boolean
|
sourcemap?: boolean
|
||||||
@ -12,7 +12,7 @@ interface LoaderOptions {
|
|||||||
}
|
}
|
||||||
const CLIENT_FALLBACK_RE = /<(?:NuxtClientFallback|nuxt-client-fallback)(?: [^>]*)?>/
|
const CLIENT_FALLBACK_RE = /<(?:NuxtClientFallback|nuxt-client-fallback)(?: [^>]*)?>/
|
||||||
const CLIENT_FALLBACK_GLOBAL_RE = /<(NuxtClientFallback|nuxt-client-fallback)( [^>]*)?>/g
|
const CLIENT_FALLBACK_GLOBAL_RE = /<(NuxtClientFallback|nuxt-client-fallback)( [^>]*)?>/g
|
||||||
export const clientFallbackAutoIdPlugin = createUnplugin((options: LoaderOptions) => {
|
export const ClientFallbackAutoIdPlugin = createUnplugin((options: LoaderOptions) => {
|
||||||
const exclude = options.transform?.exclude || []
|
const exclude = options.transform?.exclude || []
|
||||||
const include = options.transform?.include || []
|
const include = options.transform?.include || []
|
||||||
|
|
46
packages/nuxt/src/components/plugins/component-names.ts
Normal file
46
packages/nuxt/src/components/plugins/component-names.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { createUnplugin } from 'unplugin'
|
||||||
|
import MagicString from 'magic-string'
|
||||||
|
import type { Component } from 'nuxt/schema'
|
||||||
|
import { isVue } from '../../core/utils'
|
||||||
|
|
||||||
|
interface NameDevPluginOptions {
|
||||||
|
sourcemap: boolean
|
||||||
|
getComponents: () => Component[]
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set the default name of components to their PascalCase name
|
||||||
|
*/
|
||||||
|
export const ComponentNamePlugin = (options: NameDevPluginOptions) => createUnplugin(() => {
|
||||||
|
return {
|
||||||
|
name: 'nuxt:component-name-plugin',
|
||||||
|
enforce: 'post',
|
||||||
|
transformInclude (id) {
|
||||||
|
return isVue(id) || !!id.match(/\.[tj]sx$/)
|
||||||
|
},
|
||||||
|
transform (code, id) {
|
||||||
|
const filename = id.match(/([^/\\]+)\.\w+$/)?.[1]
|
||||||
|
if (!filename) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const component = options.getComponents().find(c => c.filePath === id)
|
||||||
|
|
||||||
|
if (!component) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const NAME_RE = new RegExp(`__name:\\s*['"]${filename}['"]`)
|
||||||
|
const s = new MagicString(code)
|
||||||
|
s.replace(NAME_RE, `__name: ${JSON.stringify(component.pascalName)}`)
|
||||||
|
|
||||||
|
if (s.hasChanged()) {
|
||||||
|
return {
|
||||||
|
code: s.toString(),
|
||||||
|
map: options.sourcemap
|
||||||
|
? s.generateMap({ hires: true })
|
||||||
|
: undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
@ -9,7 +9,7 @@ import { ELEMENT_NODE, parse, walk } from 'ultrahtml'
|
|||||||
import { hash } from 'ohash'
|
import { hash } from 'ohash'
|
||||||
import { resolvePath } from '@nuxt/kit'
|
import { resolvePath } from '@nuxt/kit'
|
||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
import { isVue } from '../core/utils'
|
import { isVue } from '../../core/utils'
|
||||||
|
|
||||||
interface ServerOnlyComponentTransformPluginOptions {
|
interface ServerOnlyComponentTransformPluginOptions {
|
||||||
getComponents: () => Component[]
|
getComponents: () => Component[]
|
@ -6,8 +6,8 @@ import { resolve } from 'pathe'
|
|||||||
import type { Component, ComponentsOptions } from 'nuxt/schema'
|
import type { Component, ComponentsOptions } from 'nuxt/schema'
|
||||||
|
|
||||||
import { logger, tryUseNuxt } from '@nuxt/kit'
|
import { logger, tryUseNuxt } from '@nuxt/kit'
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../../dirs'
|
||||||
import { isVue } from '../core/utils'
|
import { isVue } from '../../core/utils'
|
||||||
|
|
||||||
interface LoaderOptions {
|
interface LoaderOptions {
|
||||||
getComponents (): Component[]
|
getComponents (): Component[]
|
||||||
@ -17,7 +17,7 @@ interface LoaderOptions {
|
|||||||
experimentalComponentIslands?: boolean
|
experimentalComponentIslands?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
|
export const LoaderPlugin = createUnplugin((options: LoaderOptions) => {
|
||||||
const exclude = options.transform?.exclude || []
|
const exclude = options.transform?.exclude || []
|
||||||
const include = options.transform?.include || []
|
const include = options.transform?.include || []
|
||||||
const serverComponentRuntime = resolve(distDir, 'components/runtime/server-component')
|
const serverComponentRuntime = resolve(distDir, 'components/runtime/server-component')
|
||||||
@ -49,7 +49,7 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
|
|||||||
// @ts-expect-error TODO: refactor to nuxi
|
// @ts-expect-error TODO: refactor to nuxi
|
||||||
if (component._internal_install && tryUseNuxt()?.options.test === false) {
|
if (component._internal_install && tryUseNuxt()?.options.test === false) {
|
||||||
// @ts-expect-error TODO: refactor to nuxi
|
// @ts-expect-error TODO: refactor to nuxi
|
||||||
import('../core/features').then(({ installNuxtModule }) => installNuxtModule(component._internal_install))
|
import('../../core/features').then(({ installNuxtModule }) => installNuxtModule(component._internal_install))
|
||||||
}
|
}
|
||||||
let identifier = map.get(component) || `__nuxt_component_${num++}`
|
let identifier = map.get(component) || `__nuxt_component_${num++}`
|
||||||
map.set(component, identifier)
|
map.set(component, identifier)
|
@ -7,8 +7,8 @@ import { parseURL } from 'ufo'
|
|||||||
import { parseQuery } from 'vue-router'
|
import { parseQuery } from 'vue-router'
|
||||||
import { normalize, resolve } from 'pathe'
|
import { normalize, resolve } from 'pathe'
|
||||||
import { genImport } from 'knitwork'
|
import { genImport } from 'knitwork'
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../../dirs'
|
||||||
import type { getComponentsT } from './module'
|
import type { getComponentsT } from '../module'
|
||||||
|
|
||||||
const COMPONENT_QUERY_RE = /[?&]nuxt_component=/
|
const COMPONENT_QUERY_RE = /[?&]nuxt_component=/
|
||||||
|
|
@ -6,7 +6,7 @@ import type { AssignmentProperty, CallExpression, Identifier, Literal, MemberExp
|
|||||||
import { createUnplugin } from 'unplugin'
|
import { createUnplugin } from 'unplugin'
|
||||||
import type { Component } from '@nuxt/schema'
|
import type { Component } from '@nuxt/schema'
|
||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../../dirs'
|
||||||
|
|
||||||
interface TreeShakeTemplatePluginOptions {
|
interface TreeShakeTemplatePluginOptions {
|
||||||
sourcemap?: boolean
|
sourcemap?: boolean
|
@ -4,7 +4,7 @@ import type { Component, Nuxt } from '@nuxt/schema'
|
|||||||
import { kebabCase } from 'scule'
|
import { kebabCase } from 'scule'
|
||||||
import { normalize } from 'pathe'
|
import { normalize } from 'pathe'
|
||||||
|
|
||||||
import { createTransformPlugin } from '../src/components/transform'
|
import { createTransformPlugin } from '../src/components/plugins/transform'
|
||||||
|
|
||||||
describe('components:transform', () => {
|
describe('components:transform', () => {
|
||||||
it('should transform #components imports', async () => {
|
it('should transform #components imports', async () => {
|
||||||
|
@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest'
|
|||||||
import type { Plugin } from 'vite'
|
import type { Plugin } from 'vite'
|
||||||
import type { Component } from '@nuxt/schema'
|
import type { Component } from '@nuxt/schema'
|
||||||
import type { UnpluginOptions } from 'unplugin'
|
import type { UnpluginOptions } from 'unplugin'
|
||||||
import { islandsTransform } from '../src/components/islandsTransform'
|
import { islandsTransform } from '../src/components/plugins/islands-transform'
|
||||||
import { normalizeLineEndings } from './utils'
|
import { normalizeLineEndings } from './utils'
|
||||||
|
|
||||||
const getComponents = () => [{
|
const getComponents = () => [{
|
||||||
|
@ -6,7 +6,7 @@ import type { Plugin } from 'vite'
|
|||||||
import { Parser } from 'acorn'
|
import { Parser } from 'acorn'
|
||||||
import type { Options } from '@vitejs/plugin-vue'
|
import type { Options } from '@vitejs/plugin-vue'
|
||||||
import _vuePlugin from '@vitejs/plugin-vue'
|
import _vuePlugin from '@vitejs/plugin-vue'
|
||||||
import { TreeShakeTemplatePlugin } from '../src/components/tree-shake'
|
import { TreeShakeTemplatePlugin } from '../src/components/plugins/tree-shake'
|
||||||
import { fixtureDir, normalizeLineEndings } from './utils'
|
import { fixtureDir, normalizeLineEndings } from './utils'
|
||||||
|
|
||||||
// mock due to differences of results between windows and linux
|
// mock due to differences of results between windows and linux
|
||||||
|
@ -389,5 +389,15 @@ export default defineUntypedSchema({
|
|||||||
* This only works for source files within `srcDir` and `serverDir` for the Vue/Nitro parts of your app.
|
* This only works for source files within `srcDir` and `serverDir` for the Vue/Nitro parts of your app.
|
||||||
*/
|
*/
|
||||||
buildCache: false,
|
buildCache: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that auto-generated Vue component names match the full component name
|
||||||
|
* you would use to auto-import the component.
|
||||||
|
*/
|
||||||
|
normalizeComponentNames: {
|
||||||
|
$resolve: async (val, get) => {
|
||||||
|
return val ?? ((await get('future') as Record<string, unknown>).compatibilityVersion === 4)
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user