mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-23 09:00:31 +00:00
Merge branch 'main' into add-middleware
This commit is contained in:
commit
be28c16104
2
.github/workflows/autofix-docs.yml
vendored
2
.github/workflows/autofix-docs.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
2
.github/workflows/autofix.yml
vendored
2
.github/workflows/autofix.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
52
.github/workflows/benchmark.yml
vendored
52
.github/workflows/benchmark.yml
vendored
@ -1,52 +0,0 @@
|
|||||||
name: benchmark
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
# pull_request:
|
|
||||||
# paths-ignore:
|
|
||||||
# - "docs/**"
|
|
||||||
# - "*.md"
|
|
||||||
# branches:
|
|
||||||
# - main
|
|
||||||
# - "!v[0-9]*"
|
|
||||||
|
|
||||||
# https://github.com/vitejs/vite/blob/main/.github/workflows/ci.yml
|
|
||||||
env:
|
|
||||||
# 7 GiB by default on GitHub, setting to 6 GiB
|
|
||||||
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
|
||||||
NODE_OPTIONS: --max-old-space-size=6144
|
|
||||||
|
|
||||||
# Remove default permissions of GITHUB_TOKEN for security
|
|
||||||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
|
||||||
permissions: {}
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
|
|
||||||
cancel-in-progress: ${{ github.event_name != 'push' }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
run:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
||||||
- run: corepack enable
|
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
||||||
with:
|
|
||||||
node-version: lts/*
|
|
||||||
cache: "pnpm"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install
|
|
||||||
|
|
||||||
- name: Build (stub)
|
|
||||||
run: pnpm dev:prepare
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
|
|
||||||
- name: Run benchmarks
|
|
||||||
uses: CodSpeedHQ/action@513a19673a831f139e8717bf45ead67e47f00044 # v3.2.0
|
|
||||||
with:
|
|
||||||
run: pnpm vitest bench
|
|
||||||
token: ${{ secrets.CODSPEED_TOKEN }}
|
|
2
.github/workflows/changelog.yml
vendored
2
.github/workflows/changelog.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
50
.github/workflows/ci.yml
vendored
50
.github/workflows/ci.yml
vendored
@ -39,7 +39,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -78,7 +78,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
uses: github/codeql-action/init@17a820bf2e43b47be2c72b39cc905417bc1ab6d0 # v3.28.6
|
||||||
with:
|
with:
|
||||||
config: |
|
config: |
|
||||||
paths:
|
paths:
|
||||||
@ -95,7 +95,7 @@ jobs:
|
|||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
uses: github/codeql-action/analyze@17a820bf2e43b47be2c72b39cc905417bc1ab6d0 # v3.28.6
|
||||||
with:
|
with:
|
||||||
category: "/language:${{ matrix.language }}"
|
category: "/language:${{ matrix.language }}"
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -144,7 +144,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -171,7 +171,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -196,7 +196,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -213,6 +213,34 @@ jobs:
|
|||||||
- name: Check bundle size
|
- name: Check bundle size
|
||||||
run: pnpm vitest run bundle
|
run: pnpm vitest run bundle
|
||||||
|
|
||||||
|
test-benchmark:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
- run: corepack enable
|
||||||
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Restore dist cache
|
||||||
|
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: packages
|
||||||
|
|
||||||
|
- name: Run benchmarks
|
||||||
|
uses: CodSpeedHQ/action@513a19673a831f139e8717bf45ead67e47f00044 # v3.2.0
|
||||||
|
with:
|
||||||
|
run: pnpm vitest bench
|
||||||
|
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||||
|
|
||||||
test-fixtures:
|
test-fixtures:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
needs:
|
needs:
|
||||||
@ -253,7 +281,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -280,7 +308,7 @@ jobs:
|
|||||||
TEST_PAYLOAD: ${{ matrix.payload }}
|
TEST_PAYLOAD: ${{ matrix.payload }}
|
||||||
SKIP_BUNDLE_SIZE: true
|
SKIP_BUNDLE_SIZE: true
|
||||||
|
|
||||||
- uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2
|
- uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
|
||||||
if: github.event_name != 'push' && matrix.env == 'built' && matrix.builder == 'vite' && matrix.context == 'default' && matrix.os == 'ubuntu-latest' && matrix.manifest == 'manifest-on'
|
if: github.event_name != 'push' && matrix.env == 'built' && matrix.builder == 'vite' && matrix.context == 'default' && matrix.os == 'ubuntu-latest' && matrix.manifest == 'manifest-on'
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
@ -305,7 +333,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
@ -337,7 +365,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
2
.github/workflows/lint-monorepo.yml
vendored
2
.github/workflows/lint-monorepo.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
registry-url: "https://registry.npmjs.org/"
|
registry-url: "https://registry.npmjs.org/"
|
||||||
|
2
.github/workflows/scorecards.yml
vendored
2
.github/workflows/scorecards.yml
vendored
@ -68,7 +68,7 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
uses: github/codeql-action/upload-sarif@17a820bf2e43b47be2c72b39cc905417bc1ab6d0 # v3.28.6
|
||||||
if: github.repository == 'nuxt/nuxt' && success()
|
if: github.repository == 'nuxt/nuxt' && success()
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
@ -126,6 +126,26 @@ This will produce three files:
|
|||||||
|
|
||||||
The `200.html` and `404.html` might be useful for the hosting provider you are using.
|
The `200.html` and `404.html` might be useful for the hosting provider you are using.
|
||||||
|
|
||||||
|
#### Skipping Client Fallback Generation
|
||||||
|
|
||||||
|
When prerendering a client-rendered app, Nuxt will generate `index.html`, `200.html` and `404.html` files by default. However, if you need to prevent any (or all) of these files from being generated in your build, you can use the `'prerender:generate'` hook from [Nitro](/docs/getting-started/prerendering#prerendergenerate-nitro-hook).
|
||||||
|
|
||||||
|
```ts twoslash [nuxt.config.ts]
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
ssr: false,
|
||||||
|
nitro: {
|
||||||
|
hooks: {
|
||||||
|
'prerender:generate'(route) {
|
||||||
|
const routesToSkip = ['/index.html', '/200.html', '/404.html']
|
||||||
|
if (routesToSkip.includes(route.route)) {
|
||||||
|
route.skip = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
## Hybrid Rendering
|
## Hybrid Rendering
|
||||||
|
|
||||||
Hybrid rendering allows different caching rules per route using **Route Rules** and decides how the server should respond to a new request on a given URL.
|
Hybrid rendering allows different caching rules per route using **Route Rules** and decides how the server should respond to a new request on a given URL.
|
||||||
|
39
package.json
39
package.json
@ -37,13 +37,15 @@
|
|||||||
"typecheck:docs": "DOCS_TYPECHECK=true pnpm nuxi prepare && nuxt-content-twoslash verify --content-dir docs --languages html"
|
"typecheck:docs": "DOCS_TYPECHECK=true pnpm nuxi prepare && nuxt-content-twoslash verify --content-dir docs --languages html"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
"@babel/core": "7.26.7",
|
||||||
|
"@babel/helper-plugin-utils": "7.26.5",
|
||||||
"@nuxt/cli": "3.20.0",
|
"@nuxt/cli": "3.20.0",
|
||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
"@nuxt/rspack-builder": "workspace:*",
|
"@nuxt/rspack-builder": "workspace:*",
|
||||||
"@nuxt/schema": "workspace:*",
|
"@nuxt/schema": "workspace:*",
|
||||||
"@nuxt/vite-builder": "workspace:*",
|
"@nuxt/vite-builder": "workspace:*",
|
||||||
"@nuxt/webpack-builder": "workspace:*",
|
"@nuxt/webpack-builder": "workspace:*",
|
||||||
"@types/node": "22.10.7",
|
"@types/node": "22.12.0",
|
||||||
"@unhead/dom": "1.11.18",
|
"@unhead/dom": "1.11.18",
|
||||||
"@unhead/schema": "1.11.18",
|
"@unhead/schema": "1.11.18",
|
||||||
"@unhead/shared": "1.11.18",
|
"@unhead/shared": "1.11.18",
|
||||||
@ -53,27 +55,28 @@
|
|||||||
"@vue/compiler-dom": "3.5.13",
|
"@vue/compiler-dom": "3.5.13",
|
||||||
"@vue/shared": "3.5.13",
|
"@vue/shared": "3.5.13",
|
||||||
"c12": "2.0.1",
|
"c12": "2.0.1",
|
||||||
"h3": "npm:h3-nightly@1.13.1-20250110-173418-de24917",
|
"h3": "npm:h3-nightly@1.14.0-20250122-114730-3f9e703",
|
||||||
"jiti": "2.4.2",
|
"jiti": "2.4.2",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
"nitro": "npm:nitro-nightly@3.0.0-beta-28938837.19ec5395",
|
"nitro": "npm:nitro-nightly@3.0.0-beta-28968142.ce23e942",
|
||||||
"nuxt": "workspace:*",
|
"nuxt": "workspace:*",
|
||||||
"ohash": "1.1.4",
|
"ohash": "1.1.4",
|
||||||
"postcss": "8.5.1",
|
"postcss": "8.5.1",
|
||||||
"rollup": "4.31.0",
|
"rollup": "4.32.1",
|
||||||
"send": ">=1.1.0",
|
"send": ">=1.1.0",
|
||||||
"typescript": "5.7.3",
|
"typescript": "5.7.3",
|
||||||
"ufo": "1.5.4",
|
"ufo": "1.5.4",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"unhead": "1.11.18",
|
"unhead": "1.11.18",
|
||||||
"unimport": "3.14.6",
|
"unimport": "4.0.0",
|
||||||
"vite": "6.0.11",
|
"vite": "6.0.11",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arethetypeswrong/cli": "0.17.3",
|
"@arethetypeswrong/cli": "0.17.3",
|
||||||
"@babel/core": "7.26.0",
|
"@babel/core": "7.26.7",
|
||||||
"@babel/helper-plugin-utils": "7.26.5",
|
"@babel/helper-plugin-utils": "7.26.5",
|
||||||
|
"@codspeed/vitest-plugin": "4.0.0",
|
||||||
"@nuxt/cli": "3.20.0",
|
"@nuxt/cli": "3.20.0",
|
||||||
"@nuxt/eslint-config": "0.7.5",
|
"@nuxt/eslint-config": "0.7.5",
|
||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
@ -83,11 +86,11 @@
|
|||||||
"@testing-library/vue": "8.1.0",
|
"@testing-library/vue": "8.1.0",
|
||||||
"@types/babel__core": "7.20.5",
|
"@types/babel__core": "7.20.5",
|
||||||
"@types/babel__helper-plugin-utils": "7.10.3",
|
"@types/babel__helper-plugin-utils": "7.10.3",
|
||||||
"@types/node": "22.10.7",
|
"@types/node": "22.12.0",
|
||||||
"@types/semver": "7.5.8",
|
"@types/semver": "7.5.8",
|
||||||
"@unhead/schema": "1.11.18",
|
"@unhead/schema": "1.11.18",
|
||||||
"@unhead/vue": "1.11.18",
|
"@unhead/vue": "1.11.18",
|
||||||
"@vitest/coverage-v8": "3.0.3",
|
"@vitest/coverage-v8": "3.0.4",
|
||||||
"@vue/test-utils": "2.4.6",
|
"@vue/test-utils": "2.4.6",
|
||||||
"acorn": "8.14.0",
|
"acorn": "8.14.0",
|
||||||
"autoprefixer": "10.4.20",
|
"autoprefixer": "10.4.20",
|
||||||
@ -97,29 +100,29 @@
|
|||||||
"cssnano": "7.0.6",
|
"cssnano": "7.0.6",
|
||||||
"destr": "2.0.3",
|
"destr": "2.0.3",
|
||||||
"devalue": "5.1.1",
|
"devalue": "5.1.1",
|
||||||
"eslint": "9.18.0",
|
"eslint": "9.19.0",
|
||||||
"eslint-plugin-no-only-tests": "3.3.0",
|
"eslint-plugin-no-only-tests": "3.3.0",
|
||||||
"eslint-plugin-perfectionist": "4.7.0",
|
"eslint-plugin-perfectionist": "4.7.0",
|
||||||
"eslint-typegen": "1.0.0",
|
"eslint-typegen": "1.0.0",
|
||||||
"estree-walker": "3.0.3",
|
"estree-walker": "3.0.3",
|
||||||
"h3": "npm:h3-nightly@1.13.1-20250110-173418-de24917",
|
"h3": "npm:h3-nightly@1.14.0-20250122-114730-3f9e703",
|
||||||
"happy-dom": "16.7.1",
|
"happy-dom": "16.7.3",
|
||||||
"installed-check": "9.3.0",
|
"installed-check": "9.3.0",
|
||||||
"jiti": "2.4.2",
|
"jiti": "2.4.2",
|
||||||
"knip": "5.42.2",
|
"knip": "5.43.6",
|
||||||
"magic-string": "0.30.17",
|
"magic-string": "0.30.17",
|
||||||
"markdownlint-cli": "0.43.0",
|
"markdownlint-cli": "0.44.0",
|
||||||
"memfs": "4.17.0",
|
"memfs": "4.17.0",
|
||||||
"nitro": "npm:nitro-nightly@3.0.0-beta-28938837.19ec5395",
|
"nitro": "npm:nitro-nightly@3.0.0-beta-28968142.ce23e942",
|
||||||
"nuxt": "workspace:*",
|
"nuxt": "workspace:*",
|
||||||
"nuxt-content-twoslash": "0.1.2",
|
"nuxt-content-twoslash": "0.1.2",
|
||||||
"ofetch": "1.4.1",
|
"ofetch": "1.4.1",
|
||||||
"pathe": "2.0.2",
|
"pathe": "2.0.2",
|
||||||
"pkg-pr-new": "0.0.39",
|
"pkg-pr-new": "0.0.39",
|
||||||
"playwright-core": "1.49.1",
|
"playwright-core": "1.50.0",
|
||||||
"rollup": "4.31.0",
|
"rollup": "4.32.1",
|
||||||
"semver": "7.6.3",
|
"semver": "7.6.3",
|
||||||
"sherif": "1.1.1",
|
"sherif": "1.2.0",
|
||||||
"std-env": "3.8.0",
|
"std-env": "3.8.0",
|
||||||
"tinyexec": "0.3.2",
|
"tinyexec": "0.3.2",
|
||||||
"tinyglobby": "0.2.10",
|
"tinyglobby": "0.2.10",
|
||||||
@ -127,7 +130,7 @@
|
|||||||
"typescript": "5.7.3",
|
"typescript": "5.7.3",
|
||||||
"ufo": "1.5.4",
|
"ufo": "1.5.4",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"vitest": "3.0.3",
|
"vitest": "3.0.4",
|
||||||
"vitest-environment-nuxt": "1.0.1",
|
"vitest-environment-nuxt": "1.0.1",
|
||||||
"vue": "3.5.13",
|
"vue": "3.5.13",
|
||||||
"vue-tsc": "2.2.0",
|
"vue-tsc": "2.2.0",
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
"test:attw": "attw --pack"
|
"test:attw": "attw --pack"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/schema": "workspace:*",
|
|
||||||
"c12": "^2.0.1",
|
"c12": "^2.0.1",
|
||||||
"consola": "^3.4.0",
|
"consola": "^3.4.0",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
@ -46,19 +45,20 @@
|
|||||||
"std-env": "^3.8.0",
|
"std-env": "^3.8.0",
|
||||||
"ufo": "^1.5.4",
|
"ufo": "^1.5.4",
|
||||||
"unctx": "^2.4.1",
|
"unctx": "^2.4.1",
|
||||||
"unimport": "^3.14.6",
|
"unimport": "^4.0.0",
|
||||||
"untyped": "^1.5.2"
|
"untyped": "^1.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rspack/core": "1.2.0",
|
"@nuxt/schema": "workspace:*",
|
||||||
|
"@rspack/core": "1.2.2",
|
||||||
"@types/semver": "7.5.8",
|
"@types/semver": "7.5.8",
|
||||||
"nitro": "npm:nitro-nightly@3.0.0-beta-28938837.19ec5395",
|
"nitro": "npm:nitro-nightly@3.0.0-beta-28968142.ce23e942",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"vite": "6.0.11",
|
"vite": "6.0.11",
|
||||||
"vitest": "3.0.3",
|
"vitest": "3.0.4",
|
||||||
"webpack": "5.97.1"
|
"webpack": "5.97.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { kebabCase, pascalCase } from 'scule'
|
import { kebabCase, pascalCase } from 'scule'
|
||||||
import type { Component, ComponentsDir } from '@nuxt/schema'
|
import type { Component, ComponentsDir } from '@nuxt/schema'
|
||||||
import { useNuxt } from './context'
|
import { useNuxt } from './context'
|
||||||
import { checkNuxtVersion } from './compatibility'
|
|
||||||
import { logger } from './logger'
|
import { logger } from './logger'
|
||||||
import { MODE_RE } from './utils'
|
import { MODE_RE } from './utils'
|
||||||
|
|
||||||
@ -10,9 +9,6 @@ import { MODE_RE } from './utils'
|
|||||||
*/
|
*/
|
||||||
export function addComponentsDir (dir: ComponentsDir, opts: { prepend?: boolean } = {}) {
|
export function addComponentsDir (dir: ComponentsDir, opts: { prepend?: boolean } = {}) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
if (!checkNuxtVersion('>=2.13', nuxt)) {
|
|
||||||
throw new Error(`\`addComponentsDir\` requires Nuxt 2.13 or higher.`)
|
|
||||||
}
|
|
||||||
nuxt.options.components ||= []
|
nuxt.options.components ||= []
|
||||||
dir.priority ||= 0
|
dir.priority ||= 0
|
||||||
nuxt.hook('components:dirs', (dirs) => { dirs[opts.prepend ? 'unshift' : 'push'](dir) })
|
nuxt.hook('components:dirs', (dirs) => { dirs[opts.prepend ? 'unshift' : 'push'](dir) })
|
||||||
@ -27,10 +23,6 @@ export type AddComponentOptions = { name: string, filePath: string } & Partial<E
|
|||||||
*/
|
*/
|
||||||
export function addComponent (opts: AddComponentOptions) {
|
export function addComponent (opts: AddComponentOptions) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
if (!checkNuxtVersion('>=2.13', nuxt)) {
|
|
||||||
throw new Error(`\`addComponent\` requires Nuxt 2.13 or higher.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
nuxt.options.components ||= []
|
nuxt.options.components ||= []
|
||||||
|
|
||||||
if (!opts.mode) {
|
if (!opts.mode) {
|
||||||
|
@ -1,27 +1,21 @@
|
|||||||
import { existsSync } from 'node:fs'
|
import { existsSync } from 'node:fs'
|
||||||
|
import { pathToFileURL } from 'node:url'
|
||||||
import type { JSValue } from 'untyped'
|
import type { JSValue } from 'untyped'
|
||||||
import { applyDefaults } from 'untyped'
|
import { applyDefaults } from 'untyped'
|
||||||
import type { ConfigLayer, ConfigLayerMeta, LoadConfigOptions } from 'c12'
|
import type { ConfigLayer, ConfigLayerMeta, LoadConfigOptions } from 'c12'
|
||||||
import { loadConfig } from 'c12'
|
import { loadConfig } from 'c12'
|
||||||
import type { NuxtConfig, NuxtOptions } from '@nuxt/schema'
|
import type { NuxtConfig, NuxtOptions } from '@nuxt/schema'
|
||||||
import { NuxtConfigSchema } from '@nuxt/schema'
|
|
||||||
import { globby } from 'globby'
|
import { globby } from 'globby'
|
||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
import { join } from 'pathe'
|
import { join } from 'pathe'
|
||||||
|
import { isWindows } from 'std-env'
|
||||||
|
import { tryResolveModule } from '../internal/esm'
|
||||||
|
|
||||||
export interface LoadNuxtConfigOptions extends Omit<LoadConfigOptions<NuxtConfig>, 'overrides'> {
|
export interface LoadNuxtConfigOptions extends Omit<LoadConfigOptions<NuxtConfig>, 'overrides'> {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||||
overrides?: Exclude<LoadConfigOptions<NuxtConfig>['overrides'], Promise<any> | Function>
|
overrides?: Exclude<LoadConfigOptions<NuxtConfig>['overrides'], Promise<any> | Function>
|
||||||
}
|
}
|
||||||
|
|
||||||
const layerSchemaKeys = ['future', 'srcDir', 'rootDir', 'serverDir', 'dir']
|
|
||||||
const layerSchema = Object.create(null)
|
|
||||||
for (const key of layerSchemaKeys) {
|
|
||||||
if (key in NuxtConfigSchema) {
|
|
||||||
layerSchema[key] = NuxtConfigSchema[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
|
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
|
||||||
// Automatically detect and import layers from `~~/layers/` directory
|
// Automatically detect and import layers from `~~/layers/` directory
|
||||||
opts.overrides = defu(opts.overrides, {
|
opts.overrides = defu(opts.overrides, {
|
||||||
@ -54,6 +48,16 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
|
|||||||
nuxtConfig.buildDir = join(nuxtConfig.rootDir!, 'node_modules/.cache/nuxt/.nuxt')
|
nuxtConfig.buildDir = join(nuxtConfig.rootDir!, 'node_modules/.cache/nuxt/.nuxt')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NuxtConfigSchema = await loadNuxtSchema(nuxtConfig.rootDir || cwd || process.cwd())
|
||||||
|
|
||||||
|
const layerSchemaKeys = ['future', 'srcDir', 'rootDir', 'serverDir', 'dir']
|
||||||
|
const layerSchema = Object.create(null)
|
||||||
|
for (const key of layerSchemaKeys) {
|
||||||
|
if (key in NuxtConfigSchema) {
|
||||||
|
layerSchema[key] = NuxtConfigSchema[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const _layers: ConfigLayer<NuxtConfig, ConfigLayerMeta>[] = []
|
const _layers: ConfigLayer<NuxtConfig, ConfigLayerMeta>[] = []
|
||||||
const processedLayers = new Set<string>()
|
const processedLayers = new Set<string>()
|
||||||
for (const layer of layers) {
|
for (const layer of layers) {
|
||||||
@ -89,3 +93,13 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
|
|||||||
// Resolve and apply defaults
|
// Resolve and apply defaults
|
||||||
return await applyDefaults(NuxtConfigSchema, nuxtConfig as NuxtConfig & Record<string, JSValue>) as unknown as NuxtOptions
|
return await applyDefaults(NuxtConfigSchema, nuxtConfig as NuxtConfig & Record<string, JSValue>) as unknown as NuxtOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadNuxtSchema (cwd: string) {
|
||||||
|
const paths = [cwd]
|
||||||
|
const nuxtPath = await tryResolveModule('nuxt', cwd) ?? await tryResolveModule('nuxt-nightly', cwd)
|
||||||
|
if (nuxtPath) {
|
||||||
|
paths.unshift(nuxtPath)
|
||||||
|
}
|
||||||
|
const schemaPath = await tryResolveModule('@nuxt/schema', paths) ?? '@nuxt/schema'
|
||||||
|
return await import(isWindows ? pathToFileURL(schemaPath).href : schemaPath).then(r => r.NuxtConfigSchema)
|
||||||
|
}
|
||||||
|
76
packages/kit/src/runtime-config.test.ts
Normal file
76
packages/kit/src/runtime-config.test.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
import { useRuntimeConfig } from './runtime-config'
|
||||||
|
|
||||||
|
const { useNuxt, klona } = vi.hoisted(() => ({ useNuxt: vi.fn(), klona: vi.fn() }))
|
||||||
|
|
||||||
|
vi.mock('./context', () => ({ useNuxt }))
|
||||||
|
vi.mock('klona', () => ({ klona }))
|
||||||
|
|
||||||
|
const testCases = [
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
'should return runtime config with environment variables applied',
|
||||||
|
runtimeConfig: {
|
||||||
|
apiUrl: 'http://localhost',
|
||||||
|
authUrl: 'http://auth.com',
|
||||||
|
},
|
||||||
|
envExpansion: true,
|
||||||
|
env: {
|
||||||
|
NITRO_API_URL: 'http://example.com',
|
||||||
|
},
|
||||||
|
expected: {
|
||||||
|
apiUrl: 'http://example.com',
|
||||||
|
authUrl: 'http://auth.com',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: 'should expand environment variables in strings',
|
||||||
|
runtimeConfig: {
|
||||||
|
apiUrl: '{{BASE_URL}}/api',
|
||||||
|
mail: '{{MAIL_SCHEME}}://{{MAIL_HOST}}:{{MAIL_PORT}}',
|
||||||
|
},
|
||||||
|
envExpansion: true,
|
||||||
|
env: {
|
||||||
|
BASE_URL: 'http://example.com',
|
||||||
|
MAIL_SCHEME: 'http',
|
||||||
|
MAIL_HOST: 'localhost',
|
||||||
|
MAIL_PORT: '3366',
|
||||||
|
},
|
||||||
|
expected: {
|
||||||
|
apiUrl: 'http://example.com/api',
|
||||||
|
mail: 'http://localhost:3366',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
'should not expand environment variables if envExpansion is false',
|
||||||
|
runtimeConfig: {
|
||||||
|
apiUrl: '{{BASE_URL}}/api',
|
||||||
|
someUrl: '',
|
||||||
|
},
|
||||||
|
envExpansion: false,
|
||||||
|
env: {
|
||||||
|
BASE_URL: 'http://example1.com',
|
||||||
|
NITRO_NOT_API_URL: 'http://example2.com',
|
||||||
|
NUXT_SOME_URL: 'http://example3.com',
|
||||||
|
},
|
||||||
|
expected: {
|
||||||
|
apiUrl: '{{BASE_URL}}/api',
|
||||||
|
someUrl: 'http://example3.com',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
describe('useRuntimeConfig', () => {
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs()
|
||||||
|
})
|
||||||
|
|
||||||
|
it.each(testCases)('$description', ({ runtimeConfig, envExpansion, env, expected }) => {
|
||||||
|
useNuxt.mockReturnValue({ options: { nitro: { runtimeConfig, experimental: { envExpansion } } } })
|
||||||
|
klona.mockReturnValue(runtimeConfig)
|
||||||
|
Object.entries(env).forEach(([key, value]) => vi.stubEnv(key, value))
|
||||||
|
|
||||||
|
expect(useRuntimeConfig()).toEqual(expected)
|
||||||
|
})
|
||||||
|
})
|
@ -94,7 +94,7 @@ function applyEnv (
|
|||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
const envExpandRx = /\{\{(.*?)\}\}/g
|
const envExpandRx = /\{\{([^{}]*)\}\}/g
|
||||||
|
|
||||||
function _expandFromEnv (value: string, env: Record<string, any> = process.env) {
|
function _expandFromEnv (value: string, env: Record<string, any> = process.env) {
|
||||||
return value.replace(envExpandRx, (match, key) => {
|
return value.replace(envExpandRx, (match, key) => {
|
||||||
|
@ -2,7 +2,7 @@ import { fileURLToPath } from 'node:url'
|
|||||||
import { bench, describe } from 'vitest'
|
import { bench, describe } from 'vitest'
|
||||||
import { join, normalize } from 'pathe'
|
import { join, normalize } from 'pathe'
|
||||||
import { withoutTrailingSlash } from 'ufo'
|
import { withoutTrailingSlash } from 'ufo'
|
||||||
import { loadNuxtConfig } from '../src'
|
import { loadNuxtConfig } from '@nuxt/kit'
|
||||||
|
|
||||||
const fixtures = {
|
const fixtures = {
|
||||||
'empty directory': 'node_modules/fixture',
|
'empty directory': 'node_modules/fixture',
|
||||||
@ -16,7 +16,7 @@ describe('loadNuxtConfig', () => {
|
|||||||
for (const fixture in fixtures) {
|
for (const fixture in fixtures) {
|
||||||
const relativeDir = join('../../..', fixtures[fixture as keyof typeof fixtures])
|
const relativeDir = join('../../..', fixtures[fixture as keyof typeof fixtures])
|
||||||
const path = withoutTrailingSlash(normalize(fileURLToPath(new URL(relativeDir, import.meta.url))))
|
const path = withoutTrailingSlash(normalize(fileURLToPath(new URL(relativeDir, import.meta.url))))
|
||||||
bench(fixture, async () => {
|
bench(`loadNuxtConfig in the ${fixture}`, async () => {
|
||||||
await loadNuxtConfig({ cwd: path })
|
await loadNuxtConfig({ cwd: path })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { fileURLToPath } from 'node:url'
|
|||||||
import { afterAll, bench, describe } from 'vitest'
|
import { afterAll, bench, describe } from 'vitest'
|
||||||
import { join, normalize } from 'pathe'
|
import { join, normalize } from 'pathe'
|
||||||
import { withoutTrailingSlash } from 'ufo'
|
import { withoutTrailingSlash } from 'ufo'
|
||||||
import { loadNuxt, writeTypes } from '../src'
|
import { loadNuxt, writeTypes } from '@nuxt/kit'
|
||||||
|
|
||||||
describe('writeTypes', async () => {
|
describe('writeTypes', async () => {
|
||||||
const relativeDir = join('../../..', 'test/fixtures/basic-types')
|
const relativeDir = join('../../..', 'test/fixtures/basic-types')
|
||||||
@ -13,7 +13,7 @@ describe('writeTypes', async () => {
|
|||||||
await nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
bench('write types', async () => {
|
bench('writeTypes in the basic-types fixture', async () => {
|
||||||
await writeTypes(nuxt)
|
await writeTypes(nuxt)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -90,7 +90,7 @@
|
|||||||
"escape-string-regexp": "^5.0.0",
|
"escape-string-regexp": "^5.0.0",
|
||||||
"estree-walker": "^3.0.3",
|
"estree-walker": "^3.0.3",
|
||||||
"globby": "^14.0.2",
|
"globby": "^14.0.2",
|
||||||
"h3": "npm:h3-nightly@1.13.1-20250110-173418-de24917",
|
"h3": "npm:h3-nightly@1.14.0-20250122-114730-3f9e703",
|
||||||
"hookable": "^5.5.3",
|
"hookable": "^5.5.3",
|
||||||
"ignore": "^7.0.3",
|
"ignore": "^7.0.3",
|
||||||
"impound": "^0.2.0",
|
"impound": "^0.2.0",
|
||||||
@ -100,8 +100,8 @@
|
|||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
"mlly": "^1.7.4",
|
"mlly": "^1.7.4",
|
||||||
"nanotar": "^0.2.0",
|
"nanotar": "^0.2.0",
|
||||||
"nitro": "npm:nitro-nightly@3.0.0-beta-28938837.19ec5395",
|
"nitro": "npm:nitro-nightly@3.0.0-beta-28968142.ce23e942",
|
||||||
"nypm": "^0.5.0",
|
"nypm": "^0.5.2",
|
||||||
"ofetch": "^1.4.1",
|
"ofetch": "^1.4.1",
|
||||||
"ohash": "^1.1.4",
|
"ohash": "^1.1.4",
|
||||||
"pathe": "^2.0.2",
|
"pathe": "^2.0.2",
|
||||||
@ -119,9 +119,9 @@
|
|||||||
"unctx": "^2.4.1",
|
"unctx": "^2.4.1",
|
||||||
"unenv": "^1.10.0",
|
"unenv": "^1.10.0",
|
||||||
"unhead": "^1.11.18",
|
"unhead": "^1.11.18",
|
||||||
"unimport": "^3.14.6",
|
"unimport": "^4.0.0",
|
||||||
"unplugin": "^2.1.2",
|
"unplugin": "^2.1.2",
|
||||||
"unplugin-vue-router": "^0.11.0",
|
"unplugin-vue-router": "^0.11.2",
|
||||||
"unstorage": "^1.14.4",
|
"unstorage": "^1.14.4",
|
||||||
"untyped": "^1.5.2",
|
"untyped": "^1.5.2",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
@ -131,13 +131,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/scripts": "0.9.5",
|
"@nuxt/scripts": "0.9.5",
|
||||||
"@parcel/watcher": "2.5.0",
|
"@parcel/watcher": "2.5.1",
|
||||||
"@types/estree": "1.0.6",
|
"@types/estree": "1.0.6",
|
||||||
"@vitejs/plugin-vue": "5.2.1",
|
"@vitejs/plugin-vue": "5.2.1",
|
||||||
"@vue/compiler-sfc": "3.5.13",
|
"@vue/compiler-sfc": "3.5.13",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"vite": "6.0.11",
|
"vite": "6.0.11",
|
||||||
"vitest": "3.0.3"
|
"vitest": "3.0.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@parcel/watcher": "^2.1.0",
|
"@parcel/watcher": "^2.1.0",
|
||||||
|
@ -132,10 +132,11 @@ export default defineComponent({
|
|||||||
ssrHTML.value = getFragmentHTML(instance.vnode.el, true)?.join('') || ''
|
ssrHTML.value = getFragmentHTML(instance.vnode.el, true)?.join('') || ''
|
||||||
const key = `${props.name}_${hashId.value}`
|
const key = `${props.name}_${hashId.value}`
|
||||||
nuxtApp.payload.data[key] ||= {}
|
nuxtApp.payload.data[key] ||= {}
|
||||||
nuxtApp.payload.data[key].html = ssrHTML.value
|
// clear all data-island-uid to avoid conflicts when saving into payloads
|
||||||
|
nuxtApp.payload.data[key].html = ssrHTML.value.replaceAll(new RegExp(`data-island-uid="${ssrHTML.value.match(SSR_UID_RE)?.[1] || ''}"`, 'g'), `data-island-uid=""`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const uid = ref<string>(ssrHTML.value.match(SSR_UID_RE)?.[1] ?? getId())
|
const uid = ref<string>(ssrHTML.value.match(SSR_UID_RE)?.[1] || getId())
|
||||||
const availableSlots = computed(() => [...ssrHTML.value.matchAll(SLOTNAME_RE)].map(m => m[1]))
|
const availableSlots = computed(() => [...ssrHTML.value.matchAll(SLOTNAME_RE)].map(m => m[1]))
|
||||||
const html = computed(() => {
|
const html = computed(() => {
|
||||||
const currentSlots = Object.keys(slots)
|
const currentSlots = Object.keys(slots)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import type { DefineComponent, MaybeRef, VNode } from 'vue'
|
import type { DefineComponent, MaybeRef, VNode } from 'vue'
|
||||||
import { Suspense, Transition, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, ref, unref } from 'vue'
|
import { Suspense, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, ref, unref } from 'vue'
|
||||||
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
|
|
||||||
import type { PageMeta } from '../../pages/runtime/composables'
|
import type { PageMeta } from '../../pages/runtime/composables'
|
||||||
|
|
||||||
import { useRoute, useRouter } from '../composables/router'
|
import { useRoute, useRouter } from '../composables/router'
|
||||||
import { useNuxtApp } from '../nuxt'
|
import { useNuxtApp } from '../nuxt'
|
||||||
import { _wrapIf } from './utils'
|
import { _wrapInTransition } from './utils'
|
||||||
import { LayoutMetaSymbol, PageRouteSymbol } from './injections'
|
import { LayoutMetaSymbol, PageRouteSymbol } from './injections'
|
||||||
|
|
||||||
// @ts-expect-error virtual file
|
// @ts-expect-error virtual file
|
||||||
@ -80,7 +80,7 @@ export default defineComponent({
|
|||||||
const transitionProps = route.meta.layoutTransition ?? defaultLayoutTransition
|
const transitionProps = route.meta.layoutTransition ?? defaultLayoutTransition
|
||||||
|
|
||||||
// We avoid rendering layout transition if there is no layout to render
|
// We avoid rendering layout transition if there is no layout to render
|
||||||
return _wrapIf(Transition, hasLayout && transitionProps, {
|
return _wrapInTransition(hasLayout && transitionProps, {
|
||||||
default: () => h(Suspense, { suspensible: true, onResolve: () => { nextTick(done) } }, {
|
default: () => h(Suspense, { suspensible: true, onResolve: () => { nextTick(done) } }, {
|
||||||
default: () => h(
|
default: () => h(
|
||||||
LayoutProvider,
|
LayoutProvider,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { createStaticVNode, h } from 'vue'
|
import { Transition, createStaticVNode, h } from 'vue'
|
||||||
import type { Component, RendererNode, VNode } from 'vue'
|
import type { RendererNode, VNode } from 'vue'
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
import { isString, isPromise, isArray, isObject } from '@vue/shared'
|
import { isString, isPromise, isArray, isObject } from '@vue/shared'
|
||||||
import type { RouteLocationNormalized } from 'vue-router'
|
import type { RouteLocationNormalized } from 'vue-router'
|
||||||
@ -10,9 +10,8 @@ import { START_LOCATION } from '#build/pages'
|
|||||||
* Internal utility
|
* Internal utility
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export const _wrapIf = (component: Component, props: any, slots: any) => {
|
export const _wrapInTransition = (props: any, children: any) => {
|
||||||
props = props === true ? {} : props
|
return { default: () => import.meta.client && props ? h(Transition, props === true ? {} : props, children) : children.default?.() }
|
||||||
return { default: () => props ? h(component, props, slots) : slots.default?.() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ROUTE_KEY_PARENTHESES_RE = /(:\w+)\([^)]+\)/g
|
const ROUTE_KEY_PARENTHESES_RE = /(:\w+)\([^)]+\)/g
|
||||||
|
@ -18,7 +18,7 @@ export const useRouter: typeof _useRouter = () => {
|
|||||||
|
|
||||||
/** @since 3.0.0 */
|
/** @since 3.0.0 */
|
||||||
export const useRoute: typeof _useRoute = () => {
|
export const useRoute: typeof _useRoute = () => {
|
||||||
if (import.meta.dev && isProcessingMiddleware()) {
|
if (import.meta.dev && !getCurrentInstance() && 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()) {
|
||||||
|
@ -108,6 +108,18 @@ function createWatcher () {
|
|||||||
ignored: [isIgnored, /[\\/]node_modules[\\/]/],
|
ignored: [isIgnored, /[\\/]node_modules[\\/]/],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const restartPaths = new Set<string>()
|
||||||
|
const srcDir = nuxt.options.srcDir.replace(/\/?$/, '/')
|
||||||
|
for (const pattern of nuxt.options.watch) {
|
||||||
|
if (typeof pattern !== 'string') { continue }
|
||||||
|
const path = resolve(nuxt.options.srcDir, pattern)
|
||||||
|
if (!path.startsWith(srcDir)) {
|
||||||
|
restartPaths.add(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watcher.add([...restartPaths])
|
||||||
|
|
||||||
watcher.on('all', (event, path) => {
|
watcher.on('all', (event, path) => {
|
||||||
if (event === 'all' || event === 'ready' || event === 'error' || event === 'raw') {
|
if (event === 'all' || event === 'ready' || event === 'error' || event === 'raw') {
|
||||||
return
|
return
|
||||||
|
@ -83,7 +83,6 @@ const nightlies = {
|
|||||||
|
|
||||||
export const keyDependencies = [
|
export const keyDependencies = [
|
||||||
'@nuxt/kit',
|
'@nuxt/kit',
|
||||||
'@nuxt/schema',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
let warnedAboutCompatDate = false
|
let warnedAboutCompatDate = false
|
||||||
@ -414,7 +413,7 @@ async function initNuxt (nuxt: Nuxt) {
|
|||||||
await nuxt.callHook('modules:before')
|
await nuxt.callHook('modules:before')
|
||||||
const modulesToInstall = new Map<string | NuxtModule, Record<string, any>>()
|
const modulesToInstall = new Map<string | NuxtModule, Record<string, any>>()
|
||||||
|
|
||||||
const watchedPaths = new Set<string>()
|
const modulePaths = new Set<string>()
|
||||||
const specifiedModules = new Set<string>()
|
const specifiedModules = new Set<string>()
|
||||||
|
|
||||||
for (const _mod of nuxt.options.modules) {
|
for (const _mod of nuxt.options.modules) {
|
||||||
@ -432,13 +431,15 @@ async function initNuxt (nuxt: Nuxt) {
|
|||||||
`${modulesDir}/*/index{${nuxt.options.extensions.join(',')}}`,
|
`${modulesDir}/*/index{${nuxt.options.extensions.join(',')}}`,
|
||||||
])
|
])
|
||||||
for (const mod of layerModules) {
|
for (const mod of layerModules) {
|
||||||
watchedPaths.add(mod)
|
modulePaths.add(mod)
|
||||||
if (specifiedModules.has(mod)) { continue }
|
if (specifiedModules.has(mod)) { continue }
|
||||||
specifiedModules.add(mod)
|
specifiedModules.add(mod)
|
||||||
modulesToInstall.set(mod, {})
|
modulesToInstall.set(mod, {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nuxt.options.watch.push(...modulePaths)
|
||||||
|
|
||||||
// Register user and then ad-hoc modules
|
// Register user and then ad-hoc modules
|
||||||
for (const key of ['modules', '_modules'] as const) {
|
for (const key of ['modules', '_modules'] as const) {
|
||||||
for (const item of nuxt.options[key as 'modules']) {
|
for (const item of nuxt.options[key as 'modules']) {
|
||||||
@ -661,7 +662,7 @@ export default defineNuxtPlugin({
|
|||||||
nuxt.hooks.hook('builder:watch', (event, relativePath) => {
|
nuxt.hooks.hook('builder:watch', (event, relativePath) => {
|
||||||
const path = resolve(nuxt.options.srcDir, relativePath)
|
const path = resolve(nuxt.options.srcDir, relativePath)
|
||||||
// Local module patterns
|
// Local module patterns
|
||||||
if (watchedPaths.has(path)) {
|
if (modulePaths.has(path)) {
|
||||||
return nuxt.callHook('restart', { hard: true })
|
return nuxt.callHook('restart', { hard: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ export function walk (ast: Program | Node, callback: Partial<WalkOptions>) {
|
|||||||
|
|
||||||
export function parseAndWalk (code: string, sourceFilename: string, callback: WalkerCallback): Program
|
export function parseAndWalk (code: string, sourceFilename: string, callback: WalkerCallback): Program
|
||||||
export function parseAndWalk (code: string, sourceFilename: string, object: Partial<WalkOptions>): Program
|
export function parseAndWalk (code: string, sourceFilename: string, object: Partial<WalkOptions>): Program
|
||||||
export function parseAndWalk (code: string, _sourceFilename: string, callback: Partial<WalkOptions> | WalkerCallback) {
|
export function parseAndWalk (code: string, sourceFilename: string, callback: Partial<WalkOptions> | WalkerCallback) {
|
||||||
const ast = parse (code, { sourceType: 'module', ecmaVersion: 'latest', locations: true })
|
const ast = parse (code, { sourceType: 'module', ecmaVersion: 'latest', locations: true, sourceFile: sourceFilename })
|
||||||
walk(ast, typeof callback === 'function' ? { enter: callback } : callback)
|
walk(ast, typeof callback === 'function' ? { enter: callback } : callback)
|
||||||
return ast
|
return ast
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Fragment, Suspense, Transition, defineComponent, h, inject, nextTick, ref, watch } from 'vue'
|
import { Fragment, Suspense, defineComponent, h, inject, nextTick, ref, watch } from 'vue'
|
||||||
import type { KeepAliveProps, TransitionProps, VNode } from 'vue'
|
import type { KeepAliveProps, TransitionProps, VNode } from 'vue'
|
||||||
import { RouterView } from 'vue-router'
|
import { RouterView } from 'vue-router'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
@ -9,7 +9,7 @@ import type { RouterViewSlotProps } from './utils'
|
|||||||
import { RouteProvider } from '#app/components/route-provider'
|
import { RouteProvider } from '#app/components/route-provider'
|
||||||
import { useNuxtApp } from '#app/nuxt'
|
import { useNuxtApp } from '#app/nuxt'
|
||||||
import { useRouter } from '#app/composables/router'
|
import { useRouter } from '#app/composables/router'
|
||||||
import { _wrapIf } from '#app/components/utils'
|
import { _wrapInTransition } from '#app/components/utils'
|
||||||
import { LayoutMetaSymbol, PageRouteSymbol } from '#app/components/injections'
|
import { LayoutMetaSymbol, PageRouteSymbol } from '#app/components/injections'
|
||||||
// @ts-expect-error virtual file
|
// @ts-expect-error virtual file
|
||||||
import { appKeepalive as defaultKeepaliveConfig, appPageTransition as defaultPageTransition } from '#build/nuxt.config.mjs'
|
import { appKeepalive as defaultKeepaliveConfig, appPageTransition as defaultPageTransition } from '#build/nuxt.config.mjs'
|
||||||
@ -101,8 +101,30 @@ export default defineComponent({
|
|||||||
nuxtApp.callHook('page:loading:end')
|
nuxtApp.callHook('page:loading:end')
|
||||||
pageLoadingEndHookAlreadyCalled = true
|
pageLoadingEndHookAlreadyCalled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
previousPageKey = key
|
previousPageKey = key
|
||||||
|
|
||||||
|
if (import.meta.server) {
|
||||||
|
vnode = h(Suspense, {
|
||||||
|
suspensible: true,
|
||||||
|
}, {
|
||||||
|
default: () => {
|
||||||
|
const providerVNode = h(RouteProvider, {
|
||||||
|
key: key || undefined,
|
||||||
|
vnode: slots.default ? h(Fragment, undefined, slots.default(routeProps)) : routeProps.Component,
|
||||||
|
route: routeProps.route,
|
||||||
|
renderKey: key || undefined,
|
||||||
|
vnodeRef: pageRef,
|
||||||
|
})
|
||||||
|
return providerVNode
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return vnode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client side rendering
|
||||||
|
|
||||||
const hasTransition = !!(props.transition ?? routeProps.route.meta.pageTransition ?? defaultPageTransition)
|
const hasTransition = !!(props.transition ?? routeProps.route.meta.pageTransition ?? defaultPageTransition)
|
||||||
const transitionProps = hasTransition && _mergeTransitionProps([
|
const transitionProps = hasTransition && _mergeTransitionProps([
|
||||||
props.transition,
|
props.transition,
|
||||||
@ -112,7 +134,7 @@ export default defineComponent({
|
|||||||
].filter(Boolean))
|
].filter(Boolean))
|
||||||
|
|
||||||
const keepaliveConfig = props.keepalive ?? routeProps.route.meta.keepalive ?? (defaultKeepaliveConfig as KeepAliveProps)
|
const keepaliveConfig = props.keepalive ?? routeProps.route.meta.keepalive ?? (defaultKeepaliveConfig as KeepAliveProps)
|
||||||
vnode = _wrapIf(Transition, hasTransition && transitionProps,
|
vnode = _wrapInTransition(hasTransition && transitionProps,
|
||||||
wrapInKeepAlive(keepaliveConfig, h(Suspense, {
|
wrapInKeepAlive(keepaliveConfig, h(Suspense, {
|
||||||
suspensible: true,
|
suspensible: true,
|
||||||
onPending: () => nuxtApp.callHook('page:start', routeProps.Component),
|
onPending: () => nuxtApp.callHook('page:start', routeProps.Component),
|
||||||
@ -134,7 +156,7 @@ export default defineComponent({
|
|||||||
trackRootNodes: hasTransition,
|
trackRootNodes: hasTransition,
|
||||||
vnodeRef: pageRef,
|
vnodeRef: pageRef,
|
||||||
})
|
})
|
||||||
if (import.meta.client && keepaliveConfig) {
|
if (keepaliveConfig) {
|
||||||
(providerVNode.type as any).name = (routeProps.Component.type as any).name || (routeProps.Component.type as any).__name || 'RouteProvider'
|
(providerVNode.type as any).name = (routeProps.Component.type as any).name || (routeProps.Component.type as any).__name || 'RouteProvider'
|
||||||
}
|
}
|
||||||
return providerVNode
|
return providerVNode
|
||||||
|
@ -11,6 +11,7 @@ import { transform } from 'esbuild'
|
|||||||
import type { Property } from 'estree'
|
import type { Property } from 'estree'
|
||||||
import type { NuxtPage } from 'nuxt/schema'
|
import type { NuxtPage } from 'nuxt/schema'
|
||||||
|
|
||||||
|
import { klona } from 'klona'
|
||||||
import { parseAndWalk, withLocations } from '../core/utils/parse'
|
import { parseAndWalk, withLocations } from '../core/utils/parse'
|
||||||
import { getLoader, uniqueBy } from '../core/utils'
|
import { getLoader, uniqueBy } from '../core/utils'
|
||||||
import { logger, toArray } from '../utils'
|
import { logger, toArray } from '../utils'
|
||||||
@ -215,7 +216,7 @@ export async function getRouteMeta (contents: string, absolutePath: string, extr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (absolutePath in metaCache && metaCache[absolutePath]) {
|
if (absolutePath in metaCache && metaCache[absolutePath]) {
|
||||||
return metaCache[absolutePath]
|
return klona(metaCache[absolutePath])
|
||||||
}
|
}
|
||||||
|
|
||||||
const loader = getLoader(absolutePath)
|
const loader = getLoader(absolutePath)
|
||||||
@ -314,7 +315,7 @@ export async function getRouteMeta (contents: string, absolutePath: string, extr
|
|||||||
}
|
}
|
||||||
|
|
||||||
metaCache[absolutePath] = extractedMeta
|
metaCache[absolutePath] = extractedMeta
|
||||||
return extractedMeta
|
return klona(extractedMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
const COLON_RE = /:/g
|
const COLON_RE = /:/g
|
||||||
|
@ -2,13 +2,13 @@ import { fileURLToPath } from 'node:url'
|
|||||||
import { bench, describe } from 'vitest'
|
import { bench, describe } from 'vitest'
|
||||||
import { normalize } from 'pathe'
|
import { normalize } from 'pathe'
|
||||||
import { withoutTrailingSlash } from 'ufo'
|
import { withoutTrailingSlash } from 'ufo'
|
||||||
import { loadNuxt } from '../src'
|
import { loadNuxt } from 'nuxt'
|
||||||
|
|
||||||
const emptyDir = withoutTrailingSlash(normalize(fileURLToPath(new URL('../../../node_modules/fixture', import.meta.url))))
|
const emptyDir = withoutTrailingSlash(normalize(fileURLToPath(new URL('../../../node_modules/fixture', import.meta.url))))
|
||||||
const basicTestFixtureDir = withoutTrailingSlash(normalize(fileURLToPath(new URL('../../../test/fixtures/basic', import.meta.url))))
|
const basicTestFixtureDir = withoutTrailingSlash(normalize(fileURLToPath(new URL('../../../test/fixtures/basic', import.meta.url))))
|
||||||
|
|
||||||
describe('loadNuxt', () => {
|
describe('loadNuxt', () => {
|
||||||
bench('empty directory', async () => {
|
bench('loadNuxt in an empty directory', async () => {
|
||||||
const nuxt = await loadNuxt({
|
const nuxt = await loadNuxt({
|
||||||
cwd: emptyDir,
|
cwd: emptyDir,
|
||||||
ready: true,
|
ready: true,
|
||||||
@ -16,7 +16,7 @@ describe('loadNuxt', () => {
|
|||||||
await nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
bench('basic test fixture', async () => {
|
bench('loadNuxt in the basic test fixture', async () => {
|
||||||
const nuxt = await loadNuxt({
|
const nuxt = await loadNuxt({
|
||||||
cwd: basicTestFixtureDir,
|
cwd: basicTestFixtureDir,
|
||||||
ready: true,
|
ready: true,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { describe, expect, it } from 'vitest'
|
import { type MockedFunction, describe, expect, it, vi } from 'vitest'
|
||||||
import { compileScript, parse } from '@vue/compiler-sfc'
|
import { compileScript, parse } from '@vue/compiler-sfc'
|
||||||
import * as Parser from 'acorn'
|
import * as Parser from 'acorn'
|
||||||
|
import { klona } from 'klona'
|
||||||
import { transform as esbuildTransform } from 'esbuild'
|
import { transform as esbuildTransform } from 'esbuild'
|
||||||
import { PageMetaPlugin } from '../src/pages/plugins/page-meta'
|
import { PageMetaPlugin } from '../src/pages/plugins/page-meta'
|
||||||
import { getRouteMeta, normalizeRoutes } from '../src/pages/utils'
|
import { getRouteMeta, normalizeRoutes } from '../src/pages/utils'
|
||||||
@ -8,6 +9,8 @@ import type { NuxtPage } from '../schema'
|
|||||||
|
|
||||||
const filePath = '/app/pages/index.vue'
|
const filePath = '/app/pages/index.vue'
|
||||||
|
|
||||||
|
vi.mock('klona', { spy: true })
|
||||||
|
|
||||||
describe('page metadata', () => {
|
describe('page metadata', () => {
|
||||||
it('should not extract metadata from empty files', async () => {
|
it('should not extract metadata from empty files', async () => {
|
||||||
expect(await getRouteMeta('', filePath)).toEqual({})
|
expect(await getRouteMeta('', filePath)).toEqual({})
|
||||||
@ -62,11 +65,20 @@ definePageMeta({ name: 'bar' })
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should use and invalidate cache', async () => {
|
it('should use and invalidate cache', async () => {
|
||||||
|
const _klona = klona as unknown as MockedFunction<typeof klona>
|
||||||
|
_klona.mockImplementation(obj => obj)
|
||||||
const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>`
|
const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>`
|
||||||
const meta = await getRouteMeta(fileContents, filePath)
|
const meta = await getRouteMeta(fileContents, filePath)
|
||||||
expect(meta === await getRouteMeta(fileContents, filePath)).toBeTruthy()
|
expect(meta === await getRouteMeta(fileContents, filePath)).toBeTruthy()
|
||||||
expect(meta === await getRouteMeta(fileContents, '/app/pages/other.vue')).toBeFalsy()
|
expect(meta === await getRouteMeta(fileContents, '/app/pages/other.vue')).toBeFalsy()
|
||||||
expect(meta === await getRouteMeta('<template><div>Hi</div></template>' + fileContents, filePath)).toBeFalsy()
|
expect(meta === await getRouteMeta('<template><div>Hi</div></template>' + fileContents, filePath)).toBeFalsy()
|
||||||
|
_klona.mockReset()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not share state between page metadata', async () => {
|
||||||
|
const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>`
|
||||||
|
const meta = await getRouteMeta(fileContents, filePath)
|
||||||
|
expect(meta === await getRouteMeta(fileContents, filePath)).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should extract serialisable metadata', async () => {
|
it('should extract serialisable metadata', async () => {
|
||||||
|
@ -834,3 +834,41 @@ describe('pages:pathToNitroGlob', () => {
|
|||||||
expect(pathToNitroGlob(path)).to.equal(expected)
|
expect(pathToNitroGlob(path)).to.equal(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('page:extends', () => {
|
||||||
|
const DYNAMIC_META_KEY = '__nuxt_dynamic_meta_key' as const
|
||||||
|
it('should preserve distinct metadata for multiple routes referencing the same file', async () => {
|
||||||
|
const files: NuxtPage[] = [
|
||||||
|
{ path: 'home', file: `pages/index.vue` },
|
||||||
|
{ path: 'home1', file: `pages/index.vue`, meta: { test: true } },
|
||||||
|
{ path: 'home2', file: `pages/index.vue`, meta: { snap: true } },
|
||||||
|
]
|
||||||
|
const vfs = Object.fromEntries(
|
||||||
|
files.map(file => [file.file, `
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
hello: 'world'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
`]),
|
||||||
|
) as Record<string, string>
|
||||||
|
await augmentPages(files, vfs)
|
||||||
|
expect(files).toEqual([
|
||||||
|
{
|
||||||
|
path: 'home',
|
||||||
|
file: `pages/index.vue`,
|
||||||
|
meta: { [DYNAMIC_META_KEY]: new Set(['meta']) },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'home1',
|
||||||
|
file: `pages/index.vue`,
|
||||||
|
meta: { [DYNAMIC_META_KEY]: new Set(['meta']), test: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'home2',
|
||||||
|
file: `pages/index.vue`,
|
||||||
|
meta: { [DYNAMIC_META_KEY]: new Set(['meta']), snap: true },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/friendly-errors-webpack-plugin": "^2.6.0",
|
"@nuxt/friendly-errors-webpack-plugin": "^2.6.0",
|
||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
"@rspack/core": "^1.2.0",
|
"@rspack/core": "^1.2.2",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"css-loader": "^7.1.2",
|
"css-loader": "^7.1.2",
|
||||||
"css-minimizer-webpack-plugin": "^7.0.0",
|
"css-minimizer-webpack-plugin": "^7.0.0",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"fork-ts-checker-webpack-plugin": "^9.0.2",
|
"fork-ts-checker-webpack-plugin": "^9.0.2",
|
||||||
"globby": "^14.0.2",
|
"globby": "^14.0.2",
|
||||||
"h3": "npm:h3-nightly@1.13.1-20250110-173418-de24917",
|
"h3": "npm:h3-nightly@1.14.0-20250122-114730-3f9e703",
|
||||||
"jiti": "^2.4.2",
|
"jiti": "^2.4.2",
|
||||||
"knitwork": "^1.2.0",
|
"knitwork": "^1.2.0",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
@ -75,7 +75,7 @@
|
|||||||
"@types/pify": "5.0.4",
|
"@types/pify": "5.0.4",
|
||||||
"@types/webpack-bundle-analyzer": "4.7.0",
|
"@types/webpack-bundle-analyzer": "4.7.0",
|
||||||
"@types/webpack-hot-middleware": "2.25.9",
|
"@types/webpack-hot-middleware": "2.25.9",
|
||||||
"rollup": "4.31.0",
|
"rollup": "4.32.1",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
|
@ -48,17 +48,17 @@
|
|||||||
"compatx": "0.1.8",
|
"compatx": "0.1.8",
|
||||||
"esbuild-loader": "4.2.2",
|
"esbuild-loader": "4.2.2",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"h3": "npm:h3-nightly@1.13.1-20250110-173418-de24917",
|
"h3": "npm:h3-nightly@1.14.0-20250122-114730-3f9e703",
|
||||||
"hookable": "5.5.3",
|
"hookable": "5.5.3",
|
||||||
"ignore": "7.0.3",
|
"ignore": "7.0.3",
|
||||||
"nitro": "npm:nitro-nightly@3.0.0-beta-28938837.19ec5395",
|
"nitro": "npm:nitro-nightly@3.0.0-beta-28968142.ce23e942",
|
||||||
"ofetch": "1.4.1",
|
"ofetch": "1.4.1",
|
||||||
"pkg-types": "1.3.1",
|
"pkg-types": "1.3.1",
|
||||||
"sass-loader": "16.0.4",
|
"sass-loader": "16.0.4",
|
||||||
"scule": "1.3.0",
|
"scule": "1.3.0",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"unctx": "2.4.1",
|
"unctx": "2.4.1",
|
||||||
"unimport": "3.14.6",
|
"unimport": "4.0.0",
|
||||||
"untyped": "1.5.2",
|
"untyped": "1.5.2",
|
||||||
"vite": "6.0.11",
|
"vite": "6.0.11",
|
||||||
"vue": "3.5.13",
|
"vue": "3.5.13",
|
||||||
|
@ -39,5 +39,13 @@ export default defineUntypedSchema({
|
|||||||
* @type {(data: { loading?: string }) => string}
|
* @type {(data: { loading?: string }) => string}
|
||||||
*/
|
*/
|
||||||
loadingTemplate,
|
loadingTemplate,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set CORS options for the dev server
|
||||||
|
* @type {typeof import('h3').H3CorsOptions}
|
||||||
|
*/
|
||||||
|
cors: {
|
||||||
|
origin: [/^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
"prerender": "pnpm build && jiti ./lib/prerender"
|
"prerender": "pnpm build && jiti ./lib/prerender"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@unocss/reset": "65.4.2",
|
"@unocss/reset": "65.4.3",
|
||||||
"beasties": "0.2.0",
|
"beasties": "0.2.0",
|
||||||
"html-validate": "9.1.3",
|
"html-validate": "9.1.3",
|
||||||
"htmlnano": "2.1.1",
|
"htmlnano": "2.1.1",
|
||||||
@ -29,7 +29,7 @@
|
|||||||
"svgo": "3.3.2",
|
"svgo": "3.3.2",
|
||||||
"tinyexec": "0.3.2",
|
"tinyexec": "0.3.2",
|
||||||
"tinyglobby": "0.2.10",
|
"tinyglobby": "0.2.10",
|
||||||
"unocss": "65.4.2",
|
"unocss": "65.4.3",
|
||||||
"vite": "6.0.11"
|
"vite": "6.0.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/schema": "workspace:*",
|
"@nuxt/schema": "workspace:*",
|
||||||
"rollup": "4.31.0",
|
"rollup": "4.32.1",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
@ -41,8 +41,9 @@
|
|||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
"esbuild": "^0.24.2",
|
"esbuild": "^0.24.2",
|
||||||
"escape-string-regexp": "^5.0.0",
|
"escape-string-regexp": "^5.0.0",
|
||||||
|
"externality": "^1.0.2",
|
||||||
"get-port-please": "^3.1.2",
|
"get-port-please": "^3.1.2",
|
||||||
"h3": "npm:h3-nightly@1.13.1-20250110-173418-de24917",
|
"h3": "npm:h3-nightly@1.14.0-20250122-114730-3f9e703",
|
||||||
"jiti": "^2.4.2",
|
"jiti": "^2.4.2",
|
||||||
"knitwork": "^1.2.0",
|
"knitwork": "^1.2.0",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
@ -56,7 +57,7 @@
|
|||||||
"unenv": "^1.10.0",
|
"unenv": "^1.10.0",
|
||||||
"unplugin": "^2.1.2",
|
"unplugin": "^2.1.2",
|
||||||
"vite": "^6.0.11",
|
"vite": "^6.0.11",
|
||||||
"vite-node": "^3.0.3",
|
"vite-node": "^3.0.4",
|
||||||
"vite-plugin-checker": "^0.8.0",
|
"vite-plugin-checker": "^0.8.0",
|
||||||
"vue-bundle-renderer": "^2.1.1"
|
"vue-bundle-renderer": "^2.1.1"
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,7 @@ import { getPort } from 'get-port-please'
|
|||||||
import { joinURL, withoutLeadingSlash } from 'ufo'
|
import { joinURL, withoutLeadingSlash } from 'ufo'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { env, nodeless } from 'unenv'
|
import { env, nodeless } from 'unenv'
|
||||||
import { appendCorsHeaders, appendCorsPreflightHeaders, defineEventHandler } from 'h3'
|
import { defineEventHandler, handleCors, setHeader } from 'h3'
|
||||||
import type { ViteConfig } from '@nuxt/schema'
|
import type { ViteConfig } from '@nuxt/schema'
|
||||||
import type { ViteBuildContext } from './vite'
|
import type { ViteBuildContext } from './vite'
|
||||||
import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
|
import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
|
||||||
@ -255,11 +255,11 @@ export async function buildClient (ctx: ViteBuildContext) {
|
|||||||
// @ts-expect-error _skip_transform is a private property
|
// @ts-expect-error _skip_transform is a private property
|
||||||
event.node.req._skip_transform = true
|
event.node.req._skip_transform = true
|
||||||
} else if (!useViteCors) {
|
} else if (!useViteCors) {
|
||||||
if (event.method === 'OPTIONS') {
|
const isPreflight = handleCors(event, ctx.nuxt.options.devServer.cors)
|
||||||
appendCorsPreflightHeaders(event, {})
|
if (isPreflight) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
appendCorsHeaders(event, {})
|
setHeader(event, 'Vary', 'Origin')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround: vite devmiddleware modifies req.url
|
// Workaround: vite devmiddleware modifies req.url
|
||||||
|
36
packages/vite/src/utils/external.ts
Normal file
36
packages/vite/src/utils/external.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import type { ExternalsOptions } from 'externality'
|
||||||
|
import { ExternalsDefaults, isExternal } from 'externality'
|
||||||
|
import type { ViteDevServer } from 'vite'
|
||||||
|
import escapeStringRegexp from 'escape-string-regexp'
|
||||||
|
import { withTrailingSlash } from 'ufo'
|
||||||
|
import type { Nuxt } from 'nuxt/schema'
|
||||||
|
import { resolve } from 'pathe'
|
||||||
|
import { toArray } from '.'
|
||||||
|
|
||||||
|
export function createIsExternal (viteServer: ViteDevServer, nuxt: Nuxt) {
|
||||||
|
const externalOpts: ExternalsOptions = {
|
||||||
|
inline: [
|
||||||
|
/virtual:/,
|
||||||
|
/\.ts$/,
|
||||||
|
...ExternalsDefaults.inline || [],
|
||||||
|
...(
|
||||||
|
viteServer.config.ssr.noExternal && viteServer.config.ssr.noExternal !== true
|
||||||
|
? toArray(viteServer.config.ssr.noExternal)
|
||||||
|
: []
|
||||||
|
),
|
||||||
|
],
|
||||||
|
external: [
|
||||||
|
'#shared',
|
||||||
|
new RegExp('^' + escapeStringRegexp(withTrailingSlash(resolve(nuxt.options.rootDir, nuxt.options.dir.shared)))),
|
||||||
|
...(viteServer.config.ssr.external as string[]) || [],
|
||||||
|
/node_modules/,
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
modules: nuxt.options.modulesDir,
|
||||||
|
type: 'module',
|
||||||
|
extensions: ['.ts', '.js', '.json', '.vue', '.mjs', '.jsx', '.tsx', '.wasm'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return (id: string) => isExternal(id, nuxt.options.rootDir, externalOpts)
|
||||||
|
}
|
@ -8,9 +8,11 @@ import { isFileServingAllowed } from 'vite'
|
|||||||
import type { ModuleNode, Plugin as VitePlugin } from 'vite'
|
import type { ModuleNode, Plugin as VitePlugin } from 'vite'
|
||||||
import { getQuery } from 'ufo'
|
import { getQuery } from 'ufo'
|
||||||
import { normalizeViteManifest } from 'vue-bundle-renderer'
|
import { normalizeViteManifest } from 'vue-bundle-renderer'
|
||||||
|
import { resolve as resolveModule } from 'mlly'
|
||||||
import { distDir } from './dirs'
|
import { distDir } from './dirs'
|
||||||
import type { ViteBuildContext } from './vite'
|
import type { ViteBuildContext } from './vite'
|
||||||
import { isCSS } from './utils'
|
import { isCSS } from './utils'
|
||||||
|
import { createIsExternal } from './utils/external'
|
||||||
|
|
||||||
// TODO: Remove this in favor of registerViteNodeMiddleware
|
// TODO: Remove this in favor of registerViteNodeMiddleware
|
||||||
// after Nitropack or h3 allows adding middleware after setup
|
// after Nitropack or h3 allows adding middleware after setup
|
||||||
@ -126,6 +128,15 @@ function createViteNodeApp (ctx: ViteBuildContext, invalidates: Set<string> = ne
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isExternal = createIsExternal(viteServer, ctx.nuxt)
|
||||||
|
node.shouldExternalize = async (id: string) => {
|
||||||
|
const result = await isExternal(id)
|
||||||
|
if (result?.external) {
|
||||||
|
return resolveModule(result.id, { url: ctx.nuxt.options.modulesDir }).catch(() => false)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return eventHandler(async (event) => {
|
return eventHandler(async (event) => {
|
||||||
const moduleId = decodeURI(event.path).substring(1)
|
const moduleId = decodeURI(event.path).substring(1)
|
||||||
if (moduleId === '/') {
|
if (moduleId === '/') {
|
||||||
|
@ -85,7 +85,7 @@ export const bundle: NuxtBuilder['bundle'] = async (nuxt) => {
|
|||||||
// https://github.com/vitejs/vite/tree/main/packages/vite/src/node/build.ts#L464-L478
|
// https://github.com/vitejs/vite/tree/main/packages/vite/src/node/build.ts#L464-L478
|
||||||
assetFileNames: nuxt.options.dev
|
assetFileNames: nuxt.options.dev
|
||||||
? undefined
|
? undefined
|
||||||
: chunk => withoutLeadingSlash(join(nuxt.options.app.buildAssetsDir, `${sanitizeFilePath(filename(chunk.name!))}.[hash].[ext]`)),
|
: chunk => withoutLeadingSlash(join(nuxt.options.app.buildAssetsDir, `${sanitizeFilePath(filename(chunk.names[0]!))}.[hash].[ext]`)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"fork-ts-checker-webpack-plugin": "^9.0.2",
|
"fork-ts-checker-webpack-plugin": "^9.0.2",
|
||||||
"globby": "^14.0.2",
|
"globby": "^14.0.2",
|
||||||
"h3": "npm:h3-nightly@1.13.1-20250110-173418-de24917",
|
"h3": "npm:h3-nightly@1.14.0-20250122-114730-3f9e703",
|
||||||
"jiti": "^2.4.2",
|
"jiti": "^2.4.2",
|
||||||
"knitwork": "^1.2.0",
|
"knitwork": "^1.2.0",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
@ -73,11 +73,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/schema": "workspace:*",
|
"@nuxt/schema": "workspace:*",
|
||||||
"@rspack/core": "1.2.0",
|
"@rspack/core": "1.2.2",
|
||||||
"@types/pify": "5.0.4",
|
"@types/pify": "5.0.4",
|
||||||
"@types/webpack-bundle-analyzer": "4.7.0",
|
"@types/webpack-bundle-analyzer": "4.7.0",
|
||||||
"@types/webpack-hot-middleware": "2.25.9",
|
"@types/webpack-hot-middleware": "2.25.9",
|
||||||
"rollup": "4.31.0",
|
"rollup": "4.32.1",
|
||||||
"unbuild": "3.3.1",
|
"unbuild": "3.3.1",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import pify from 'pify'
|
import pify from 'pify'
|
||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { defineEventHandler, fromNodeMiddleware } from 'h3'
|
import { createError, defineEventHandler, fromNodeMiddleware, getRequestHeader, handleCors, setHeader } from 'h3'
|
||||||
|
import type { H3CorsOptions } from 'h3'
|
||||||
import type { IncomingMessage, MultiWatching, ServerResponse } from 'webpack-dev-middleware'
|
import type { IncomingMessage, MultiWatching, ServerResponse } from 'webpack-dev-middleware'
|
||||||
import webpackDevMiddleware from 'webpack-dev-middleware'
|
import webpackDevMiddleware from 'webpack-dev-middleware'
|
||||||
import webpackHotMiddleware from 'webpack-hot-middleware'
|
import webpackHotMiddleware from 'webpack-hot-middleware'
|
||||||
@ -125,7 +126,7 @@ async function createDevMiddleware (compiler: Compiler) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Register devMiddleware on server
|
// Register devMiddleware on server
|
||||||
const devHandler = wdmToH3Handler(devMiddleware)
|
const devHandler = wdmToH3Handler(devMiddleware, nuxt.options.devServer.cors)
|
||||||
const hotHandler = fromNodeMiddleware(hotMiddleware)
|
const hotHandler = fromNodeMiddleware(hotMiddleware)
|
||||||
await nuxt.callHook('server:devHandler', defineEventHandler(async (event) => {
|
await nuxt.callHook('server:devHandler', defineEventHandler(async (event) => {
|
||||||
const body = await devHandler(event)
|
const body = await devHandler(event)
|
||||||
@ -139,8 +140,20 @@ async function createDevMiddleware (compiler: Compiler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement upstream in `webpack-dev-middleware`
|
// TODO: implement upstream in `webpack-dev-middleware`
|
||||||
function wdmToH3Handler (devMiddleware: webpackDevMiddleware.API<IncomingMessage, ServerResponse>) {
|
function wdmToH3Handler (devMiddleware: webpackDevMiddleware.API<IncomingMessage, ServerResponse>, corsOptions: H3CorsOptions) {
|
||||||
return defineEventHandler(async (event) => {
|
return defineEventHandler(async (event) => {
|
||||||
|
const isPreflight = handleCors(event, corsOptions)
|
||||||
|
if (isPreflight) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// disallow cross-site requests in no-cors mode
|
||||||
|
if (getRequestHeader(event, 'sec-fetch-mode') === 'no-cors' && getRequestHeader(event, 'sec-fetch-site') === 'cross-site') {
|
||||||
|
throw createError({ statusCode: 403 })
|
||||||
|
}
|
||||||
|
|
||||||
|
setHeader(event, 'Vary', 'Origin')
|
||||||
|
|
||||||
event.context.webpack = {
|
event.context.webpack = {
|
||||||
...event.context.webpack,
|
...event.context.webpack,
|
||||||
devMiddleware: devMiddleware.context,
|
devMiddleware: devMiddleware.context,
|
||||||
|
2425
pnpm-lock.yaml
2425
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -61,7 +61,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"209k"`)
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"209k"`)
|
||||||
|
|
||||||
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1398k"`)
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1402k"`)
|
||||||
|
|
||||||
const packages = modules.files
|
const packages = modules.files
|
||||||
.filter(m => m.endsWith('package.json'))
|
.filter(m => m.endsWith('package.json'))
|
||||||
@ -127,10 +127,10 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
const serverDir = join(pagesRootDir, '.output/server')
|
const serverDir = join(pagesRootDir, '.output/server')
|
||||||
|
|
||||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"303k"`)
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"301k"`)
|
||||||
|
|
||||||
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1398k"`)
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1402k"`)
|
||||||
|
|
||||||
const packages = modules.files
|
const packages = modules.files
|
||||||
.filter(m => m.endsWith('package.json'))
|
.filter(m => m.endsWith('package.json'))
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { configDefaults, coverageConfigDefaults, defineConfig } from 'vitest/config'
|
import { configDefaults, coverageConfigDefaults, defineConfig } from 'vitest/config'
|
||||||
import { isWindows } from 'std-env'
|
import { isWindows } from 'std-env'
|
||||||
// import codspeedPlugin from '@codspeed/vitest-plugin'
|
import codspeedPlugin from '@codspeed/vitest-plugin'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// plugins: [codspeedPlugin()],
|
plugins: [codspeedPlugin()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'#build/nuxt.config.mjs': resolve('./test/mocks/nuxt-config'),
|
'#build/nuxt.config.mjs': resolve('./test/mocks/nuxt-config'),
|
||||||
|
Loading…
Reference in New Issue
Block a user