feat(vite,webpack): tree-shakable import.meta.* build flags (#22428)

This commit is contained in:
Lucas Vargas 2023-08-07 19:03:40 -03:00 committed by GitHub
parent 305d6de030
commit ffd0223583
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 226 additions and 202 deletions

View File

@ -74,12 +74,12 @@ export const useLocale = () => useState<string>('locale', () => useDefaultLocale
export const useDefaultLocale = (fallback = 'en-US') => { export const useDefaultLocale = (fallback = 'en-US') => {
const locale = ref(fallback) const locale = ref(fallback)
if (process.server) { if (import.meta.server) {
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0] const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
if (reqLocale) { if (reqLocale) {
locale.value = reqLocale locale.value = reqLocale
} }
} else if (process.client) { } else if (import.meta.client) {
const navLang = navigator.language const navLang = navigator.language
if (navLang) { if (navLang) {
locale.value = navLang locale.value = navLang

View File

@ -125,12 +125,12 @@ However, if you want to avoid this behaviour you can do so:
```js ```js
export default defineNuxtRouteMiddleware(to => { export default defineNuxtRouteMiddleware(to => {
// skip middleware on server // skip middleware on server
if (process.server) return if (import.meta.server) return
// skip middleware on client side entirely // skip middleware on client side entirely
if (process.client) return if (import.meta.client) return
// or only skip middleware on initial client load // or only skip middleware on initial client load
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (process.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return if (import.meta.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
}) })
``` ```

View File

@ -62,7 +62,7 @@ export default defineNuxtPlugin({
``` ```
::alert ::alert
If you are using an object-syntax plugin, the properties may be statically analyzed in future to produce a more optimized build. So you should not define them at runtime. For example, setting `enforce: process.server ? 'pre' : 'post'` would defeat any future optimization Nuxt is able to do for your plugins. If you are using an object-syntax plugin, the properties may be statically analyzed in future to produce a more optimized build. So you should not define them at runtime. For example, setting `enforce: import.meta.server ? 'pre' : 'post'` would defeat any future optimization Nuxt is able to do for your plugins.
:: ::
## Plugin Registration Order ## Plugin Registration Order

View File

@ -94,7 +94,7 @@ The entire runtime config is available on the server-side, but it is read-only t
<script setup lang="ts"> <script setup lang="ts">
const config = useRuntimeConfig() const config = useRuntimeConfig()
console.log('Runtime config:', config) console.log('Runtime config:', config)
if (process.server) { if (import.meta.server) {
console.log('API secret:', config.apiSecret) console.log('API secret:', config.apiSecret)
} }
</script> </script>

View File

@ -138,6 +138,6 @@ import { createMemoryHistory } from 'vue-router'
// https://router.vuejs.org/api/interfaces/routeroptions.html // https://router.vuejs.org/api/interfaces/routeroptions.html
export default <RouterConfig> { export default <RouterConfig> {
history: base => process.client ? createMemoryHistory(base) : null /* default */ history: base => import.meta.client ? createMemoryHistory(base) : null /* default */
} }
``` ```

View File

@ -45,7 +45,7 @@ export default defineNuxtPlugin((nuxtApp) => {
}) })
nuxtApp.hook('vue:error', (..._args) => { nuxtApp.hook('vue:error', (..._args) => {
console.log('vue:error') console.log('vue:error')
// if (process.client) { // if (import.meta.client) {
// console.log(..._args) // console.log(..._args)
// } // }
}) })
@ -105,7 +105,7 @@ When accessing the same `payload.data` from [ssrcontext](#ssrcontext), you can a
export const useColor = () => useState<string>('color', () => 'pink') export const useColor = () => useState<string>('color', () => 'pink')
export default defineNuxtPlugin((nuxtApp) => { export default defineNuxtPlugin((nuxtApp) => {
if (process.server) { if (import.meta.server) {
const color = useColor() const color = useColor()
} }
}) })
@ -137,7 +137,7 @@ export default defineComponent({
setup (_props, { slots, emit }) { setup (_props, { slots, emit }) {
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
onErrorCaptured((err) => { onErrorCaptured((err) => {
if (process.client && !nuxtApp.isHydrating) { if (import.meta.client && !nuxtApp.isHydrating) {
// ... // ...
} }
}) })

View File

@ -128,7 +128,6 @@ export async function writeTypes (nuxt: Nuxt) {
noEmit: true, noEmit: true,
resolveJsonModule: true, resolveJsonModule: true,
allowSyntheticDefaultImports: true, allowSyntheticDefaultImports: true,
types: ['node'],
paths: {} paths: {}
}, },
include: [ include: [

View File

@ -122,6 +122,9 @@
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@parcel/watcher": { "@parcel/watcher": {
"optional": true "optional": true
},
"@types/node": {
"optional": true
} }
}, },
"engines": { "engines": {

View File

@ -1,6 +1,6 @@
// Polyfills for Safari support // Polyfills for Safari support
// https://caniuse.com/requestidlecallback // https://caniuse.com/requestidlecallback
export const requestIdleCallback: Window['requestIdleCallback'] = process.server export const requestIdleCallback: Window['requestIdleCallback'] = import.meta.server
? (() => {}) as any ? (() => {}) as any
: (globalThis.requestIdleCallback || ((cb) => { : (globalThis.requestIdleCallback || ((cb) => {
const start = Date.now() const start = Date.now()
@ -11,6 +11,6 @@ export const requestIdleCallback: Window['requestIdleCallback'] = process.server
return setTimeout(() => { cb(idleDeadline) }, 1) return setTimeout(() => { cb(idleDeadline) }, 1)
})) }))
export const cancelIdleCallback: Window['cancelIdleCallback'] = process.server export const cancelIdleCallback: Window['cancelIdleCallback'] = import.meta.server
? (() => {}) as any ? (() => {}) as any
: (globalThis.cancelIdleCallback || ((id) => { clearTimeout(id) })) : (globalThis.cancelIdleCallback || ((id) => { clearTimeout(id) }))

View File

@ -3,7 +3,7 @@ import { defineComponent } from 'vue'
export default defineComponent({ export default defineComponent({
name: 'DevOnly', name: 'DevOnly',
setup (_, props) { setup (_, props) {
if (process.dev) { if (import.meta.dev) {
return () => props.slots.default?.() return () => props.slots.default?.()
} }
return () => props.slots.fallback?.() return () => props.slots.fallback?.()

View File

@ -12,7 +12,7 @@ export default defineComponent({
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
onErrorCaptured((err, target, info) => { onErrorCaptured((err, target, info) => {
if (process.client && !nuxtApp.isHydrating) { if (import.meta.client && !nuxtApp.isHydrating) {
emit('error', err) emit('error', err)
nuxtApp.hooks.callHook('vue:error', err, target, info) nuxtApp.hooks.callHook('vue:error', err, target, info)
error.value = err error.value = err

View File

@ -36,11 +36,11 @@ const is404 = statusCode === 404
const statusMessage = _error.statusMessage ?? (is404 ? 'Page Not Found' : 'Internal Server Error') const statusMessage = _error.statusMessage ?? (is404 ? 'Page Not Found' : 'Internal Server Error')
const description = _error.message || _error.toString() const description = _error.message || _error.toString()
const stack = process.dev && !is404 ? _error.description || `<pre>${stacktrace}</pre>` : undefined const stack = import.meta.dev && !is404 ? _error.description || `<pre>${stacktrace}</pre>` : undefined
// TODO: Investigate side-effect issue with imports // TODO: Investigate side-effect issue with imports
const _Error404 = defineAsyncComponent(() => import('@nuxt/ui-templates/templates/error-404.vue').then(r => r.default || r)) const _Error404 = defineAsyncComponent(() => import('@nuxt/ui-templates/templates/error-404.vue').then(r => r.default || r))
const _Error = process.dev const _Error = import.meta.dev
? defineAsyncComponent(() => import('@nuxt/ui-templates/templates/error-dev.vue').then(r => r.default || r)) ? defineAsyncComponent(() => import('@nuxt/ui-templates/templates/error-dev.vue').then(r => r.default || r))
: defineAsyncComponent(() => import('@nuxt/ui-templates/templates/error-500.vue').then(r => r.default || r)) : defineAsyncComponent(() => import('@nuxt/ui-templates/templates/error-500.vue').then(r => r.default || r))

View File

@ -23,7 +23,7 @@ const SLOTNAME_RE = /nuxt-ssr-slot-name="([^"]*)"/g
const SLOT_FALLBACK_RE = /<div nuxt-slot-fallback-start="([^"]*)"[^>]*><\/div>(((?!<div nuxt-slot-fallback-end[^>]*>)[\s\S])*)<div nuxt-slot-fallback-end[^>]*><\/div>/g const SLOT_FALLBACK_RE = /<div nuxt-slot-fallback-start="([^"]*)"[^>]*><\/div>(((?!<div nuxt-slot-fallback-end[^>]*>)[\s\S])*)<div nuxt-slot-fallback-end[^>]*><\/div>/g
let id = 0 let id = 0
const getId = process.client ? () => (id++).toString() : randomUUID const getId = import.meta.client ? () => (id++).toString() : randomUUID
export default defineComponent({ export default defineComponent({
name: 'NuxtIsland', name: 'NuxtIsland',
@ -54,7 +54,7 @@ export default defineComponent({
const instance = getCurrentInstance()! const instance = getCurrentInstance()!
const event = useRequestEvent() const event = useRequestEvent()
// TODO: remove use of `$fetch.raw` when nitro 503 issues on windows dev server are resolved // TODO: remove use of `$fetch.raw` when nitro 503 issues on windows dev server are resolved
const eventFetch = process.server ? event.fetch : process.dev ? $fetch.raw : globalThis.fetch const eventFetch = import.meta.server ? event.fetch : import.meta.dev ? $fetch.raw : globalThis.fetch
const mounted = ref(false) const mounted = ref(false)
onMounted(() => { mounted.value = true }) onMounted(() => { mounted.value = true })
@ -62,7 +62,7 @@ export default defineComponent({
nuxtApp.payload.data[key] = { nuxtApp.payload.data[key] = {
__nuxt_island: { __nuxt_island: {
key, key,
...(process.server && process.env.prerender) ...(import.meta.server && import.meta.prerender)
? {} ? {}
: { params: { ...props.context, props: props.props ? JSON.stringify(props.props) : undefined } } : { params: { ...props.context, props: props.props ? JSON.stringify(props.props) : undefined } }
}, },
@ -71,7 +71,7 @@ export default defineComponent({
} }
const ssrHTML = ref<string>('') const ssrHTML = ref<string>('')
if (process.client) { if (import.meta.client) {
const renderedHTML = getFragmentHTML(instance.vnode?.el ?? null).join('') const renderedHTML = getFragmentHTML(instance.vnode?.el ?? null).join('')
if (renderedHTML && nuxtApp.isHydrating) { if (renderedHTML && nuxtApp.isHydrating) {
setPayload(`${props.name}_${hashId.value}`, { setPayload(`${props.name}_${hashId.value}`, {
@ -111,19 +111,19 @@ export default defineComponent({
const url = remoteComponentIslands && props.source ? new URL(`/__nuxt_island/${key}`, props.source).href : `/__nuxt_island/${key}` const url = remoteComponentIslands && props.source ? new URL(`/__nuxt_island/${key}`, props.source).href : `/__nuxt_island/${key}`
if (process.server && process.env.prerender) { if (import.meta.server && import.meta.prerender) {
// Hint to Nitro to prerender the island component // Hint to Nitro to prerender the island component
appendResponseHeader(event, 'x-nitro-prerender', url) appendResponseHeader(event, 'x-nitro-prerender', url)
} }
// TODO: Validate response // TODO: Validate response
// $fetch handles the app.baseURL in dev // $fetch handles the app.baseURL in dev
const r = await eventFetch(withQuery(process.dev && process.client ? url : joinURL(config.app.baseURL ?? '', url), { const r = await eventFetch(withQuery(import.meta.dev && import.meta.client ? url : joinURL(config.app.baseURL ?? '', url), {
...props.context, ...props.context,
props: props.props ? JSON.stringify(props.props) : undefined props: props.props ? JSON.stringify(props.props) : undefined
})) }))
const result = process.server || !process.dev ? await r.json() : (r as FetchResponse<NuxtIslandResponse>)._data const result = import.meta.server || !import.meta.dev ? await r.json() : (r as FetchResponse<NuxtIslandResponse>)._data
// TODO: support passing on more headers // TODO: support passing on more headers
if (process.server && process.env.prerender) { if (import.meta.server && import.meta.prerender) {
const hints = r.headers.get('x-nitro-prerender') const hints = r.headers.get('x-nitro-prerender')
if (hints) { if (hints) {
appendResponseHeader(event, 'x-nitro-prerender', hints) appendResponseHeader(event, 'x-nitro-prerender', hints)
@ -149,7 +149,7 @@ export default defineComponent({
}) })
key.value++ key.value++
error.value = null error.value = null
if (process.client) { if (import.meta.client) {
// must await next tick for Teleport to work correctly with static node re-rendering // must await next tick for Teleport to work correctly with static node re-rendering
await nextTick() await nextTick()
} }
@ -165,13 +165,13 @@ export default defineComponent({
}) })
} }
if (process.client) { if (import.meta.client) {
watch(props, debounce(() => fetchComponent(), 100)) watch(props, debounce(() => fetchComponent(), 100))
} }
if (process.client && !nuxtApp.isHydrating && props.lazy) { if (import.meta.client && !nuxtApp.isHydrating && props.lazy) {
fetchComponent() fetchComponent()
} else if (process.server || !nuxtApp.isHydrating) { } else if (import.meta.server || !nuxtApp.isHydrating) {
await fetchComponent() await fetchComponent()
} }
@ -182,10 +182,10 @@ export default defineComponent({
const nodes = [createVNode(Fragment, { const nodes = [createVNode(Fragment, {
key: key.value key: key.value
}, [h(createStaticVNode(html.value || '<div></div>', 1))])] }, [h(createStaticVNode(html.value || '<div></div>', 1))])]
if (uid.value && (mounted.value || nuxtApp.isHydrating || process.server)) { if (uid.value && (mounted.value || nuxtApp.isHydrating || import.meta.server)) {
for (const slot in slots) { for (const slot in slots) {
if (availableSlots.value.includes(slot)) { if (availableSlots.value.includes(slot)) {
nodes.push(createVNode(Teleport, { to: process.client ? `[nuxt-ssr-component-uid='${uid.value}'] [nuxt-ssr-slot-name='${slot}']` : `uid=${uid.value};slot=${slot}` }, { nodes.push(createVNode(Teleport, { to: import.meta.client ? `[nuxt-ssr-component-uid='${uid.value}'] [nuxt-ssr-slot-name='${slot}']` : `uid=${uid.value};slot=${slot}` }, {
default: () => (slotProps.value[slot] ?? [undefined]).map((data: any) => slots[slot]?.(data)) default: () => (slotProps.value[slot] ?? [undefined]).map((data: any) => slots[slot]?.(data))
})) }))
} }

View File

@ -57,7 +57,7 @@ export default defineComponent({
return () => { return () => {
const hasLayout = layout.value && layout.value in layouts const hasLayout = layout.value && layout.value in layouts
if (process.dev && layout.value && !hasLayout && layout.value !== 'default') { if (import.meta.dev && layout.value && !hasLayout && layout.value !== 'default') {
console.warn(`Invalid layout \`${layout.value}\` selected.`) console.warn(`Invalid layout \`${layout.value}\` selected.`)
} }
@ -112,7 +112,7 @@ const LayoutProvider = defineComponent({
} }
let vnode: VNode | undefined let vnode: VNode | undefined
if (process.dev && process.client) { if (import.meta.dev && import.meta.client) {
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
if (['#comment', '#text'].includes(vnode?.el?.nodeName)) { if (['#comment', '#text'].includes(vnode?.el?.nodeName)) {
@ -128,14 +128,14 @@ const LayoutProvider = defineComponent({
return () => { return () => {
if (!name || (typeof name === 'string' && !(name in layouts))) { if (!name || (typeof name === 'string' && !(name in layouts))) {
if (process.dev && process.client && props.hasTransition) { if (import.meta.dev && import.meta.client && props.hasTransition) {
vnode = context.slots.default?.() as VNode | undefined vnode = context.slots.default?.() as VNode | undefined
return vnode return vnode
} }
return context.slots.default?.() return context.slots.default?.()
} }
if (process.dev && process.client && props.hasTransition) { if (import.meta.dev && import.meta.client && props.hasTransition) {
vnode = h( vnode = h(
// @ts-expect-error seems to be an issue in vue types // @ts-expect-error seems to be an issue in vue types
LayoutLoader, LayoutLoader,

View File

@ -51,7 +51,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
const componentName = options.componentName || 'NuxtLink' const componentName = options.componentName || 'NuxtLink'
const checkPropConflicts = (props: NuxtLinkProps, main: keyof NuxtLinkProps, sub: keyof NuxtLinkProps): void => { const checkPropConflicts = (props: NuxtLinkProps, main: keyof NuxtLinkProps, sub: keyof NuxtLinkProps): void => {
if (process.dev && props[main] !== undefined && props[sub] !== undefined) { if (import.meta.dev && props[main] !== undefined && props[sub] !== undefined) {
console.warn(`[${componentName}] \`${main}\` and \`${sub}\` cannot be used together. \`${sub}\` will be ignored.`) console.warn(`[${componentName}] \`${main}\` and \`${sub}\` cannot be used together. \`${sub}\` will be ignored.`)
} }
} }
@ -198,10 +198,10 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
// Prefetching // Prefetching
const prefetched = ref(false) const prefetched = ref(false)
const el = process.server ? undefined : ref<HTMLElement | null>(null) const el = import.meta.server ? undefined : ref<HTMLElement | null>(null)
const elRef = process.server ? undefined : (ref: any) => { el!.value = props.custom ? ref?.$el?.nextElementSibling : ref?.$el } const elRef = import.meta.server ? undefined : (ref: any) => { el!.value = props.custom ? ref?.$el?.nextElementSibling : ref?.$el }
if (process.client) { if (import.meta.client) {
checkPropConflicts(props, 'prefetch', 'noPrefetch') checkPropConflicts(props, 'prefetch', 'noPrefetch')
const shouldPrefetch = props.prefetch !== false && props.noPrefetch !== true && props.target !== '_blank' && !isSlowConnection() const shouldPrefetch = props.prefetch !== false && props.noPrefetch !== true && props.target !== '_blank' && !isSlowConnection()
if (shouldPrefetch) { if (shouldPrefetch) {
@ -329,7 +329,7 @@ type CallbackFn = () => void
type ObserveFn = (element: Element, callback: CallbackFn) => () => void type ObserveFn = (element: Element, callback: CallbackFn) => () => void
function useObserver (): { observe: ObserveFn } | undefined { function useObserver (): { observe: ObserveFn } | undefined {
if (process.server) { return } if (import.meta.server) { return }
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (nuxtApp._observer) { if (nuxtApp._observer) {
@ -370,7 +370,7 @@ function useObserver (): { observe: ObserveFn } | undefined {
} }
function isSlowConnection () { function isSlowConnection () {
if (process.server) { return } if (import.meta.server) { return }
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
const cn = (navigator as any).connection as { saveData: boolean, effectiveType: string } | null const cn = (navigator as any).connection as { saveData: boolean, effectiveType: string } | null

View File

@ -101,7 +101,7 @@ function useLoadingIndicator (opts: {
function start () { function start () {
clear() clear()
progress.value = 0 progress.value = 0
if (opts.throttle && process.client) { if (opts.throttle && import.meta.client) {
_throttle = setTimeout(() => { _throttle = setTimeout(() => {
isLoading.value = true isLoading.value = true
_startTimer() _startTimer()
@ -129,7 +129,7 @@ function useLoadingIndicator (opts: {
function _hide () { function _hide () {
clear() clear()
if (process.client) { if (import.meta.client) {
setTimeout(() => { setTimeout(() => {
isLoading.value = false isLoading.value = false
setTimeout(() => { progress.value = 0 }, 400) setTimeout(() => { progress.value = 0 }, 400)
@ -138,7 +138,7 @@ function useLoadingIndicator (opts: {
} }
function _startTimer () { function _startTimer () {
if (process.client) { if (import.meta.client) {
_timer = setInterval(() => { _increase(step.value) }, 100) _timer = setInterval(() => { _increase(step.value) }, 100)
} }
} }

View File

@ -16,23 +16,23 @@ import { PageRouteSymbol } from '#app/components/injections'
import AppComponent from '#build/app-component.mjs' import AppComponent from '#build/app-component.mjs'
import ErrorComponent from '#build/error-component.mjs' import ErrorComponent from '#build/error-component.mjs'
const IslandRenderer = process.server const IslandRenderer = import.meta.server
? defineAsyncComponent(() => import('./island-renderer').then(r => r.default || r)) ? defineAsyncComponent(() => import('./island-renderer').then(r => r.default || r))
: () => null : () => null
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const onResolve = nuxtApp.deferHydration() const onResolve = nuxtApp.deferHydration()
const url = process.server ? nuxtApp.ssrContext.url : window.location.pathname const url = import.meta.server ? nuxtApp.ssrContext.url : window.location.pathname
const SingleRenderer = process.test && process.dev && process.server && url.startsWith('/__nuxt_component_test__/') && /* #__PURE__ */ defineAsyncComponent(() => import('#build/test-component-wrapper.mjs') const SingleRenderer = import.meta.test && import.meta.dev && import.meta.server && url.startsWith('/__nuxt_component_test__/') && /* #__PURE__ */ defineAsyncComponent(() => import('#build/test-component-wrapper.mjs')
.then(r => r.default(process.server ? url : window.location.href))) .then(r => r.default(import.meta.server ? url : window.location.href)))
// Inject default route (outside of pages) as active route // Inject default route (outside of pages) as active route
provide(PageRouteSymbol, useRoute()) provide(PageRouteSymbol, useRoute())
// vue:setup hook // vue:setup hook
const results = nuxtApp.hooks.callHookWith(hooks => hooks.map(hook => hook()), 'vue:setup') const results = nuxtApp.hooks.callHookWith(hooks => hooks.map(hook => hook()), 'vue:setup')
if (process.dev && results && results.some(i => i && 'then' in i)) { if (import.meta.dev && results && results.some(i => i && 'then' in i)) {
console.error('[nuxt] Error in `vue:setup`. Callbacks must be synchronous.') console.error('[nuxt] Error in `vue:setup`. Callbacks must be synchronous.')
} }
@ -40,7 +40,7 @@ if (process.dev && results && results.some(i => i && 'then' in i)) {
const error = useError() const error = useError()
onErrorCaptured((err, target, info) => { onErrorCaptured((err, target, info) => {
nuxtApp.hooks.callHook('vue:error', err, target, info).catch(hookError => console.error('[nuxt] Error in `vue:error` hook', hookError)) nuxtApp.hooks.callHook('vue:error', err, target, info).catch(hookError => console.error('[nuxt] Error in `vue:error` hook', hookError))
if (process.server || (isNuxtError(err) && (err.fatal || err.unhandled))) { if (import.meta.server || (isNuxtError(err) && (err.fatal || err.unhandled))) {
const p = nuxtApp.runWithContext(() => showError(err)) const p = nuxtApp.runWithContext(() => showError(err))
onServerPrefetch(() => p) onServerPrefetch(() => p)
return false // suppress error from breaking render return false // suppress error from breaking render
@ -48,5 +48,5 @@ onErrorCaptured((err, target, info) => {
}) })
// Component islands context // Component islands context
const { islandContext } = process.server && nuxtApp.ssrContext const islandContext = import.meta.server && nuxtApp.ssrContext.islandContext
</script> </script>

View File

@ -36,7 +36,7 @@ export const RouteProvider = defineComponent({
provide(PageRouteSymbol, shallowReactive(route)) provide(PageRouteSymbol, shallowReactive(route))
let vnode: VNode let vnode: VNode
if (process.dev && process.client && props.trackRootNodes) { if (import.meta.dev && import.meta.client && props.trackRootNodes) {
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
if (['#comment', '#text'].includes(vnode?.el?.nodeName)) { if (['#comment', '#text'].includes(vnode?.el?.nodeName)) {
@ -48,7 +48,7 @@ export const RouteProvider = defineComponent({
} }
return () => { return () => {
if (process.dev && process.client) { if (import.meta.dev && import.meta.client) {
vnode = h(props.vnode, { ref: props.vnodeRef }) vnode = h(props.vnode, { ref: props.vnodeRef })
return vnode return vnode
} }

View File

@ -73,7 +73,7 @@ export function vforToArray (source: any): any[] {
} else if (isString(source)) { } else if (isString(source)) {
return source.split('') return source.split('')
} else if (typeof source === 'number') { } else if (typeof source === 'number') {
if (process.dev && !Number.isInteger(source)) { if (import.meta.dev && !Number.isInteger(source)) {
console.warn(`The v-for range expect an integer value but got ${source}.`) console.warn(`The v-for range expect an integer value but got ${source}.`)
} }
const array = [] const array = []

View File

@ -222,7 +222,7 @@ export function useAsyncData<
const fetchOnServer = options.server !== false && nuxt.payload.serverRendered const fetchOnServer = options.server !== false && nuxt.payload.serverRendered
// Server side // Server side
if (process.server && fetchOnServer && options.immediate) { if (import.meta.server && fetchOnServer && options.immediate) {
const promise = initialFetch() const promise = initialFetch()
if (getCurrentInstance()) { if (getCurrentInstance()) {
onServerPrefetch(() => promise) onServerPrefetch(() => promise)
@ -232,7 +232,7 @@ export function useAsyncData<
} }
// Client side // Client side
if (process.client) { if (import.meta.client) {
// Setup hook callbacks once per instance // Setup hook callbacks once per instance
const instance = getCurrentInstance() const instance = getCurrentInstance()
if (instance && !instance._nuxtOnBeforeMountCbs) { if (instance && !instance._nuxtOnBeforeMountCbs) {
@ -349,7 +349,7 @@ export function useNuxtData<DataT = any> (key: string): { data: Ref<DataT | null
} }
export async function refreshNuxtData (keys?: string | string[]): Promise<void> { export async function refreshNuxtData (keys?: string | string[]): Promise<void> {
if (process.server) { if (import.meta.server) {
return Promise.resolve() return Promise.resolve()
} }

View File

@ -29,7 +29,7 @@ export interface ReloadNuxtAppOptions {
} }
export function reloadNuxtApp (options: ReloadNuxtAppOptions = {}) { export function reloadNuxtApp (options: ReloadNuxtAppOptions = {}) {
if (process.server) { return } if (import.meta.server) { return }
const path = options.path || window.location.pathname const path = options.path || window.location.pathname
let handledPath: Record<string, any> = {} let handledPath: Record<string, any> = {}

View File

@ -22,7 +22,7 @@ async function runLegacyAsyncData (res: Record<string, any> | Promise<Record<str
} }
if (data.value && typeof data.value === 'object') { if (data.value && typeof data.value === 'object') {
Object.assign(await res, toRefs(reactive(data.value))) Object.assign(await res, toRefs(reactive(data.value)))
} else if (process.dev) { } else if (import.meta.dev) {
console.warn('[nuxt] asyncData should return an object', data) console.warn('[nuxt] asyncData should return an object', data)
} }
} }

View File

@ -33,7 +33,7 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
const cookie = ref<T | undefined>(cookies[name] as any ?? opts.default?.()) const cookie = ref<T | undefined>(cookies[name] as any ?? opts.default?.())
if (process.client) { if (import.meta.client) {
const channel = typeof BroadcastChannel === 'undefined' ? null : new BroadcastChannel(`nuxt:cookies:${name}`) const channel = typeof BroadcastChannel === 'undefined' ? null : new BroadcastChannel(`nuxt:cookies:${name}`)
if (getCurrentInstance()) { onUnmounted(() => { channel?.close() }) } if (getCurrentInstance()) { onUnmounted(() => { channel?.close() }) }
@ -61,7 +61,7 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
} else { } else {
callback() callback()
} }
} else if (process.server) { } else if (import.meta.server) {
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const writeFinalCookieValue = () => { const writeFinalCookieValue = () => {
if (!isEqual(cookie.value, cookies[name])) { if (!isEqual(cookie.value, cookies[name])) {
@ -79,9 +79,9 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
} }
function readRawCookies (opts: CookieOptions = {}): Record<string, string> | undefined { function readRawCookies (opts: CookieOptions = {}): Record<string, string> | undefined {
if (process.server) { if (import.meta.server) {
return parse(useRequestEvent()?.node.req.headers.cookie || '', opts) return parse(useRequestEvent()?.node.req.headers.cookie || '', opts)
} else if (process.client) { } else if (import.meta.client) {
return parse(document.cookie, opts) return parse(document.cookie, opts)
} }
} }
@ -94,7 +94,7 @@ function serializeCookie (name: string, value: any, opts: CookieSerializeOptions
} }
function writeClientCookie (name: string, value: any, opts: CookieSerializeOptions = {}) { function writeClientCookie (name: string, value: any, opts: CookieSerializeOptions = {}) {
if (process.client) { if (import.meta.client) {
document.cookie = serializeCookie(name, value, opts) document.cookie = serializeCookie(name, value, opts)
} }
} }

View File

@ -14,7 +14,7 @@ export const showError = (_err: string | Error | Partial<NuxtError>) => {
try { try {
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const error = useError() const error = useError()
if (process.client) { if (import.meta.client) {
nuxtApp.hooks.callHook('app:error', err) nuxtApp.hooks.callHook('app:error', err)
} }
error.value = error.value || err error.value = error.value || err

View File

@ -134,7 +134,7 @@ export function useFetch<
const isLocalFetch = typeof _request.value === 'string' && _request.value.startsWith('/') const isLocalFetch = typeof _request.value === 'string' && _request.value.startsWith('/')
let _$fetch = opts.$fetch || globalThis.$fetch let _$fetch = opts.$fetch || globalThis.$fetch
// Use fetch with request context and headers for server direct API calls // Use fetch with request context and headers for server direct API calls
if (process.server && !opts.$fetch && isLocalFetch) { if (import.meta.server && !opts.$fetch && isLocalFetch) {
_$fetch = useRequestFetch() _$fetch = useRequestFetch()
} }

View File

@ -11,13 +11,13 @@ import type { NuxtPayload } from '#app'
export const useHydration = <K extends keyof NuxtPayload, T = NuxtPayload[K]> (key: K, get: () => T, set: (value: T) => void) => { export const useHydration = <K extends keyof NuxtPayload, T = NuxtPayload[K]> (key: K, get: () => T, set: (value: T) => void) => {
const nuxt = useNuxtApp() const nuxt = useNuxtApp()
if (process.server) { if (import.meta.server) {
nuxt.hooks.hook('app:rendered', () => { nuxt.hooks.hook('app:rendered', () => {
nuxt.payload[key] = get() nuxt.payload[key] = get()
}) })
} }
if (process.client) { if (import.meta.client) {
nuxt.hooks.hook('app:created', () => { nuxt.hooks.hook('app:created', () => {
set(nuxt.payload[key] as T) set(nuxt.payload[key] as T)
}) })

View File

@ -13,7 +13,7 @@ interface LoadPayloadOptions {
} }
export function loadPayload (url: string, opts: LoadPayloadOptions = {}): Record<string, any> | Promise<Record<string, any>> | null { export function loadPayload (url: string, opts: LoadPayloadOptions = {}): Record<string, any> | Promise<Record<string, any>> | null {
if (process.server) { return null } if (import.meta.server) { return null }
const payloadURL = _getPayloadURL(url, opts) const payloadURL = _getPayloadURL(url, opts)
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const cache = nuxtApp._payloadCache = nuxtApp._payloadCache || {} const cache = nuxtApp._payloadCache = nuxtApp._payloadCache || {}
@ -55,7 +55,7 @@ function _getPayloadURL (url: string, opts: LoadPayloadOptions = {}) {
} }
async function _importPayload (payloadURL: string) { async function _importPayload (payloadURL: string) {
if (process.server) { return null } if (import.meta.server) { return null }
try { try {
return renderJsonPayloads return renderJsonPayloads
? parsePayload(await fetch(payloadURL).then(res => res.text())) ? parsePayload(await fetch(payloadURL).then(res => res.text()))
@ -74,7 +74,7 @@ export function isPrerendered () {
let payloadCache: any = null let payloadCache: any = null
export async function getNuxtClientPayload () { export async function getNuxtClientPayload () {
if (process.server) { if (import.meta.server) {
return return
} }
if (payloadCache) { if (payloadCache) {
@ -110,7 +110,7 @@ export function definePayloadReducer (
name: string, name: string,
reduce: (data: any) => any reduce: (data: any) => any
) { ) {
if (process.server) { if (import.meta.server) {
useNuxtApp().ssrContext!._payloadReducers[name] = reduce useNuxtApp().ssrContext!._payloadReducers[name] = reduce
} }
} }
@ -124,10 +124,10 @@ export function definePayloadReviver (
name: string, name: string,
revive: (data: string) => any | undefined revive: (data: string) => any | undefined
) { ) {
if (process.dev && getCurrentInstance()) { if (import.meta.dev && getCurrentInstance()) {
console.warn('[nuxt] [definePayloadReviver] This function must be called in a Nuxt plugin that is `unshift`ed to the beginning of the Nuxt plugins array.') console.warn('[nuxt] [definePayloadReviver] This function must be called in a Nuxt plugin that is `unshift`ed to the beginning of the Nuxt plugins array.')
} }
if (process.client) { if (import.meta.client) {
useNuxtApp()._payloadRevivers[name] = revive useNuxtApp()._payloadRevivers[name] = revive
} }
} }

View File

@ -9,7 +9,7 @@ import { useRouter } from './router'
* @param components Pascal-cased name or names of components to prefetch * @param components Pascal-cased name or names of components to prefetch
*/ */
export const preloadComponents = async (components: string | string[]) => { export const preloadComponents = async (components: string | string[]) => {
if (process.server) { return } if (import.meta.server) { return }
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
components = Array.isArray(components) ? components : [components] components = Array.isArray(components) ? components : [components]
@ -35,7 +35,7 @@ function _loadAsyncComponent (component: Component) {
} }
export async function preloadRouteComponents (to: RouteLocationRaw, router: Router & { _routePreloaded?: Set<string>; _preloadPromises?: Array<Promise<any>> } = useRouter()): Promise<void> { export async function preloadRouteComponents (to: RouteLocationRaw, router: Router & { _routePreloaded?: Set<string>; _preloadPromises?: Array<Promise<any>> } = useRouter()): Promise<void> {
if (process.server) { return } if (import.meta.server) { return }
const { path, matched } = router.resolve(to) const { path, matched } = router.resolve(to)

View File

@ -2,7 +2,7 @@ import { useNuxtApp } from '../nuxt'
import { requestIdleCallback } from '../compat/idle-callback' import { requestIdleCallback } from '../compat/idle-callback'
export const onNuxtReady = (callback: () => any) => { export const onNuxtReady = (callback: () => any) => {
if (process.server) { return } if (import.meta.server) { return }
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (nuxtApp.isHydrating) { if (nuxtApp.isHydrating) {

View File

@ -17,7 +17,7 @@ export const useRouter: typeof _useRouter = () => {
} }
export const useRoute: typeof _useRoute = () => { export const useRoute: typeof _useRoute = () => {
if (process.dev && isProcessingMiddleware()) { if (import.meta.dev && isProcessingMiddleware()) {
console.warn('[nuxt] Calling `useRoute` within middleware may lead to misleading results. Instead, use the (to, from) arguments passed to the middleware to access the new and old routes.') console.warn('[nuxt] Calling `useRoute` within middleware may lead to misleading results. Instead, use the (to, from) arguments passed to the middleware to access the new and old routes.')
} }
if (hasInjectionContext()) { if (hasInjectionContext()) {
@ -118,7 +118,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
// Early open handler // Early open handler
if (options?.open) { if (options?.open) {
if (process.client) { if (import.meta.client) {
const { target = '_blank', windowFeatures = {} } = options.open const { target = '_blank', windowFeatures = {} } = options.open
const features = Object.entries(windowFeatures) const features = Object.entries(windowFeatures)
@ -146,7 +146,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
const inMiddleware = isProcessingMiddleware() const inMiddleware = isProcessingMiddleware()
// Early redirect on client-side // Early redirect on client-side
if (process.client && !isExternal && inMiddleware) { if (import.meta.client && !isExternal && inMiddleware) {
return to return to
} }
@ -154,7 +154,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (process.server) { if (import.meta.server) {
if (nuxtApp.ssrContext) { if (nuxtApp.ssrContext) {
const fullPath = typeof to === 'string' || isExternal ? toPath : router.resolve(to).fullPath || '/' const fullPath = typeof to === 'string' || isExternal ? toPath : router.resolve(to).fullPath || '/'
const location = isExternal ? toPath : joinURL(useRuntimeConfig().app.baseURL, fullPath) const location = isExternal ? toPath : joinURL(useRuntimeConfig().app.baseURL, fullPath)
@ -206,7 +206,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
/** This will abort navigation within a Nuxt route middleware handler. */ /** This will abort navigation within a Nuxt route middleware handler. */
export const abortNavigation = (err?: string | Partial<NuxtError>) => { export const abortNavigation = (err?: string | Partial<NuxtError>) => {
if (process.dev && !isProcessingMiddleware()) { if (import.meta.dev && !isProcessingMiddleware()) {
throw new Error('abortNavigation() is only usable inside a route middleware handler.') throw new Error('abortNavigation() is only usable inside a route middleware handler.')
} }
@ -222,18 +222,18 @@ export const abortNavigation = (err?: string | Partial<NuxtError>) => {
} }
export const setPageLayout = (layout: unknown extends PageMeta['layout'] ? string : PageMeta['layout']) => { export const setPageLayout = (layout: unknown extends PageMeta['layout'] ? string : PageMeta['layout']) => {
if (process.server) { if (import.meta.server) {
if (process.dev && getCurrentInstance() && useState('_layout').value !== layout) { if (import.meta.dev && getCurrentInstance() && useState('_layout').value !== layout) {
console.warn('[warn] [nuxt] `setPageLayout` should not be called to change the layout on the server within a component as this will cause hydration errors.') console.warn('[warn] [nuxt] `setPageLayout` should not be called to change the layout on the server within a component as this will cause hydration errors.')
} }
useState('_layout').value = layout useState('_layout').value = layout
} }
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (process.dev && nuxtApp.isHydrating && nuxtApp.payload.serverRendered && useState('_layout').value !== layout) { if (import.meta.dev && nuxtApp.isHydrating && nuxtApp.payload.serverRendered && useState('_layout').value !== layout) {
console.warn('[warn] [nuxt] `setPageLayout` should not be called to change the layout during hydration as this will cause hydration errors.') console.warn('[warn] [nuxt] `setPageLayout` should not be called to change the layout during hydration as this will cause hydration errors.')
} }
const inMiddleware = isProcessingMiddleware() const inMiddleware = isProcessingMiddleware()
if (inMiddleware || process.server || nuxtApp.isHydrating) { if (inMiddleware || import.meta.server || nuxtApp.isHydrating) {
const unsubscribe = useRouter().beforeResolve((to) => { const unsubscribe = useRouter().beforeResolve((to) => {
to.meta.layout = layout as Exclude<PageMeta['layout'], Ref | false> to.meta.layout = layout as Exclude<PageMeta['layout'], Ref | false>
unsubscribe() unsubscribe()

View File

@ -6,7 +6,7 @@ import { useNuxtApp } from '../nuxt'
export function useRequestHeaders<K extends string = string> (include: K[]): { [key in Lowercase<K>]?: string } export function useRequestHeaders<K extends string = string> (include: K[]): { [key in Lowercase<K>]?: string }
export function useRequestHeaders (): Readonly<Record<string, string>> export function useRequestHeaders (): Readonly<Record<string, string>>
export function useRequestHeaders (include?: any[]) { export function useRequestHeaders (include?: any[]) {
if (process.client) { return {} } if (import.meta.client) { return {} }
const headers = useNuxtApp().ssrContext?.event.node.req.headers ?? {} const headers = useNuxtApp().ssrContext?.event.node.req.headers ?? {}
if (!include) { return headers } if (!include) { return headers }
return Object.fromEntries(include.map(key => key.toLowerCase()).filter(key => headers[key]).map(key => [key, headers[key]])) return Object.fromEntries(include.map(key => key.toLowerCase()).filter(key => headers[key]).map(key => [key, headers[key]]))
@ -17,7 +17,7 @@ export function useRequestEvent (nuxtApp: NuxtApp = useNuxtApp()): H3Event {
} }
export function useRequestFetch (): typeof global.$fetch { export function useRequestFetch (): typeof global.$fetch {
if (process.client) { if (import.meta.client) {
return globalThis.$fetch return globalThis.$fetch
} }
const event = useNuxtApp().ssrContext?.event as H3Event const event = useNuxtApp().ssrContext?.event as H3Event
@ -28,7 +28,7 @@ export function setResponseStatus (event: H3Event, code?: number, message?: stri
/** @deprecated Pass `event` as first option. */ /** @deprecated Pass `event` as first option. */
export function setResponseStatus (code: number, message?: string): void export function setResponseStatus (code: number, message?: string): void
export function setResponseStatus (arg1: H3Event | number | undefined, arg2?: number | string, arg3?: string) { export function setResponseStatus (arg1: H3Event | number | undefined, arg2?: number | string, arg3?: string) {
if (process.client) { return } if (import.meta.client) { return }
if (arg1 && typeof arg1 !== 'number') { if (arg1 && typeof arg1 !== 'number') {
return _setResponseStatus(arg1, arg2 as number | undefined, arg3) return _setResponseStatus(arg1, arg2 as number | undefined, arg3)
} }

View File

@ -4,7 +4,7 @@ import { useRequestEvent } from './ssr'
import { useRuntimeConfig } from '#app' import { useRuntimeConfig } from '#app'
export function useRequestURL () { export function useRequestURL () {
if (process.server) { if (import.meta.server) {
const url = getRequestURL(useRequestEvent()) const url = getRequestURL(useRequestEvent())
url.pathname = joinURL(useRuntimeConfig().app.baseURL, url.pathname) url.pathname = joinURL(useRuntimeConfig().app.baseURL, url.pathname)
return url return url

View File

@ -38,7 +38,7 @@ function deepAssign (obj: any, newObj: any) {
export function useAppConfig (): AppConfig { export function useAppConfig (): AppConfig {
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (!nuxtApp._appConfig) { if (!nuxtApp._appConfig) {
nuxtApp._appConfig = (process.server ? klona(__appConfig) : reactive(__appConfig)) as AppConfig nuxtApp._appConfig = (import.meta.server ? klona(__appConfig) : reactive(__appConfig)) as AppConfig
} }
return nuxtApp._appConfig return nuxtApp._appConfig
} }
@ -54,7 +54,7 @@ export function updateAppConfig (appConfig: DeepPartial<AppConfig>) {
} }
// HMR Support // HMR Support
if (process.dev) { if (import.meta.dev) {
function applyHMR (newConfig: AppConfig) { function applyHMR (newConfig: AppConfig) {
const appConfig = useAppConfig() const appConfig = useAppConfig()
if (newConfig && appConfig) { if (newConfig && appConfig) {

View File

@ -1,10 +1,10 @@
import type { CreateOptions } from '#app' import type { CreateOptions } from '#app'
const entry = process.server const entry = import.meta.server
? (ctx?: CreateOptions['ssrContext']) => import('#app/entry').then(m => m.default(ctx)) ? (ctx?: CreateOptions['ssrContext']) => import('#app/entry').then(m => m.default(ctx))
: () => import('#app/entry').then(m => m.default) : () => import('#app/entry').then(m => m.default)
if (process.client) { if (import.meta.client) {
entry() entry()
} }

View File

@ -26,7 +26,7 @@ if (!globalThis.$fetch) {
let entry: Function let entry: Function
if (process.server) { if (import.meta.server) {
entry = async function createNuxtAppServer (ssrContext: CreateOptions['ssrContext']) { entry = async function createNuxtAppServer (ssrContext: CreateOptions['ssrContext']) {
const vueApp = createApp(RootComponent) const vueApp = createApp(RootComponent)
@ -45,10 +45,10 @@ if (process.server) {
} }
} }
if (process.client) { if (import.meta.client) {
// TODO: temporary webpack 5 HMR fix // TODO: temporary webpack 5 HMR fix
// https://github.com/webpack-contrib/webpack-hot-middleware/issues/390 // https://github.com/webpack-contrib/webpack-hot-middleware/issues/390
if (process.dev && import.meta.webpackHot) { if (import.meta.dev && import.meta.webpackHot) {
import.meta.webpackHot.accept() import.meta.webpackHot.accept()
} }

View File

@ -210,13 +210,13 @@ export function createNuxtApp (options: CreateOptions) {
data: {}, data: {},
state: {}, state: {},
_errors: {}, _errors: {},
...(process.client ? window.__NUXT__ ?? {} : { serverRendered: true }) ...(import.meta.client ? window.__NUXT__ ?? {} : { serverRendered: true })
}), }),
static: { static: {
data: {} data: {}
}, },
runWithContext: (fn: any) => callWithNuxt(nuxtApp, fn), runWithContext: (fn: any) => callWithNuxt(nuxtApp, fn),
isHydrating: process.client, isHydrating: import.meta.client,
deferHydration () { deferHydration () {
if (!nuxtApp.isHydrating) { return () => {} } if (!nuxtApp.isHydrating) { return () => {} }
@ -244,7 +244,7 @@ export function createNuxtApp (options: CreateOptions) {
nuxtApp.hooks = createHooks<RuntimeNuxtHooks>() nuxtApp.hooks = createHooks<RuntimeNuxtHooks>()
nuxtApp.hook = nuxtApp.hooks.hook nuxtApp.hook = nuxtApp.hooks.hook
if (process.server) { if (import.meta.server) {
async function contextCaller (hooks: HookCallback[], args: any[]) { async function contextCaller (hooks: HookCallback[], args: any[]) {
for (const hook of hooks) { for (const hook of hooks) {
await nuxtApp.runWithContext(() => hook(...args)) await nuxtApp.runWithContext(() => hook(...args))
@ -267,7 +267,7 @@ export function createNuxtApp (options: CreateOptions) {
defineGetter(nuxtApp.vueApp, '$nuxt', nuxtApp) defineGetter(nuxtApp.vueApp, '$nuxt', nuxtApp)
defineGetter(nuxtApp.vueApp.config.globalProperties, '$nuxt', nuxtApp) defineGetter(nuxtApp.vueApp.config.globalProperties, '$nuxt', nuxtApp)
if (process.server) { if (import.meta.server) {
if (nuxtApp.ssrContext) { if (nuxtApp.ssrContext) {
// Expose nuxt to the renderContext // Expose nuxt to the renderContext
nuxtApp.ssrContext.nuxt = nuxtApp nuxtApp.ssrContext.nuxt = nuxtApp
@ -291,7 +291,7 @@ export function createNuxtApp (options: CreateOptions) {
} }
// Listen to chunk load errors // Listen to chunk load errors
if (process.client) { if (import.meta.client) {
window.addEventListener('nuxt.preloadError', (event) => { window.addEventListener('nuxt.preloadError', (event) => {
nuxtApp.callHook('app:chunkError', { error: (event as Event & { payload: Error }).payload }) nuxtApp.callHook('app:chunkError', { error: (event as Event & { payload: Error }).payload })
}) })
@ -305,7 +305,7 @@ export function createNuxtApp (options: CreateOptions) {
} }
// Expose runtime config // Expose runtime config
const runtimeConfig = process.server ? options.ssrContext!.runtimeConfig : reactive(nuxtApp.payload.config!) const runtimeConfig = import.meta.server ? options.ssrContext!.runtimeConfig : reactive(nuxtApp.payload.config!)
nuxtApp.provide('config', runtimeConfig) nuxtApp.provide('config', runtimeConfig)
return nuxtApp return nuxtApp
@ -329,7 +329,7 @@ export async function applyPlugins (nuxtApp: NuxtApp, plugins: Array<Plugin & Ob
const parallels: Promise<any>[] = [] const parallels: Promise<any>[] = []
const errors: Error[] = [] const errors: Error[] = []
for (const plugin of plugins) { for (const plugin of plugins) {
if (process.server && nuxtApp.ssrContext?.islandContext && plugin.env?.islands === false) { continue } if (import.meta.server && nuxtApp.ssrContext?.islandContext && plugin.env?.islands === false) { continue }
const promise = applyPlugin(nuxtApp, plugin) const promise = applyPlugin(nuxtApp, plugin)
if (plugin.parallel) { if (plugin.parallel) {
parallels.push(promise.catch(e => errors.push(e))) parallels.push(promise.catch(e => errors.push(e)))
@ -363,7 +363,7 @@ export function isNuxtPlugin (plugin: unknown) {
*/ */
export function callWithNuxt<T extends (...args: any[]) => any> (nuxt: NuxtApp | _NuxtApp, setup: T, args?: Parameters<T>) { export function callWithNuxt<T extends (...args: any[]) => any> (nuxt: NuxtApp | _NuxtApp, setup: T, args?: Parameters<T>) {
const fn: () => ReturnType<T> = () => args ? setup(...args as Parameters<T>) : setup() const fn: () => ReturnType<T> = () => args ? setup(...args as Parameters<T>) : setup()
if (process.server) { if (import.meta.server) {
return nuxt.vueApp.runWithContext(() => nuxtAppCtx.callAsync(nuxt as NuxtApp, fn)) return nuxt.vueApp.runWithContext(() => nuxtAppCtx.callAsync(nuxt as NuxtApp, fn))
} else { } else {
// In client side we could assume nuxt app is singleton // In client side we could assume nuxt app is singleton
@ -385,7 +385,7 @@ export function useNuxtApp (): NuxtApp {
nuxtAppInstance = nuxtAppInstance || nuxtAppCtx.tryUse() nuxtAppInstance = nuxtAppInstance || nuxtAppCtx.tryUse()
if (!nuxtAppInstance) { if (!nuxtAppInstance) {
if (process.dev) { if (import.meta.dev) {
throw new Error('[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at `https://nuxt.com/docs/guide/concepts/auto-imports#using-vue-and-nuxt-composables`.') throw new Error('[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at `https://nuxt.com/docs/guide/concepts/auto-imports#using-vue-and-nuxt-composables`.')
} else { } else {
throw new Error('[nuxt] instance unavailable') throw new Error('[nuxt] instance unavailable')

View File

@ -99,7 +99,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
name: 'nuxt:router', name: 'nuxt:router',
enforce: 'pre', enforce: 'pre',
setup (nuxtApp) { setup (nuxtApp) {
const initialURL = process.client const initialURL = import.meta.client
? withoutBase(window.location.pathname, useRuntimeConfig().app.baseURL) + window.location.search + window.location.hash ? withoutBase(window.location.pathname, useRuntimeConfig().app.baseURL) + window.location.search + window.location.hash
: nuxtApp.ssrContext!.url : nuxtApp.ssrContext!.url
@ -138,7 +138,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
} }
// Perform navigation // Perform navigation
Object.assign(route, to) Object.assign(route, to)
if (process.client) { if (import.meta.client) {
window.history[replace ? 'replaceState' : 'pushState']({}, '', joinURL(baseURL, to.fullPath)) window.history[replace ? 'replaceState' : 'pushState']({}, '', joinURL(baseURL, to.fullPath))
if (!nuxtApp.isHydrating) { if (!nuxtApp.isHydrating) {
// Clear any existing errors // Clear any existing errors
@ -150,7 +150,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
await middleware(to, route) await middleware(to, route)
} }
} catch (err) { } catch (err) {
if (process.dev && !hooks.error.length) { if (import.meta.dev && !hooks.error.length) {
console.warn('No error handlers registered to handle middleware errors. You can register an error handler with `router.onError()`', err) console.warn('No error handlers registered to handle middleware errors. You can register an error handler with `router.onError()`', err)
} }
for (const handler of hooks.error) { for (const handler of hooks.error) {
@ -211,7 +211,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
} }
}) })
if (process.client) { if (import.meta.client) {
window.addEventListener('popstate', (event) => { window.addEventListener('popstate', (event) => {
const location = (event.target as Window).location const location = (event.target as Window).location
router.replace(location.href.replace(location.origin, '')) router.replace(location.href.replace(location.origin, ''))
@ -235,12 +235,12 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
} }
nuxtApp._processingMiddleware = true nuxtApp._processingMiddleware = true
if (process.client || !nuxtApp.ssrContext?.islandContext) { if (import.meta.client || !nuxtApp.ssrContext?.islandContext) {
const middlewareEntries = new Set<RouteGuard>([...globalMiddleware, ...nuxtApp._middleware.global]) const middlewareEntries = new Set<RouteGuard>([...globalMiddleware, ...nuxtApp._middleware.global])
for (const middleware of middlewareEntries) { for (const middleware of middlewareEntries) {
const result = await nuxtApp.runWithContext(() => middleware(to, from)) const result = await nuxtApp.runWithContext(() => middleware(to, from))
if (process.server) { if (import.meta.server) {
if (result === false || result instanceof Error) { if (result === false || result instanceof Error) {
const error = result || createError({ const error = result || createError({
statusCode: 404, statusCode: 404,

View File

@ -1,17 +1,20 @@
import type { NuxtApp, useNuxtApp } from '../nuxt' import type { NuxtApp, useNuxtApp } from '../nuxt'
declare global { interface NuxtStaticBuildFlags {
namespace NodeJS {
interface Process {
browser: boolean browser: boolean
client: boolean client: boolean
dev: boolean dev: boolean
mode: 'spa' | 'universal'
server: boolean server: boolean
static: boolean test: boolean
} }
declare global {
namespace NodeJS {
interface Process extends NuxtStaticBuildFlags {}
} }
interface ImportMeta extends NuxtStaticBuildFlags {}
interface Window { interface Window {
__NUXT__?: Record<string, any> __NUXT__?: Record<string, any>
useNuxtApp?: typeof useNuxtApp useNuxtApp?: typeof useNuxtApp

View File

@ -15,7 +15,7 @@ export default <NitroErrorHandler> async function errorhandler (error: H3Error,
statusCode, statusCode,
statusMessage, statusMessage,
message, message,
stack: process.dev && statusCode !== 404 stack: import.meta.dev && statusCode !== 404
? `<pre>${stack.map(i => `<span class="stack${i.internal ? ' internal' : ''}">${i.text}</span>`).join('\n')}</pre>` ? `<pre>${stack.map(i => `<span class="stack${i.internal ? ' internal' : ''}">${i.text}</span>`).join('\n')}</pre>`
: '', : '',
data: error.data data: error.data
@ -56,12 +56,12 @@ export default <NitroErrorHandler> async function errorhandler (error: H3Error,
// Fallback to static rendered error page // Fallback to static rendered error page
if (!res) { if (!res) {
const { template } = process.dev const { template } = import.meta.dev
// @ts-expect-error TODO: add legacy type support for subpath imports // @ts-expect-error TODO: add legacy type support for subpath imports
? await import('@nuxt/ui-templates/templates/error-dev.mjs') ? await import('@nuxt/ui-templates/templates/error-dev.mjs')
// @ts-expect-error TODO: add legacy type support for subpath imports // @ts-expect-error TODO: add legacy type support for subpath imports
: await import('@nuxt/ui-templates/templates/error-500.mjs') : await import('@nuxt/ui-templates/templates/error-500.mjs')
if (process.dev) { if (import.meta.dev) {
// TODO: Support `message` in template // TODO: Support `message` in template
(errorObject as any).description = errorObject.message (errorObject as any).description = errorObject.message
} }

View File

@ -108,7 +108,7 @@ const getSSRRenderer = lazyCachedFunction(async () => {
async function renderToString (input: RenderToStringParams[0], context: RenderToStringParams[1]) { async function renderToString (input: RenderToStringParams[0], context: RenderToStringParams[1]) {
const html = await _renderToString(input, context) const html = await _renderToString(input, context)
// In development with vite-node, the manifest is on-demand and will be available after rendering // In development with vite-node, the manifest is on-demand and will be available after rendering
if (process.dev && process.env.NUXT_VITE_NODE_OPTIONS) { if (import.meta.dev && process.env.NUXT_VITE_NODE_OPTIONS) {
renderer.rendererContext.updateManifest(await getClientManifest()) renderer.rendererContext.updateManifest(await getClientManifest())
} }
return `<${appRootTag} id="${appRootId}">${html}</${appRootTag}>` return `<${appRootTag} id="${appRootId}">${html}</${appRootTag}>`
@ -155,14 +155,14 @@ const getSPARenderer = lazyCachedFunction(async () => {
} }
}) })
const payloadCache = process.env.prerender ? useStorage('internal:nuxt:prerender:payload') : null const payloadCache = import.meta.prerender ? useStorage('internal:nuxt:prerender:payload') : null
const islandCache = process.env.prerender ? useStorage('internal:nuxt:prerender:island') : null const islandCache = import.meta.prerender ? useStorage('internal:nuxt:prerender:island') : null
const islandPropCache = process.env.prerender ? useStorage('internal:nuxt:prerender:island-props') : null const islandPropCache = import.meta.prerender ? useStorage('internal:nuxt:prerender:island-props') : null
async function getIslandContext (event: H3Event): Promise<NuxtIslandContext> { async function getIslandContext (event: H3Event): Promise<NuxtIslandContext> {
// TODO: Strict validation for url // TODO: Strict validation for url
let url = event.node.req.url || '' let url = event.node.req.url || ''
if (process.env.prerender && event.node.req.url && await islandPropCache!.hasItem(event.node.req.url)) { if (import.meta.prerender && event.node.req.url && await islandPropCache!.hasItem(event.node.req.url)) {
// rehydrate props from cache so we can rerender island if cache does not have it any more // rehydrate props from cache so we can rerender island if cache does not have it any more
url = await islandPropCache!.getItem(event.node.req.url) as string url = await islandPropCache!.getItem(event.node.req.url) as string
} }
@ -213,7 +213,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
? await getIslandContext(event) ? await getIslandContext(event)
: undefined : undefined
if (process.env.prerender && islandContext && event.node.req.url && await islandCache!.hasItem(event.node.req.url)) { if (import.meta.prerender && islandContext && event.node.req.url && await islandCache!.hasItem(event.node.req.url)) {
return islandCache!.getItem(event.node.req.url) as Promise<Partial<RenderResponse>> return islandCache!.getItem(event.node.req.url) as Promise<Partial<RenderResponse>>
} }
@ -225,7 +225,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
if (isRenderingPayload) { if (isRenderingPayload) {
url = url.substring(0, url.lastIndexOf('/')) || '/' url = url.substring(0, url.lastIndexOf('/')) || '/'
event.node.req.url = url event.node.req.url = url
if (process.env.prerender && await payloadCache!.hasItem(url)) { if (import.meta.prerender && await payloadCache!.hasItem(url)) {
return payloadCache!.getItem(url) as Promise<Partial<RenderResponse>> return payloadCache!.getItem(url) as Promise<Partial<RenderResponse>>
} }
} }
@ -245,7 +245,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
!!(process.env.NUXT_NO_SSR) || !!(process.env.NUXT_NO_SSR) ||
event.context.nuxt?.noSSR || event.context.nuxt?.noSSR ||
routeOptions.ssr === false || routeOptions.ssr === false ||
(process.env.prerender ? PRERENDER_NO_SSR_ROUTES.has(url) : false), (import.meta.prerender ? PRERENDER_NO_SSR_ROUTES.has(url) : false),
head, head,
error: !!ssrError, error: !!ssrError,
nuxt: undefined!, /* NuxtApp */ nuxt: undefined!, /* NuxtApp */
@ -255,9 +255,9 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
} }
// Whether we are prerendering route // Whether we are prerendering route
const _PAYLOAD_EXTRACTION = process.env.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !ssrContext.noSSR && !islandContext const _PAYLOAD_EXTRACTION = import.meta.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !ssrContext.noSSR && !islandContext
const payloadURL = _PAYLOAD_EXTRACTION ? joinURL(useRuntimeConfig().app.baseURL, url, process.env.NUXT_JSON_PAYLOADS ? '_payload.json' : '_payload.js') : undefined const payloadURL = _PAYLOAD_EXTRACTION ? joinURL(useRuntimeConfig().app.baseURL, url, process.env.NUXT_JSON_PAYLOADS ? '_payload.json' : '_payload.js') : undefined
if (process.env.prerender) { if (import.meta.prerender) {
ssrContext.payload.prerenderedAt = Date.now() ssrContext.payload.prerenderedAt = Date.now()
} }
@ -265,7 +265,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
const renderer = (process.env.NUXT_NO_SSR || ssrContext.noSSR) ? await getSPARenderer() : await getSSRRenderer() const renderer = (process.env.NUXT_NO_SSR || ssrContext.noSSR) ? await getSPARenderer() : await getSSRRenderer()
// Render 103 Early Hints // Render 103 Early Hints
if (process.env.NUXT_EARLY_HINTS && !isRenderingPayload && !process.env.prerender) { if (process.env.NUXT_EARLY_HINTS && !isRenderingPayload && !import.meta.prerender) {
const { link } = renderResourceHeaders({}, renderer.rendererContext) const { link } = renderResourceHeaders({}, renderer.rendererContext)
writeEarlyHints(event, link) writeEarlyHints(event, link)
} }
@ -291,7 +291,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
// Directly render payload routes // Directly render payload routes
if (isRenderingPayload) { if (isRenderingPayload) {
const response = renderPayloadResponse(ssrContext) const response = renderPayloadResponse(ssrContext)
if (process.env.prerender) { if (import.meta.prerender) {
await payloadCache!.setItem(url, response) await payloadCache!.setItem(url, response)
} }
return response return response
@ -428,7 +428,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
'x-powered-by': 'Nuxt' 'x-powered-by': 'Nuxt'
} }
} satisfies RenderResponse } satisfies RenderResponse
if (process.env.prerender) { if (import.meta.prerender) {
await islandCache!.setItem(`/__nuxt_island/${islandContext!.name}_${islandContext!.id}`, response) await islandCache!.setItem(`/__nuxt_island/${islandContext!.name}_${islandContext!.id}`, response)
await islandPropCache!.setItem(`/__nuxt_island/${islandContext!.name}_${islandContext!.id}`, event.node.req.url!) await islandPropCache!.setItem(`/__nuxt_island/${islandContext!.name}_${islandContext!.id}`, event.node.req.url!)
} }
@ -527,7 +527,7 @@ function renderPayloadJsonScript (opts: { id: string, ssrContext: NuxtSSRContext
function renderPayloadScript (opts: { ssrContext: NuxtSSRContext, data?: any, src?: string }): Script[] { function renderPayloadScript (opts: { ssrContext: NuxtSSRContext, data?: any, src?: string }): Script[] {
opts.data.config = opts.ssrContext.config opts.data.config = opts.ssrContext.config
const _PAYLOAD_EXTRACTION = process.env.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !opts.ssrContext.noSSR const _PAYLOAD_EXTRACTION = import.meta.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !opts.ssrContext.noSSR
if (_PAYLOAD_EXTRACTION) { if (_PAYLOAD_EXTRACTION) {
return [ return [
{ {

View File

@ -313,7 +313,7 @@ export const publicPathTemplate: NuxtTemplate = {
'}', '}',
// On server these are registered directly in packages/nuxt/src/core/runtime/nitro/renderer.ts // On server these are registered directly in packages/nuxt/src/core/runtime/nitro/renderer.ts
'if (process.client) {', 'if (import.meta.client) {',
' globalThis.__buildAssetsURL = buildAssetsURL', ' globalThis.__buildAssetsURL = buildAssetsURL',
' globalThis.__publicAssetsURL = publicAssetsURL', ' globalThis.__publicAssetsURL = publicAssetsURL',
'}' '}'

View File

@ -149,7 +149,7 @@ export const Title = defineComponent({
name: 'Title', name: 'Title',
inheritAttrs: false, inheritAttrs: false,
setup: setupForUseMeta((_, { slots }) => { setup: setupForUseMeta((_, { slots }) => {
if (process.dev) { if (import.meta.dev) {
const defaultSlot = slots.default?.() const defaultSlot = slots.default?.()
if (defaultSlot && (defaultSlot.length > 1 || typeof defaultSlot[0].children !== 'string')) { if (defaultSlot && (defaultSlot.length > 1 || typeof defaultSlot[0].children !== 'string')) {
@ -217,7 +217,7 @@ export const Style = defineComponent({
const style = { ...props } const style = { ...props }
const textContent = slots.default?.()?.[0]?.children const textContent = slots.default?.()?.[0]?.children
if (textContent) { if (textContent) {
if (process.dev && typeof textContent !== 'string') { if (import.meta.dev && typeof textContent !== 'string') {
console.error('<Style> can only take a string in its default slot.') console.error('<Style> can only take a string in its default slot.')
} }
style.children = textContent style.children = textContent

View File

@ -4,11 +4,11 @@ import { defineNuxtPlugin } from '#app/nuxt'
export default defineNuxtPlugin({ export default defineNuxtPlugin({
name: 'nuxt:head', name: 'nuxt:head',
setup (nuxtApp) { setup (nuxtApp) {
const head = process.server ? nuxtApp.ssrContext!.head : createClientHead() const head = import.meta.server ? nuxtApp.ssrContext!.head : createClientHead()
// nuxt.config appHead is set server-side within the renderer // nuxt.config appHead is set server-side within the renderer
nuxtApp.vueApp.use(head) nuxtApp.vueApp.use(head)
if (process.client) { if (import.meta.client) {
// pause dom updates until page is ready and between page transitions // pause dom updates until page is ready and between page transitions
let pauseDOMUpdates = true let pauseDOMUpdates = true
const unpauseDom = () => { const unpauseDom = () => {

View File

@ -77,7 +77,7 @@ export default defineNuxtModule<Partial<ImportsOptions>>({
// Support for importing from '#imports' // Support for importing from '#imports'
addTemplate({ addTemplate({
filename: 'imports.mjs', filename: 'imports.mjs',
getContents: async () => await ctx.toExports() + '\nif (process.dev) { console.warn("[nuxt] `#imports` should be transformed with real imports. There seems to be something wrong with the imports plugin.") }' getContents: async () => await ctx.toExports() + '\nif (import.meta.dev) { console.warn("[nuxt] `#imports` should be transformed with real imports. There seems to be something wrong with the imports plugin.") }'
}) })
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports') nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')

View File

@ -52,7 +52,7 @@ const warnRuntimeUsage = (method: string) =>
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
export const definePageMeta = (meta: PageMeta): void => { export const definePageMeta = (meta: PageMeta): void => {
if (process.dev) { if (import.meta.dev) {
const component = getCurrentInstance()?.type const component = getCurrentInstance()?.type
try { try {
const isRouteComponent = component && useRoute().matched.some(p => Object.values(p.components || {}).includes(component)) const isRouteComponent = component && useRoute().matched.some(p => Object.values(p.components || {}).includes(component))

View File

@ -5,7 +5,7 @@ import { devPagesDir } from '#build/nuxt.config.mjs'
export default defineComponent({ export default defineComponent({
name: 'NuxtPage', name: 'NuxtPage',
setup (_, props) { setup (_, props) {
if (process.dev) { if (import.meta.dev) {
console.warn(`Create a Vue component in the \`${devPagesDir}/\` directory to enable \`<NuxtPage>\``) console.warn(`Create a Vue component in the \`${devPagesDir}/\` directory to enable \`<NuxtPage>\``)
} }
return () => props.slots.default?.() return () => props.slots.default?.()

View File

@ -51,24 +51,24 @@ export default defineComponent({
return () => { return () => {
return h(RouterView, { name: props.name, route: props.route, ...attrs }, { return h(RouterView, { name: props.name, route: props.route, ...attrs }, {
default: (routeProps: RouterViewSlotProps) => { default: (routeProps: RouterViewSlotProps) => {
const isRenderingNewRouteInOldFork = process.client && haveParentRoutesRendered(forkRoute, routeProps.route, routeProps.Component) const isRenderingNewRouteInOldFork = import.meta.client && haveParentRoutesRendered(forkRoute, routeProps.route, routeProps.Component)
const hasSameChildren = process.client && forkRoute && forkRoute.matched.length === routeProps.route.matched.length const hasSameChildren = import.meta.client && forkRoute && forkRoute.matched.length === routeProps.route.matched.length
if (!routeProps.Component) { if (!routeProps.Component) {
// If we're rendering a `<NuxtPage>` child route on navigation to a route which lacks a child page // If we're rendering a `<NuxtPage>` child route on navigation to a route which lacks a child page
// we'll render the old vnode until the new route finishes resolving // we'll render the old vnode until the new route finishes resolving
if (process.client && vnode && !hasSameChildren) { if (import.meta.client && vnode && !hasSameChildren) {
return vnode return vnode
} }
return return
} }
// Return old vnode if we are rendering _new_ page suspense fork in _old_ layout suspense fork // Return old vnode if we are rendering _new_ page suspense fork in _old_ layout suspense fork
if (process.client && vnode && _layoutMeta && !_layoutMeta.isCurrent(routeProps.route)) { if (import.meta.client && vnode && _layoutMeta && !_layoutMeta.isCurrent(routeProps.route)) {
return vnode return vnode
} }
if (process.client && isRenderingNewRouteInOldFork && forkRoute && (!_layoutMeta || _layoutMeta?.isCurrent(forkRoute))) { if (import.meta.client && isRenderingNewRouteInOldFork && forkRoute && (!_layoutMeta || _layoutMeta?.isCurrent(forkRoute))) {
// if leaving a route with an existing child route, render the old vnode // if leaving a route with an existing child route, render the old vnode
if (hasSameChildren) { if (hasSameChildren) {
return vnode return vnode

View File

@ -57,7 +57,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
routerBase += '#' routerBase += '#'
} }
const history = routerOptions.history?.(routerBase) ?? (process.client const history = routerOptions.history?.(routerBase) ?? (import.meta.client
? (routerOptions.hashMode ? createWebHashHistory(routerBase) : createWebHistory(routerBase)) ? (routerOptions.hashMode ? createWebHashHistory(routerBase) : createWebHistory(routerBase))
: createMemoryHistory(routerBase) : createMemoryHistory(routerBase)
) )
@ -65,7 +65,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
const routes = routerOptions.routes?.(_routes) ?? _routes const routes = routerOptions.routes?.(_routes) ?? _routes
let startPosition: Parameters<RouterScrollBehavior>[2] | null let startPosition: Parameters<RouterScrollBehavior>[2] | null
const initialURL = process.server const initialURL = import.meta.server
? nuxtApp.ssrContext!.url ? nuxtApp.ssrContext!.url
: createCurrentLocation(routerBase, window.location, nuxtApp.payload.path) : createCurrentLocation(routerBase, window.location, nuxtApp.payload.path)
@ -124,7 +124,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
const error = useError() const error = useError()
try { try {
if (process.server) { if (import.meta.server) {
await router.push(initialURL) await router.push(initialURL)
} }
@ -142,7 +142,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
} }
nuxtApp._processingMiddleware = true nuxtApp._processingMiddleware = true
if (process.client || !nuxtApp.ssrContext?.islandContext) { if (import.meta.client || !nuxtApp.ssrContext?.islandContext) {
type MiddlewareDef = string | RouteMiddleware type MiddlewareDef = string | RouteMiddleware
const middlewareEntries = new Set<MiddlewareDef>([...globalMiddleware, ...nuxtApp._middleware.global]) const middlewareEntries = new Set<MiddlewareDef>([...globalMiddleware, ...nuxtApp._middleware.global])
for (const component of to.matched) { for (const component of to.matched) {
@ -161,14 +161,14 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
const middleware = typeof entry === 'string' ? nuxtApp._middleware.named[entry] || await namedMiddleware[entry]?.().then((r: any) => r.default || r) : entry const middleware = typeof entry === 'string' ? nuxtApp._middleware.named[entry] || await namedMiddleware[entry]?.().then((r: any) => r.default || r) : entry
if (!middleware) { if (!middleware) {
if (process.dev) { if (import.meta.dev) {
throw new Error(`Unknown route middleware: '${entry}'. Valid middleware: ${Object.keys(namedMiddleware).map(mw => `'${mw}'`).join(', ')}.`) throw new Error(`Unknown route middleware: '${entry}'. Valid middleware: ${Object.keys(namedMiddleware).map(mw => `'${mw}'`).join(', ')}.`)
} }
throw new Error(`Unknown route middleware: '${entry}'.`) throw new Error(`Unknown route middleware: '${entry}'.`)
} }
const result = await nuxtApp.runWithContext(() => middleware(to, from)) const result = await nuxtApp.runWithContext(() => middleware(to, from))
if (process.server || (!nuxtApp.payload.serverRendered && nuxtApp.isHydrating)) { if (import.meta.server || (!nuxtApp.payload.serverRendered && nuxtApp.isHydrating)) {
if (result === false || result instanceof Error) { if (result === false || result instanceof Error) {
const error = result || createError({ const error = result || createError({
statusCode: 404, statusCode: 404,
@ -191,20 +191,20 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
router.afterEach(async (to, _from, failure) => { router.afterEach(async (to, _from, failure) => {
delete nuxtApp._processingMiddleware delete nuxtApp._processingMiddleware
if (process.client && !nuxtApp.isHydrating && error.value) { if (import.meta.client && !nuxtApp.isHydrating && error.value) {
// Clear any existing errors // Clear any existing errors
await nuxtApp.runWithContext(clearError) await nuxtApp.runWithContext(clearError)
} }
if (process.server && failure?.type === 4 /* ErrorTypes.NAVIGATION_ABORTED */) { if (import.meta.server && failure?.type === 4 /* ErrorTypes.NAVIGATION_ABORTED */) {
return return
} }
if (to.matched.length === 0 && (!process.server || !nuxtApp.ssrContext?.islandContext)) { if (to.matched.length === 0 && (!import.meta.server || !nuxtApp.ssrContext?.islandContext)) {
await nuxtApp.runWithContext(() => showError(createError({ await nuxtApp.runWithContext(() => showError(createError({
statusCode: 404, statusCode: 404,
fatal: false, fatal: false,
statusMessage: `Page not found: ${to.fullPath}` statusMessage: `Page not found: ${to.fullPath}`
}))) })))
} else if (process.server && to.redirectedFrom && to.fullPath !== initialURL) { } else if (import.meta.server && to.redirectedFrom && to.fullPath !== initialURL) {
await nuxtApp.runWithContext(() => navigateTo(to.fullPath || '/')) await nuxtApp.runWithContext(() => navigateTo(to.fullPath || '/'))
} }
}) })

View File

@ -19,5 +19,5 @@ export const generateRouteKey = (routeProps: RouterViewSlotProps, override?: str
} }
export const wrapInKeepAlive = (props: any, children: any) => { export const wrapInKeepAlive = (props: any, children: any) => {
return { default: () => process.client && props ? h(KeepAlive, props === true ? {} : props, children) : children } return { default: () => import.meta.client && props ? h(KeepAlive, props === true ? {} : props, children) : children }
} }

View File

@ -12,7 +12,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
if (result === true) { if (result === true) {
return return
} }
if (process.server) { if (import.meta.server) {
return result return result
} }
const error = createError({ const error = createError({

View File

@ -59,7 +59,7 @@ const ByeBye = defineAsyncComponent(() => import('./../some-glob.global.vue'))
const NotDotClientComponent = defineAsyncComponent(() => import('./../some.island.vue')) const NotDotClientComponent = defineAsyncComponent(() => import('./../some.island.vue'))
const SomeIsland = defineAsyncComponent(async () => { const SomeIsland = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../some.island.vue')) return (await import('./../some.island.vue'))
} }
@ -67,7 +67,7 @@ const SomeIsland = defineAsyncComponent(async () => {
}) })
const NotToBeTreeShaken = defineAsyncComponent(async () => { const NotToBeTreeShaken = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }
@ -75,7 +75,7 @@ const NotToBeTreeShaken = defineAsyncComponent(async () => {
}) })
const { ObjectPattern } = defineAsyncComponent(async () => { const { ObjectPattern } = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }
@ -83,7 +83,7 @@ const { ObjectPattern } = defineAsyncComponent(async () => {
}) })
const { ObjectPattern: ObjectPatternDeclaration } = defineAsyncComponent(async () => { const { ObjectPattern: ObjectPatternDeclaration } = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }
@ -91,7 +91,7 @@ const { ObjectPattern: ObjectPatternDeclaration } = defineAsyncComponent(async (
}) })
const { ObjectPattern: Halllo, ButShouldNotBeTreeShaken } = defineAsyncComponent(async () => { const { ObjectPattern: Halllo, ButShouldNotBeTreeShaken } = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }
@ -100,7 +100,7 @@ const { ObjectPattern: Halllo, ButShouldNotBeTreeShaken } = defineAsyncComponent
const isThis = {} const isThis = {}
const { woooooo, What = isThis } = defineAsyncComponent(async () => { const { woooooo, What = isThis } = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }
@ -110,7 +110,7 @@ const { woooooo, What = isThis } = defineAsyncComponent(async () => {
console.log(woooooo) console.log(woooooo)
const { Deep, assignment: { Pattern = ofComponent } } = defineAsyncComponent(async () => { const { Deep, assignment: { Pattern = ofComponent } } = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }
@ -118,7 +118,7 @@ const { Deep, assignment: { Pattern = ofComponent } } = defineAsyncComponent(asy
}) })
const [FromArray] = defineAsyncComponent(async () => { const [FromArray] = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }
@ -126,7 +126,7 @@ const [FromArray] = defineAsyncComponent(async () => {
}) })
const [Please, { Dont, Doo }, That] = defineAsyncComponent(async () => { const [Please, { Dont, Doo }, That] = defineAsyncComponent(async () => {
if (process.client) { if (import.meta.client) {
return (await import('./../HelloWorld.vue')) return (await import('./../HelloWorld.vue'))
} }

View File

@ -41,6 +41,9 @@ export async function buildClient (ctx: ViteBuildContext) {
'process.env.NODE_ENV': JSON.stringify(ctx.config.mode), 'process.env.NODE_ENV': JSON.stringify(ctx.config.mode),
'process.server': false, 'process.server': false,
'process.client': true, 'process.client': true,
'process.browser': true,
'process.nitro': false,
'process.prerender': false,
'module.hot': false 'module.hot': false
}, },
optimizeDeps: { optimizeDeps: {

View File

@ -15,6 +15,7 @@ export default async (ssrContext) => {
// Workaround for stub mode // Workaround for stub mode
// https://github.com/nuxt/framework/pull/3983 // https://github.com/nuxt/framework/pull/3983
process.server = true process.server = true
import.meta.server = true
// Invalidate cache for files changed since last rendering // Invalidate cache for files changed since last rendering
const invalidates = await viteNodeFetch('/invalidates') const invalidates = await viteNodeFetch('/invalidates')

View File

@ -42,6 +42,7 @@ export async function buildServer (ctx: ViteBuildContext) {
define: { define: {
'process.server': true, 'process.server': true,
'process.client': false, 'process.client': false,
'process.browser': false,
'typeof window': '"undefined"', 'typeof window': '"undefined"',
'typeof document': '"undefined"', 'typeof document': '"undefined"',
'typeof navigator': '"undefined"', 'typeof navigator': '"undefined"',

View File

@ -146,6 +146,12 @@ export async function bundle (nuxt: Nuxt) {
await nuxt.callHook('vite:extend', ctx) await nuxt.callHook('vite:extend', ctx)
nuxt.hook('vite:extendConfig', (config) => {
config.plugins!.push(replace({
...Object.fromEntries(Object.entries(config.define!).filter(([key]) => key.startsWith('process.')).map(([key, value]) => [key.replace('process.', 'import.meta.'), JSON.stringify(value)]))
}))
})
if (!ctx.nuxt.options.dev) { if (!ctx.nuxt.options.dev) {
const chunksWithInlinedCSS = new Set<string>() const chunksWithInlinedCSS = new Set<string>()
const clientCSSMap = {} const clientCSSMap = {}

View File

@ -216,14 +216,18 @@ function getWarningIgnoreFilter (ctx: WebpackConfigContext): WarningFilter {
function getEnv (ctx: WebpackConfigContext) { function getEnv (ctx: WebpackConfigContext) {
const _env: Record<string, string | boolean> = { const _env: Record<string, string | boolean> = {
'process.env.NODE_ENV': JSON.stringify(ctx.config.mode), 'process.env.NODE_ENV': JSON.stringify(ctx.config.mode),
'process.mode': JSON.stringify(ctx.config.mode),
'process.dev': ctx.options.dev,
'process.test': isTest,
__NUXT_VERSION__: JSON.stringify(ctx.nuxt._version), __NUXT_VERSION__: JSON.stringify(ctx.nuxt._version),
'process.env.VUE_ENV': JSON.stringify(ctx.name), 'process.env.VUE_ENV': JSON.stringify(ctx.name),
'process.dev': ctx.options.dev,
'process.test': isTest,
'process.browser': ctx.isClient, 'process.browser': ctx.isClient,
'process.client': ctx.isClient, 'process.client': ctx.isClient,
'process.server': ctx.isServer 'process.server': ctx.isServer,
'import.meta.dev': ctx.options.dev,
'import.meta.test': isTest,
'import.meta.browser': ctx.isClient,
'import.meta.client': ctx.isClient,
'import.meta.server': ctx.isServer
} }
if (ctx.userConfig.aggressiveCodeRemoval) { if (ctx.userConfig.aggressiveCodeRemoval) {

View File

@ -5,7 +5,7 @@ export function esbuild (ctx: WebpackConfigContext) {
// https://esbuild.github.io/getting-started/#bundling-for-the-browser // https://esbuild.github.io/getting-started/#bundling-for-the-browser
// https://gs.statcounter.com/browser-version-market-share // https://gs.statcounter.com/browser-version-market-share
// https://nodejs.org/en/ // https://nodejs.org/en/
const target = ctx.isServer ? 'es2019' : 'chrome85' const target = ctx.isServer ? 'es2020' : 'chrome85'
// https://github.com/nuxt/nuxt/issues/13052 // https://github.com/nuxt/nuxt/issues/13052
ctx.config.optimization!.minimizer!.push(new EsbuildPlugin()) ctx.config.optimization!.minimizer!.push(new EsbuildPlugin())

View File

@ -32,7 +32,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
const serverDir = join(rootDir, '.output/server') const serverDir = join(rootDir, '.output/server')
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"64.4k"') expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"64.5k"')
const modules = await analyzeSizes('node_modules/**/*', serverDir) const modules = await analyzeSizes('node_modules/**/*', serverDir)
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2346k"') expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2346k"')

View File

@ -5,7 +5,7 @@ definePageMeta({
value: 'added in pages:extend' value: 'added in pages:extend'
}) })
if (process.server) { if (import.meta.server) {
setResponseHeader(useRequestEvent(), 'x-extend', useRoute().meta.value as string) setResponseHeader(useRequestEvent(), 'x-extend', useRoute().meta.value as string)
} }
</script> </script>

View File

@ -1,12 +1,12 @@
export function useServerOnlyComposable () { export function useServerOnlyComposable () {
if (process.client) { if (import.meta.client) {
throw new Error('this should not be called in the browser') throw new Error('this should not be called in the browser')
} }
} }
export function useClientOnlyComposable () { export function useClientOnlyComposable () {
// need to do some code that fails in node but not in the browser // need to do some code that fails in node but not in the browser
if (process.server) { if (import.meta.server) {
throw new Error('this should not be called on the server') throw new Error('this should not be called on the server')
} }
} }

View File

@ -20,7 +20,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
return false return false
} }
const pluginPath = nuxtApp.$path() const pluginPath = nuxtApp.$path()
if (process.server && !/redirect|navigate/.test(pluginPath) && to.path !== pluginPath) { if (import.meta.server && !/redirect|navigate/.test(pluginPath) && to.path !== pluginPath) {
throw new Error('plugin did not run before middleware') throw new Error('plugin did not run before middleware')
} }
}) })

View File

@ -5,7 +5,7 @@ definePageMeta({
value: 'added in pages:extend' value: 'added in pages:extend'
}) })
if (process.server) { if (import.meta.server) {
setResponseHeader(useRequestEvent(), 'x-extend', useRoute().meta.value as string) setResponseHeader(useRequestEvent(), 'x-extend', useRoute().meta.value as string)
} }
</script> </script>

View File

@ -3,7 +3,7 @@ definePageMeta({
async middleware (to, from) { async middleware (to, from) {
await new Promise(resolve => setTimeout(resolve, 1)) await new Promise(resolve => setTimeout(resolve, 1))
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (process.client && from !== to && !nuxtApp.isHydrating) { if (import.meta.client && from !== to && !nuxtApp.isHydrating) {
// trigger a loading error when navigated to via client-side navigation // trigger a loading error when navigated to via client-side navigation
await import(/* webpackIgnore: true */ /* @vite-ignore */ `some-non-exis${''}ting-module`) await import(/* webpackIgnore: true */ /* @vite-ignore */ `some-non-exis${''}ting-module`)
} }

View File

@ -3,7 +3,7 @@ definePageMeta({
layout: 'custom-async' layout: 'custom-async'
}) })
if (process.client && !useNuxtApp().isHydrating) { if (import.meta.client && !useNuxtApp().isHydrating) {
throw createError({ throw createError({
fatal: true, fatal: true,
message: '`useNuxtApp().isHydrating` is false by the time we run page setup' message: '`useNuxtApp().isHydrating` is false by the time we run page setup'

View File

@ -2,7 +2,7 @@
const state = useState(() => shallowRef({} as Record<string, any>)) const state = useState(() => shallowRef({} as Record<string, any>))
const nonDisplayedState = useState(() => shallowRef({} as Record<string, any>)) const nonDisplayedState = useState(() => shallowRef({} as Record<string, any>))
if (process.server) { if (import.meta.server) {
const r = ref('') const r = ref('')
state.value.ref = r state.value.ref = r
state.value.shallowReactive = shallowReactive({ nested: { ref: r } }) state.value.shallowReactive = shallowReactive({ nested: { ref: r } })

View File

@ -2,21 +2,21 @@
import { useCustomKeyedComposable } from '~/other-composables-folder/custom-keyed-composable' import { useCustomKeyedComposable } from '~/other-composables-folder/custom-keyed-composable'
const useLocalState = () => useState(() => { const useLocalState = () => useState(() => {
if (process.client) { console.error('running usestate') } if (import.meta.client) { console.error('running usestate') }
return { foo: Math.random() } return { foo: Math.random() }
}) })
const useStateTest1 = useLocalState() const useStateTest1 = useLocalState()
const useStateTest2 = useLocalState() const useStateTest2 = useLocalState()
const useLocalAsyncData = () => useAsyncData(() => { const useLocalAsyncData = () => useAsyncData(() => {
if (process.client) { console.error('running asyncdata') } if (import.meta.client) { console.error('running asyncdata') }
return Promise.resolve({ foo: Math.random() }) return Promise.resolve({ foo: Math.random() })
}, { transform: data => data.foo }) }, { transform: data => data.foo })
const { data: useAsyncDataTest1 } = await useLocalAsyncData() const { data: useAsyncDataTest1 } = await useLocalAsyncData()
const { data: useAsyncDataTest2 } = await useLocalAsyncData() const { data: useAsyncDataTest2 } = await useLocalAsyncData()
const useLocalLazyAsyncData = () => useLazyAsyncData(() => { const useLocalLazyAsyncData = () => useLazyAsyncData(() => {
if (process.client) { console.error('running asyncdata') } if (import.meta.client) { console.error('running asyncdata') }
return Promise.resolve({ foo: Math.random() }) return Promise.resolve({ foo: Math.random() })
}, { transform: data => data.foo }) }, { transform: data => data.foo })
const { data: useLazyAsyncDataTest1 } = await useLocalLazyAsyncData() const { data: useLazyAsyncDataTest1 } = await useLocalLazyAsyncData()
@ -24,7 +24,7 @@ const { data: useLazyAsyncDataTest2 } = await useLocalLazyAsyncData()
const useLocalFetch = () => useFetch('/api/counter', { const useLocalFetch = () => useFetch('/api/counter', {
transform: (data) => { transform: (data) => {
if (process.client) { console.error('running client-side transform') } if (import.meta.client) { console.error('running client-side transform') }
return data.count return data.count
} }
}) })

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
definePageMeta({ definePageMeta({
middleware: () => { middleware: () => {
if (process.server || useNuxtApp().isHydrating) { return } if (import.meta.server || useNuxtApp().isHydrating) { return }
return abortNavigation({ return abortNavigation({
fatal: true fatal: true
}) })

View File

@ -19,7 +19,7 @@ const links = [
const route = useRoute() const route = useRoute()
const windowState = computed(() => { const windowState = computed(() => {
console.log(route.fullPath) console.log(route.fullPath)
return process.client ? window.history.state.foo : '' return import.meta.client ? window.history.state.foo : ''
}) })
</script> </script>

View File

@ -15,18 +15,18 @@ if (called.value !== 0) {
throw new Error('Handled should have not been called') throw new Error('Handled should have not been called')
} }
if (process.server && data.value !== null) { if (import.meta.server && data.value !== null) {
throw new Error('Initial data should be null: ' + data.value) throw new Error('Initial data should be null: ' + data.value)
} }
await execute() await execute()
await execute() await execute()
if (process.server && called.value as number !== 2) { if (import.meta.server && called.value as number !== 2) {
throw new Error('Should have been called once after execute (server) but called ' + called.value + ' times') throw new Error('Should have been called once after execute (server) but called ' + called.value + ' times')
} }
if (process.client && called.value as number !== 2) { if (import.meta.client && called.value as number !== 2) {
throw new Error('Should have been called once after execute (client) but called ' + called.value + ' times') throw new Error('Should have been called once after execute (client) but called ' + called.value + ' times')
} }

View File

@ -8,7 +8,7 @@
<script setup lang="ts"> <script setup lang="ts">
let count = 0 let count = 0
let timeout = 0 let timeout = 0
const { data, refresh } = await useAsyncData(() => process.server ? Promise.resolve(1) : new Promise(resolve => setTimeout(() => resolve(++count), timeout))) const { data, refresh } = await useAsyncData(() => import.meta.server ? Promise.resolve(1) : new Promise(resolve => setTimeout(() => resolve(++count), timeout)))
if (count || data.value !== 1) { if (count || data.value !== 1) {
throw new Error('Data should be unset') throw new Error('Data should be unset')
@ -17,20 +17,20 @@ if (count || data.value !== 1) {
timeout = 100 timeout = 100
const p = refresh({ dedupe: true, _initial: false }) const p = refresh({ dedupe: true, _initial: false })
if (process.client && (count !== 0 || data.value !== 1)) { if (import.meta.client && (count !== 0 || data.value !== 1)) {
throw new Error('count should start at 0') throw new Error('count should start at 0')
} }
timeout = 0 timeout = 0
await refresh({ _initial: false }) await refresh({ _initial: false })
if (process.client && (count !== 1 || data.value !== 1)) { if (import.meta.client && (count !== 1 || data.value !== 1)) {
throw new Error('override should execute') throw new Error('override should execute')
} }
await p await p
if (process.client && (count !== 2 || data.value !== 1)) { if (import.meta.client && (count !== 2 || data.value !== 1)) {
throw new Error('cancelled promise should not affect data') throw new Error('cancelled promise should not affect data')
} }
</script> </script>

View File

@ -21,7 +21,7 @@ if (status4.value !== 'success') {
} }
const { status: status5 } = await useAsyncData(() => Promise.resolve(true), { server: false }) const { status: status5 } = await useAsyncData(() => Promise.resolve(true), { server: false })
if (process.server && status5.value !== 'idle') { if (import.meta.server && status5.value !== 'idle') {
throw new Error('status5 should be "idle" server side') throw new Error('status5 should be "idle" server side')
} }

View File

@ -1,7 +1,7 @@
export default definePayloadPlugin((nuxtApp) => { export default definePayloadPlugin((nuxtApp) => {
definePayloadReducer('BlinkingText', data => data === '<original-blink>' && '_') definePayloadReducer('BlinkingText', data => data === '<original-blink>' && '_')
definePayloadReviver('BlinkingText', () => '<revivified-blink>') definePayloadReviver('BlinkingText', () => '<revivified-blink>')
if (process.server) { if (import.meta.server) {
nuxtApp.payload.blinkable = '<original-blink>' nuxtApp.payload.blinkable = '<original-blink>'
} }
}) })

View File

@ -1,5 +1,5 @@
export default defineNitroPlugin((nitroApp) => { export default defineNitroPlugin((nitroApp) => {
if (!process.dev) { return } if (!import.meta.dev) { return }
const onError = nitroApp.h3App.options.onError! const onError = nitroApp.h3App.options.onError!
nitroApp.h3App.options.onError = (error, event) => { nitroApp.h3App.options.onError = (error, event) => {

View File

@ -4,5 +4,9 @@ export default defineVitestConfig({
test: { test: {
dir: './test/nuxt', dir: './test/nuxt',
environment: 'nuxt' environment: 'nuxt'
},
define: {
'import.meta.client': true,
'import.meta.server': false
} }
}) })