mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-31 15:50:32 +00:00
Merge branch 'main' into patch-21
This commit is contained in:
commit
586cfa5a3e
40
.github/PULL_REQUEST_TEMPLATE.md
vendored
40
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,37 +1,19 @@
|
||||
<!---
|
||||
☝️ PR title should follow conventional commits (https://conventionalcommits.org)
|
||||
|
||||
Please carefully read the contribution docs before creating a pull request
|
||||
👉 https://nuxt.com/docs/community/contribution
|
||||
-->
|
||||
|
||||
### 🔗 Linked issue
|
||||
|
||||
<!-- Please ensure there is an open issue and mention its number as #123 -->
|
||||
|
||||
### ❓ Type of change
|
||||
|
||||
<!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. -->
|
||||
|
||||
- [ ] 📖 Documentation (updates to the documentation, readme or JSdoc annotations)
|
||||
- [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
|
||||
- [ ] 👌 Enhancement (improving an existing functionality like performance)
|
||||
- [ ] ✨ New feature (a non-breaking change that adds functionality)
|
||||
- [ ] 🧹 Chore (updates to the build process or auxiliary tools and libraries)
|
||||
- [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)
|
||||
<!-- Please ensure there is an open issue and mention its number. For example, "resolves #123" -->
|
||||
|
||||
### 📚 Description
|
||||
|
||||
<!-- Describe your changes in detail -->
|
||||
<!-- Why is this change required? What problem does it solve? -->
|
||||
<!-- If it resolves an open issue, please link to the issue here. For example "Resolves #1337" -->
|
||||
<!-- Describe your changes in detail. Why is this change required? What problem does it solve? -->
|
||||
|
||||
### 📝 Checklist
|
||||
<!----------------------------------------------------------------------
|
||||
Before creating the pull request, please make sure you do the following:
|
||||
|
||||
<!-- Put an `x` in all the boxes that apply. -->
|
||||
<!-- If your change requires a documentation PR, please link it appropriately -->
|
||||
<!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- Check that there isn't already a PR that solves the problem the same way. If you find a duplicate, please help us reviewing it.
|
||||
- Read the contribution docs at https://nuxt.com/docs/community/contribution
|
||||
- Ensure that PR title follows conventional commits (https://conventionalcommits.org)
|
||||
- Update the corresponding documentation if needed.
|
||||
- Include relevant tests that fail without this PR but pass with it.
|
||||
|
||||
- [ ] I have linked an issue or discussion.
|
||||
- [ ] I have added tests (if possible).
|
||||
- [ ] I have updated the documentation accordingly.
|
||||
Thank you for contributing to Nuxt!
|
||||
----------------------------------------------------------------------->
|
||||
|
@ -99,7 +99,7 @@ Nuxt uses a custom merging strategy for the `AppConfig` within [the layers](/doc
|
||||
This strategy is implemented using a [Function Merger](https://github.com/unjs/defu#function-merger), which allows defining a custom merging strategy for every key in `app.config` that has an array as value.
|
||||
|
||||
::note
|
||||
The Function Merger should only be used in the base `app.config` of your application.
|
||||
The function merger can only be used in the extended layers and not the main `app.config` in project.
|
||||
::
|
||||
|
||||
Here's an example of how you can use:
|
||||
|
@ -87,6 +87,8 @@ console.log(layoutCustomProps.title) // I am a custom layout
|
||||
|
||||
`<NuxtLayout />` renders incoming content via `<slot />`, which is then wrapped around Vue’s `<Transition />` component to activate layout transition. For this to work as expected, it is recommended that `<NuxtLayout />` is **not** the root element of the page component.
|
||||
|
||||
::code-group
|
||||
|
||||
```vue [pages/index.vue]
|
||||
<template>
|
||||
<div>
|
||||
@ -97,13 +99,27 @@ console.log(layoutCustomProps.title) // I am a custom layout
|
||||
</template>
|
||||
```
|
||||
|
||||
```vue [layouts/custom.vue]
|
||||
<template>
|
||||
<div>
|
||||
<!-- named slot -->
|
||||
<slot name="header" />
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
::
|
||||
|
||||
:read-more{to="/docs/getting-started/transitions"}
|
||||
|
||||
## Layout's Ref
|
||||
|
||||
To get the ref of a layout component, access it through `ref.value.layoutRef`.
|
||||
|
||||
````vue [app.vue]
|
||||
::code-group
|
||||
|
||||
```vue [app.vue]
|
||||
<script setup lang="ts">
|
||||
const layout = ref()
|
||||
|
||||
@ -113,8 +129,28 @@ function logFoo () {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NuxtLayout ref="layout" />
|
||||
<NuxtLayout ref="layout">
|
||||
default layout
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
````
|
||||
```
|
||||
|
||||
```vue [layouts/default.vue]
|
||||
<script setup lang="ts">
|
||||
const foo = () => console.log('foo')
|
||||
defineExpose({
|
||||
foo
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
default layout
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
::
|
||||
|
||||
:read-more{to="/docs/guide/directory-structure/layouts"}
|
||||
|
@ -14,6 +14,10 @@ When prerendering, you can hint to Nitro to prerender additional paths, even if
|
||||
`prerenderRoutes` can only be called within the [Nuxt context](/docs/guide/going-further/nuxt-app#the-nuxt-context).
|
||||
::
|
||||
|
||||
::note
|
||||
`prerenderRoutes` has to be executed during prerendering. If the `prerenderRoutes` is used in dynamic pages/routes which are not prerendered, then it will not be executed.
|
||||
::
|
||||
|
||||
```js
|
||||
const route = useRoute()
|
||||
|
||||
|
@ -31,9 +31,7 @@ Check [Discussions](https://github.com/nuxt/nuxt/discussions) and [RFCs](https:/
|
||||
Milestone | Expected date | Notes | Description
|
||||
-------------|---------------|------------------------------------------------------------------------|-----------------------
|
||||
SEO & PWA | 2024 | [nuxt/nuxt#18395](https://github.com/nuxt/nuxt/discussions/18395) | Migrating from [nuxt-community/pwa-module](https://github.com/nuxt-community/pwa-module) for built-in SEO utils and service worker support
|
||||
Scripts | 2024 | [nuxt/nuxt#22016](https://github.com/nuxt/nuxt/discussions/22016) | Easy 3rd party script management.
|
||||
Assets | 2024 | [nuxt/nuxt#22012](https://github.com/nuxt/nuxt/discussions/22012) | Allow developers and modules to handle loading third-party assets.
|
||||
A11y | 2024 | [nuxt/nuxt#23255](https://github.com/nuxt/nuxt/issues/23255) | Accessibility hinting and utilities
|
||||
Translations | - | [nuxt/translations#4](https://github.com/nuxt/translations/discussions/4) ([request access](https://github.com/nuxt/nuxt/discussions/16054)) | A collaborative project for a stable translation process for Nuxt 3 docs. Currently pending for ideas and documentation tooling support (content v2 with remote sources).
|
||||
|
||||
## Core Modules Roadmap
|
||||
@ -42,7 +40,10 @@ In addition to the Nuxt framework, there are modules that are vital for the ecos
|
||||
|
||||
Module | Status | Nuxt Support | Repository | Description
|
||||
---------------|---------------------|--------------|------------|-------------------
|
||||
Scripts | April 2024 | 3.x | `nuxt/scripts` to be announced | Easy 3rd party script management. [nuxt/nuxt#22016](https://github.com/nuxt/nuxt/discussions/22016)
|
||||
A11y | Planned | 3.x | `nuxt/a11y` to be announced | Accessibility hinting and utilities [nuxt/nuxt#23255](https://github.com/nuxt/nuxt/issues/23255)
|
||||
Auth | Planned | 3.x | `nuxt/auth` to be announced | Nuxt 3 support is planned after session support
|
||||
Hints | Planned | 3.x | `nuxt/hints` to be announced | Guidance and suggestions for enhancing development practices
|
||||
|
||||
## Release Cycle
|
||||
|
||||
|
@ -37,9 +37,9 @@
|
||||
"@nuxt/schema": "workspace:*",
|
||||
"@nuxt/vite-builder": "workspace:*",
|
||||
"@nuxt/webpack-builder": "workspace:*",
|
||||
"rollup": "^4.13.1",
|
||||
"rollup": "^4.13.2",
|
||||
"nuxt": "workspace:*",
|
||||
"vite": "5.2.6",
|
||||
"vite": "5.2.7",
|
||||
"vue": "3.4.21",
|
||||
"magic-string": "^0.30.8"
|
||||
},
|
||||
@ -50,7 +50,7 @@
|
||||
"@nuxt/webpack-builder": "workspace:*",
|
||||
"@testing-library/vue": "8.0.3",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/node": "20.11.30",
|
||||
"@types/node": "20.12.2",
|
||||
"@types/semver": "7.5.8",
|
||||
"@vitest/coverage-v8": "1.4.0",
|
||||
"@vue/test-utils": "2.4.5",
|
||||
@ -61,7 +61,7 @@
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-standard": "17.1.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-jsdoc": "48.2.1",
|
||||
"eslint-plugin-jsdoc": "48.2.2",
|
||||
"eslint-plugin-no-only-tests": "3.1.0",
|
||||
"eslint-plugin-unicorn": "51.0.1",
|
||||
"execa": "8.0.1",
|
||||
|
@ -52,7 +52,7 @@
|
||||
"lodash-es": "4.17.21",
|
||||
"nitropack": "2.9.5",
|
||||
"unbuild": "latest",
|
||||
"vite": "5.2.6",
|
||||
"vite": "5.2.7",
|
||||
"vitest": "1.4.0",
|
||||
"webpack": "5.91.0"
|
||||
},
|
||||
|
@ -60,20 +60,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/devalue": "^2.0.2",
|
||||
"@nuxt/devtools": "^1.1.4",
|
||||
"@nuxt/devtools": "^1.1.5",
|
||||
"@nuxt/kit": "workspace:*",
|
||||
"@nuxt/schema": "workspace:*",
|
||||
"@nuxt/telemetry": "^2.5.3",
|
||||
"@nuxt/ui-templates": "^1.3.1",
|
||||
"@nuxt/vite-builder": "workspace:*",
|
||||
"@unhead/dom": "^1.9.1",
|
||||
"@unhead/ssr": "^1.9.1",
|
||||
"@unhead/vue": "^1.9.1",
|
||||
"@unhead/dom": "^1.9.3",
|
||||
"@unhead/ssr": "^1.9.3",
|
||||
"@unhead/vue": "^1.9.3",
|
||||
"@vue/shared": "^3.4.21",
|
||||
"acorn": "8.11.3",
|
||||
"c12": "^1.10.0",
|
||||
"chokidar": "^3.6.0",
|
||||
"cookie-es": "^1.0.0",
|
||||
"cookie-es": "^1.1.0",
|
||||
"defu": "^6.1.4",
|
||||
"destr": "^2.0.3",
|
||||
"devalue": "^4.3.2",
|
||||
@ -100,14 +100,14 @@
|
||||
"radix3": "^1.1.2",
|
||||
"scule": "^1.3.0",
|
||||
"std-env": "^3.7.0",
|
||||
"strip-literal": "^2.0.0",
|
||||
"strip-literal": "^2.1.0",
|
||||
"ufo": "^1.5.3",
|
||||
"ultrahtml": "^1.5.3",
|
||||
"uncrypto": "^0.1.3",
|
||||
"unctx": "^2.3.1",
|
||||
"unenv": "^1.9.0",
|
||||
"unimport": "^3.7.1",
|
||||
"unplugin": "^1.10.0",
|
||||
"unplugin": "^1.10.1",
|
||||
"unplugin-vue-router": "^0.7.0",
|
||||
"unstorage": "^1.10.2",
|
||||
"untyped": "^1.4.2",
|
||||
@ -122,7 +122,7 @@
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@vitejs/plugin-vue": "5.0.4",
|
||||
"unbuild": "latest",
|
||||
"vite": "5.2.6",
|
||||
"vite": "5.2.7",
|
||||
"vitest": "1.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -88,30 +88,32 @@ export default defineComponent({
|
||||
onMounted(() => { mounted.value = true; teleportKey.value++ })
|
||||
|
||||
function setPayload (key: string, result: NuxtIslandResponse) {
|
||||
const toRevive: Partial<NuxtIslandResponse> = {}
|
||||
if (result.props) { toRevive.props = result.props }
|
||||
if (result.slots) { toRevive.slots = result.slots }
|
||||
if (result.components) { toRevive.components = result.components }
|
||||
|
||||
nuxtApp.payload.data[key] = {
|
||||
__nuxt_island: {
|
||||
key,
|
||||
...(import.meta.server && import.meta.prerender)
|
||||
? {}
|
||||
: { params: { ...props.context, props: props.props ? JSON.stringify(props.props) : undefined } },
|
||||
result: {
|
||||
props: result.props,
|
||||
slots: result.slots,
|
||||
components: result.components
|
||||
}
|
||||
result: toRevive
|
||||
},
|
||||
...result
|
||||
}
|
||||
}
|
||||
|
||||
const payloads: Required<Pick<NuxtIslandResponse, 'slots' | 'components'>> = {
|
||||
slots: {},
|
||||
components: {}
|
||||
}
|
||||
const payloads: Partial<Pick<NuxtIslandResponse, 'slots' | 'components'>> = {}
|
||||
|
||||
if (instance.vnode.el) {
|
||||
payloads.slots = toRaw(nuxtApp.payload.data[`${props.name}_${hashId.value}`])?.slots ?? {}
|
||||
payloads.components = toRaw(nuxtApp.payload.data[`${props.name}_${hashId.value}`])?.components ?? {}
|
||||
const slots = toRaw(nuxtApp.payload.data[`${props.name}_${hashId.value}`])?.slots
|
||||
if (slots) { payloads.slots = slots }
|
||||
if (selectiveClient) {
|
||||
const components = toRaw(nuxtApp.payload.data[`${props.name}_${hashId.value}`])?.components
|
||||
if (components) { payloads.components = components }
|
||||
}
|
||||
}
|
||||
|
||||
const ssrHTML = ref<string>('')
|
||||
@ -137,12 +139,15 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
return html.replaceAll(SLOT_FALLBACK_RE, (full, slotName) => {
|
||||
if (!currentSlots.includes(slotName)) {
|
||||
return full + (payloads.slots[slotName]?.fallback || '')
|
||||
}
|
||||
return full
|
||||
})
|
||||
if (payloads.slots) {
|
||||
return html.replaceAll(SLOT_FALLBACK_RE, (full, slotName) => {
|
||||
if (!currentSlots.includes(slotName)) {
|
||||
return full + (payloads.slots?.[slotName]?.fallback || '')
|
||||
}
|
||||
return full
|
||||
})
|
||||
}
|
||||
return html
|
||||
})
|
||||
|
||||
const cHead = ref<Record<'link' | 'style', Array<Record<string, string>>>>({ link: [], style: [] })
|
||||
@ -256,24 +261,26 @@ export default defineComponent({
|
||||
teleports.push(createVNode(Teleport,
|
||||
// use different selectors for even and odd teleportKey to force trigger the teleport
|
||||
{ to: import.meta.client ? `${isKeyOdd ? 'div' : ''}[data-island-uid="${uid.value}"][data-island-slot="${slot}"]` : `uid=${uid.value};slot=${slot}` },
|
||||
{ default: () => (payloads.slots[slot].props?.length ? payloads.slots[slot].props : [{}]).map((data: any) => slots[slot]?.(data)) })
|
||||
{ default: () => (payloads.slots?.[slot].props?.length ? payloads.slots[slot].props : [{}]).map((data: any) => slots[slot]?.(data)) })
|
||||
)
|
||||
}
|
||||
}
|
||||
if (selectiveClient) {
|
||||
if (import.meta.server) {
|
||||
for (const [id, info] of Object.entries(payloads.components ?? {})) {
|
||||
const { html, slots } = info
|
||||
let replaced = html.replaceAll('data-island-uid', `data-island-uid="${uid.value}"`)
|
||||
for (const slot in slots) {
|
||||
replaced = replaced.replaceAll(`data-island-slot="${slot}">`, full => full + slots[slot])
|
||||
if (payloads.components) {
|
||||
for (const [id, info] of Object.entries(payloads.components)) {
|
||||
const { html, slots } = info
|
||||
let replaced = html.replaceAll('data-island-uid', `data-island-uid="${uid.value}"`)
|
||||
for (const slot in slots) {
|
||||
replaced = replaced.replaceAll(`data-island-slot="${slot}">`, full => full + slots[slot])
|
||||
}
|
||||
teleports.push(createVNode(Teleport, { to: `uid=${uid.value};client=${id}` }, {
|
||||
default: () => [createStaticVNode(replaced, 1)]
|
||||
}))
|
||||
}
|
||||
teleports.push(createVNode(Teleport, { to: `uid=${uid.value};client=${id}` }, {
|
||||
default: () => [createStaticVNode(replaced, 1)]
|
||||
}))
|
||||
}
|
||||
} else if (canLoadClientComponent.value) {
|
||||
for (const [id, info] of Object.entries(payloads.components ?? {})) {
|
||||
} else if (canLoadClientComponent.value && payloads.components) {
|
||||
for (const [id, info] of Object.entries(payloads.components)) {
|
||||
const { props, slots } = info
|
||||
const component = components!.get(id)!
|
||||
// use different selectors for even and odd teleportKey to force trigger the teleport
|
||||
|
@ -351,13 +351,11 @@ export function useAsyncData<
|
||||
if (instance && !instance._nuxtOnBeforeMountCbs) {
|
||||
instance._nuxtOnBeforeMountCbs = []
|
||||
const cbs = instance._nuxtOnBeforeMountCbs
|
||||
if (instance) {
|
||||
onBeforeMount(() => {
|
||||
cbs.forEach((cb) => { cb() })
|
||||
cbs.splice(0, cbs.length)
|
||||
})
|
||||
onUnmounted(() => cbs.splice(0, cbs.length))
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
cbs.forEach((cb) => { cb() })
|
||||
cbs.splice(0, cbs.length)
|
||||
})
|
||||
onUnmounted(() => cbs.splice(0, cbs.length))
|
||||
}
|
||||
|
||||
if (fetchOnServer && nuxtApp.isHydrating && (asyncData.error.value || hasCachedData())) {
|
||||
|
@ -125,18 +125,16 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
|
||||
const toPath = typeof to === 'string' ? to : (withQuery((to as RouteLocationPathRaw).path || '/', to.query || {}) + (to.hash || ''))
|
||||
|
||||
// Early open handler
|
||||
if (options?.open) {
|
||||
if (import.meta.client) {
|
||||
const { target = '_blank', windowFeatures = {} } = options.open
|
||||
if (import.meta.client && options?.open) {
|
||||
const { target = '_blank', windowFeatures = {} } = options.open
|
||||
|
||||
const features = Object.entries(windowFeatures)
|
||||
.filter(([_, value]) => value !== undefined)
|
||||
.map(([feature, value]) => `${feature.toLowerCase()}=${value}`)
|
||||
.join(', ')
|
||||
const features = Object.entries(windowFeatures)
|
||||
.filter(([_, value]) => value !== undefined)
|
||||
.map(([feature, value]) => `${feature.toLowerCase()}=${value}`)
|
||||
.join(', ')
|
||||
|
||||
open(toPath, target, features)
|
||||
return Promise.resolve()
|
||||
}
|
||||
open(toPath, target, features)
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
const isExternal = options?.external || hasProtocol(toPath, { acceptRelative: true })
|
||||
|
@ -338,7 +338,7 @@ export function createNuxtApp (options: CreateOptions) {
|
||||
}
|
||||
|
||||
// Expose runtime config
|
||||
const runtimeConfig = import.meta.server ? options.ssrContext!.runtimeConfig : reactive(nuxtApp.payload.config!)
|
||||
const runtimeConfig = import.meta.server ? options.ssrContext!.runtimeConfig : nuxtApp.payload.config!
|
||||
nuxtApp.provide('config', runtimeConfig)
|
||||
|
||||
return nuxtApp
|
||||
|
@ -37,7 +37,11 @@ export default defineNuxtPlugin((nuxtApp) => {
|
||||
nuxtApp.hook('dev:ssr-logs', (logs) => {
|
||||
for (const log of logs) {
|
||||
// deduplicate so we don't print out things that are logged on client
|
||||
if (!hydrationLogs.size || !hydrationLogs.has(JSON.stringify(log.args))) {
|
||||
try {
|
||||
if (!hydrationLogs.size || !hydrationLogs.has(JSON.stringify(log.args))) {
|
||||
logger.log(normalizeServerLog({ ...log }))
|
||||
}
|
||||
} catch {
|
||||
logger.log(normalizeServerLog({ ...log }))
|
||||
}
|
||||
}
|
||||
@ -50,7 +54,8 @@ export default defineNuxtPlugin((nuxtApp) => {
|
||||
// pass SSR logs after hydration
|
||||
nuxtApp.hooks.hook('app:suspense:resolve', async () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const logs = parse(document.getElementById('__NUXT_LOGS__')?.textContent || '[]', nuxtApp._payloadRevivers) as LogObject[]
|
||||
const content = document.getElementById('__NUXT_LOGS__')?.textContent
|
||||
const logs = content ? parse(content, nuxtApp._payloadRevivers) as LogObject[] : []
|
||||
await nuxtApp.hooks.callHook('dev:ssr-logs', logs)
|
||||
}
|
||||
})
|
||||
|
@ -109,12 +109,22 @@ export const componentsTypeTemplate = {
|
||||
: c.filePath.replace(/(?<=\w)\.(?!vue)\w+$/g, ''), { wrapper: false })}['${c.export}']`
|
||||
])
|
||||
|
||||
return `// Generated by components discovery
|
||||
return `
|
||||
interface _GlobalComponents {
|
||||
${componentTypes.map(([pascalName, type]) => ` '${pascalName}': ${type}`).join('\n')}
|
||||
${componentTypes.map(([pascalName, type]) => ` 'Lazy${pascalName}': ${type}`).join('\n')}
|
||||
}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents extends _GlobalComponents { }
|
||||
}
|
||||
|
||||
declare module '@vue/runtime-dom' {
|
||||
export interface GlobalComponents extends _GlobalComponents { }
|
||||
}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
${componentTypes.map(([pascalName, type]) => ` '${pascalName}': ${type}`).join('\n')}
|
||||
${componentTypes.map(([pascalName, type]) => ` 'Lazy${pascalName}': ${type}`).join('\n')}
|
||||
}
|
||||
export interface GlobalComponents extends _GlobalComponents { }
|
||||
}
|
||||
|
||||
${componentTypes.map(([pascalName, type]) => `export const ${pascalName}: ${type}`).join('\n')}
|
||||
|
@ -649,7 +649,7 @@ const SSR_CLIENT_TELEPORT_MARKER = /^uid=([^;]*);client=(.*)$/
|
||||
const SSR_CLIENT_SLOT_MARKER = /^island-slot=(?:[^;]*);(.*)$/
|
||||
|
||||
function getSlotIslandResponse (ssrContext: NuxtSSRContext): NuxtIslandResponse['slots'] {
|
||||
if (!ssrContext.islandContext) { return {} }
|
||||
if (!ssrContext.islandContext || !Object.keys(ssrContext.islandContext.slots).length) { return undefined }
|
||||
const response: NuxtIslandResponse['slots'] = {}
|
||||
for (const slot in ssrContext.islandContext.slots) {
|
||||
response[slot] = {
|
||||
@ -661,7 +661,7 @@ function getSlotIslandResponse (ssrContext: NuxtSSRContext): NuxtIslandResponse[
|
||||
}
|
||||
|
||||
function getClientIslandResponse (ssrContext: NuxtSSRContext): NuxtIslandResponse['components'] {
|
||||
if (!ssrContext.islandContext) { return {} }
|
||||
if (!ssrContext.islandContext || !Object.keys(ssrContext.islandContext.components).length) { return undefined }
|
||||
const response: NuxtIslandResponse['components'] = {}
|
||||
|
||||
for (const clientUid in ssrContext.islandContext.components) {
|
||||
|
@ -38,7 +38,7 @@
|
||||
"@types/file-loader": "5.0.4",
|
||||
"@types/pug": "2.0.10",
|
||||
"@types/sass-loader": "8.0.8",
|
||||
"@unhead/schema": "1.9.1",
|
||||
"@unhead/schema": "1.9.3",
|
||||
"@vitejs/plugin-vue": "5.0.4",
|
||||
"@vitejs/plugin-vue-jsx": "3.1.0",
|
||||
"@vue/compiler-core": "3.4.21",
|
||||
@ -52,13 +52,13 @@
|
||||
"unbuild": "latest",
|
||||
"unctx": "2.3.1",
|
||||
"unenv": "1.9.0",
|
||||
"vite": "5.2.6",
|
||||
"vite": "5.2.7",
|
||||
"vue": "3.4.21",
|
||||
"vue-bundle-renderer": "2.0.0",
|
||||
"vue-loader": "17.4.2",
|
||||
"vue-router": "4.3.0",
|
||||
"webpack": "5.91.0",
|
||||
"webpack-dev-middleware": "7.1.1"
|
||||
"webpack-dev-middleware": "7.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/ui-templates": "^1.3.1",
|
||||
|
@ -32,7 +32,22 @@ export default defineUntypedSchema({
|
||||
*/
|
||||
hoist: {
|
||||
$resolve: (val) => {
|
||||
const defaults = ['nitropack', 'defu', 'h3', '@unhead/vue', 'vue', 'vue-router', '@nuxt/schema', 'nuxt', 'consola', 'ofetch']
|
||||
const defaults = [
|
||||
// Nitro auto-imported/augmented dependencies
|
||||
'nitropack',
|
||||
'defu',
|
||||
'h3',
|
||||
'consola',
|
||||
'ofetch',
|
||||
// Key nuxt dependencies
|
||||
'@unhead/vue',
|
||||
'vue',
|
||||
'@vue/runtime-core',
|
||||
'@vue/runtime-dom',
|
||||
'vue-router',
|
||||
'@nuxt/schema',
|
||||
'nuxt'
|
||||
]
|
||||
return val === false ? [] : (Array.isArray(val) ? val.concat(defaults) : defaults)
|
||||
}
|
||||
},
|
||||
|
@ -58,11 +58,11 @@
|
||||
"postcss": "^8.4.38",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"std-env": "^3.7.0",
|
||||
"strip-literal": "^2.0.0",
|
||||
"strip-literal": "^2.1.0",
|
||||
"ufo": "^1.5.3",
|
||||
"unenv": "^1.9.0",
|
||||
"unplugin": "^1.10.0",
|
||||
"vite": "^5.2.6",
|
||||
"unplugin": "^1.10.1",
|
||||
"vite": "^5.2.7",
|
||||
"vite-node": "^1.4.0",
|
||||
"vite-plugin-checker": "^0.6.4",
|
||||
"vue-bundle-renderer": "^2.0.0"
|
||||
|
@ -58,13 +58,13 @@
|
||||
"time-fix-plugin": "^2.0.7",
|
||||
"ufo": "^1.5.3",
|
||||
"unenv": "^1.9.0",
|
||||
"unplugin": "^1.10.0",
|
||||
"unplugin": "^1.10.1",
|
||||
"url-loader": "^4.1.1",
|
||||
"vue-bundle-renderer": "^2.0.0",
|
||||
"vue-loader": "^17.4.2",
|
||||
"webpack": "^5.91.0",
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
"webpack-dev-middleware": "^7.1.1",
|
||||
"webpack-dev-middleware": "^7.2.0",
|
||||
"webpack-hot-middleware": "^2.26.1",
|
||||
"webpack-virtual-modules": "^0.6.1",
|
||||
"webpackbar": "^6.0.1"
|
||||
|
758
pnpm-lock.yaml
758
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -1968,14 +1968,12 @@ describe('component islands', () => {
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"components": {},
|
||||
"head": {
|
||||
"link": [],
|
||||
"style": [],
|
||||
},
|
||||
"html": "<pre data-island-uid> Route: /foo
|
||||
</pre>",
|
||||
"slots": {},
|
||||
"state": {},
|
||||
}
|
||||
`)
|
||||
@ -1993,7 +1991,6 @@ describe('component islands', () => {
|
||||
result.html = result.html.replaceAll(/ (data-island-uid|data-island-component)="([^"]*)"/g, '')
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"components": {},
|
||||
"head": {
|
||||
"link": [],
|
||||
"style": [],
|
||||
|
@ -19,7 +19,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
for (const outputDir of ['.output', '.output-inline']) {
|
||||
it('default client bundle size', async () => {
|
||||
const clientStats = await analyzeSizes('**/*.js', join(rootDir, outputDir, 'public'))
|
||||
expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"106k"')
|
||||
expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"105k"')
|
||||
expect(clientStats.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(`
|
||||
[
|
||||
"_nuxt/entry.js",
|
||||
@ -75,7 +75,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"526k"')
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"76.0k"')
|
||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"75.5k"')
|
||||
|
||||
const packages = modules.files
|
||||
.filter(m => m.endsWith('package.json'))
|
||||
|
Loading…
Reference in New Issue
Block a user