mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-30 09:27:13 +00:00
Merge branch 'main' into docs/kit
This commit is contained in:
commit
066390972c
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -86,7 +86,7 @@ jobs:
|
|||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@1813ca74c3faaa3a2da2070b9b8a0b3e7373a0d8 # v2.21.0
|
uses: github/codeql-action/init@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2
|
||||||
with:
|
with:
|
||||||
languages: javascript
|
languages: javascript
|
||||||
queries: +security-and-quality
|
queries: +security-and-quality
|
||||||
@ -98,7 +98,7 @@ jobs:
|
|||||||
path: packages
|
path: packages
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@1813ca74c3faaa3a2da2070b9b8a0b3e7373a0d8 # v2.21.0
|
uses: github/codeql-action/analyze@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2
|
||||||
with:
|
with:
|
||||||
category: "/language:javascript"
|
category: "/language:javascript"
|
||||||
|
|
||||||
|
2
.github/workflows/scorecards.yml
vendored
2
.github/workflows/scorecards.yml
vendored
@ -66,6 +66,6 @@ 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@1813ca74c3faaa3a2da2070b9b8a0b3e7373a0d8 # v2.21.0
|
uses: github/codeql-action/upload-sarif@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
@ -7,6 +7,8 @@ head.title: ".env"
|
|||||||
|
|
||||||
# .env File
|
# .env File
|
||||||
|
|
||||||
|
## At Build, Dev, and Generate Time
|
||||||
|
|
||||||
Nuxt CLI has built-in [dotenv](https://github.com/motdotla/dotenv) support in development mode and when running `nuxi build` and `nuxi generate`.
|
Nuxt CLI has built-in [dotenv](https://github.com/motdotla/dotenv) support in development mode and when running `nuxi build` and `nuxi generate`.
|
||||||
|
|
||||||
In addition to any process environment variables, if you have a `.env` file in your project root directory, it will be automatically loaded **at build, dev, and generate time**, and any environment variables set there will be accessible within your `nuxt.config` file and modules.
|
In addition to any process environment variables, if you have a `.env` file in your project root directory, it will be automatically loaded **at build, dev, and generate time**, and any environment variables set there will be accessible within your `nuxt.config` file and modules.
|
||||||
@ -27,7 +29,17 @@ When updating `.env` in development mode, the Nuxt instance is automatically res
|
|||||||
Note that removing a variable from `.env` or removing the `.env` file entirely will not unset values that have already been set.
|
Note that removing a variable from `.env` or removing the `.env` file entirely will not unset values that have already been set.
|
||||||
::
|
::
|
||||||
|
|
||||||
However, **after your server is built**, you are responsible for setting environment variables when you run the server. Your `.env` file will not be read at this point. How you do this is different for every environment. On a Linux server, you could pass the environment variables as arguments using the terminal `DATABASE_HOST=mydatabaseconnectionstring node .output/server/index.mjs`. Or you could source your env file using `source .env && node .output/server/index.mjs`.
|
## Production Preview
|
||||||
|
|
||||||
|
**After your server is built**, you are responsible for setting environment variables when you run the server. Your `.env` file will not be read at this point. How you do this is different for every environment.
|
||||||
|
|
||||||
|
For local production preview purpose, we recommend using [`nuxi preview`](https://nuxt.com/docs/api/commands/preview) since using this command, the `.env` file will be loaded into `process.env` for convenience. Note that this command requires dependencies to be installed in the package directory.
|
||||||
|
|
||||||
|
Or you could pass the environment variables as arguments using the terminal. For example, on Linux or macOS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DATABASE_HOST=mydatabaseconnectionstring node .output/server/index.mjs
|
||||||
|
```
|
||||||
|
|
||||||
Note that for a purely static site, it is not possible to set runtime configuration config after your project is prerendered.
|
Note that for a purely static site, it is not possible to set runtime configuration config after your project is prerendered.
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ interface PageMeta {
|
|||||||
keepalive?: boolean | KeepAliveProps
|
keepalive?: boolean | KeepAliveProps
|
||||||
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>
|
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>
|
||||||
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
|
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
|
||||||
|
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -98,6 +99,12 @@ interface PageMeta {
|
|||||||
|
|
||||||
Validate whether a given route can validly be rendered with this page. Return true if it is valid, or false if not. If another match can't be found, this will mean a 404. You can also directly return an object with `statusCode`/`statusMessage` to respond immediately with an error (other matches will not be checked).
|
Validate whether a given route can validly be rendered with this page. Return true if it is valid, or false if not. If another match can't be found, this will mean a 404. You can also directly return an object with `statusCode`/`statusMessage` to respond immediately with an error (other matches will not be checked).
|
||||||
|
|
||||||
|
**`scrollTopTop`**
|
||||||
|
|
||||||
|
- **Type**: `boolean | (to: RouteLocationNormalized, from: RouteLocationNormalized) => boolean`
|
||||||
|
|
||||||
|
Tell Nuxt to scroll to the top before rendering the page or not. If you want to overwrite the default scroll behavior of Nuxt, you can do so in `~/app/router.options.ts` (see [docs](/docs/guide/directory-structure/pages/#router-options)) for more info.
|
||||||
|
|
||||||
**`[key: string]`**
|
**`[key: string]`**
|
||||||
|
|
||||||
- **Type**: `any`
|
- **Type**: `any`
|
||||||
|
@ -267,3 +267,42 @@ Options to pass in [`c12`](https://github.com/unjs/c12#options) `loadConfig` cal
|
|||||||
- `extendViteConfig(callback, options?)`
|
- `extendViteConfig(callback, options?)`
|
||||||
- `addWebpackPlugin(webpackPlugin, options?)`
|
- `addWebpackPlugin(webpackPlugin, options?)`
|
||||||
- `addVitePlugin(vitePlugin, options?)`
|
- `addVitePlugin(vitePlugin, options?)`
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Accessing Nuxt Vite Config
|
||||||
|
|
||||||
|
If you are building an integration that needs access to the runtime Vite or webpack config that Nuxt uses, it is possible to extract this using Kit utilities.
|
||||||
|
|
||||||
|
Some examples of projects doing this already:
|
||||||
|
|
||||||
|
- [histoire](https://github.com/histoire-dev/histoire/blob/main/packages/histoire-plugin-nuxt/src/index.ts)
|
||||||
|
- [nuxt-vitest](https://github.com/danielroe/nuxt-vitest/blob/main/packages/nuxt-vitest/src/config.ts)
|
||||||
|
- [@storybook-vue/nuxt](https://github.com/storybook-vue/nuxt/blob/main/src/preset.ts)
|
||||||
|
|
||||||
|
Here is a brief example of how you might access the Vite config from a project; you could implement a similar approach to get the webpack configuration.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { loadNuxt, buildNuxt } from '@nuxt/kit'
|
||||||
|
|
||||||
|
// https://github.com/nuxt/nuxt/issues/14534
|
||||||
|
async function getViteConfig() {
|
||||||
|
const nuxt = await loadNuxt({ cwd: process.cwd(), dev: false, overrides: { ssr: false } })
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
nuxt.hook('vite:extendConfig', (config, { isClient }) => {
|
||||||
|
if (isClient) {
|
||||||
|
resolve(config)
|
||||||
|
throw new Error('_stop_')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
buildNuxt(nuxt).catch((err) => {
|
||||||
|
if (!err.toString().includes('_stop_')) {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).finally(() => nuxt.close())
|
||||||
|
}
|
||||||
|
|
||||||
|
const viteConfig = await getViteConfig()
|
||||||
|
console.log(viteConfig)
|
||||||
|
```
|
||||||
|
18
package.json
18
package.json
@ -37,7 +37,7 @@
|
|||||||
"nuxt": "workspace:*",
|
"nuxt": "workspace:*",
|
||||||
"vite": "4.4.7",
|
"vite": "4.4.7",
|
||||||
"vue": "3.3.4",
|
"vue": "3.3.4",
|
||||||
"magic-string": "^0.30.1"
|
"magic-string": "^0.30.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@actions/core": "1.10.0",
|
"@actions/core": "1.10.0",
|
||||||
@ -45,7 +45,7 @@
|
|||||||
"@nuxt/webpack-builder": "workspace:*",
|
"@nuxt/webpack-builder": "workspace:*",
|
||||||
"@nuxtjs/eslint-config-typescript": "12.0.0",
|
"@nuxtjs/eslint-config-typescript": "12.0.0",
|
||||||
"@types/fs-extra": "11.0.1",
|
"@types/fs-extra": "11.0.1",
|
||||||
"@types/node": "18.17.0",
|
"@types/node": "18.17.1",
|
||||||
"@types/semver": "7.5.0",
|
"@types/semver": "7.5.0",
|
||||||
"case-police": "0.6.1",
|
"case-police": "0.6.1",
|
||||||
"chalk": "5.3.0",
|
"chalk": "5.3.0",
|
||||||
@ -53,11 +53,11 @@
|
|||||||
"cheerio": "1.0.0-rc.12",
|
"cheerio": "1.0.0-rc.12",
|
||||||
"consola": "3.2.3",
|
"consola": "3.2.3",
|
||||||
"devalue": "4.3.2",
|
"devalue": "4.3.2",
|
||||||
"eslint": "8.45.0",
|
"eslint": "8.46.0",
|
||||||
"eslint-plugin-import": "2.27.5",
|
"eslint-plugin-import": "2.28.0",
|
||||||
"eslint-plugin-jsdoc": "41.1.2",
|
"eslint-plugin-jsdoc": "41.1.2",
|
||||||
"eslint-plugin-no-only-tests": "3.1.0",
|
"eslint-plugin-no-only-tests": "3.1.0",
|
||||||
"execa": "7.1.1",
|
"execa": "7.2.0",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.1.1",
|
||||||
"globby": "13.2.2",
|
"globby": "13.2.2",
|
||||||
"h3": "1.7.1",
|
"h3": "1.7.1",
|
||||||
@ -70,19 +70,19 @@
|
|||||||
"nuxt-vitest": "0.10.2",
|
"nuxt-vitest": "0.10.2",
|
||||||
"ofetch": "1.1.1",
|
"ofetch": "1.1.1",
|
||||||
"pathe": "1.1.1",
|
"pathe": "1.1.1",
|
||||||
"playwright-core": "1.36.1",
|
"playwright-core": "1.36.2",
|
||||||
"rimraf": "5.0.1",
|
"rimraf": "5.0.1",
|
||||||
"semver": "7.5.4",
|
"semver": "7.5.4",
|
||||||
"std-env": "3.3.3",
|
"std-env": "3.3.3",
|
||||||
"typescript": "5.0.4",
|
"typescript": "5.1.6",
|
||||||
"ufo": "1.1.2",
|
"ufo": "1.2.0",
|
||||||
"vite": "4.4.7",
|
"vite": "4.4.7",
|
||||||
"vitest": "0.33.0",
|
"vitest": "0.33.0",
|
||||||
"vitest-environment-nuxt": "0.10.2",
|
"vitest-environment-nuxt": "0.10.2",
|
||||||
"vue": "3.3.4",
|
"vue": "3.3.4",
|
||||||
"vue-eslint-parser": "9.3.1",
|
"vue-eslint-parser": "9.3.1",
|
||||||
"vue-router": "4.2.4",
|
"vue-router": "4.2.4",
|
||||||
"vue-tsc": "1.8.6"
|
"vue-tsc": "1.8.8"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.6.10",
|
"packageManager": "pnpm@8.6.10",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"semver": "^7.5.4",
|
"semver": "^7.5.4",
|
||||||
"unctx": "^2.3.1",
|
"unctx": "^2.3.1",
|
||||||
"unimport": "^3.1.0",
|
"unimport": "^3.1.0",
|
||||||
"untyped": "^1.3.2"
|
"untyped": "^1.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/hash-sum": "1.0.0",
|
"@types/hash-sum": "1.0.0",
|
||||||
|
@ -6,6 +6,7 @@ import { genDynamicImport, genImport, genSafeVariableName } from 'knitwork'
|
|||||||
import type { NuxtTemplate } from '@nuxt/schema'
|
import type { NuxtTemplate } from '@nuxt/schema'
|
||||||
|
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
|
// TODO: Remove support for compiling ejs templates in v4
|
||||||
export async function compileTemplate (template: NuxtTemplate, ctx: any) {
|
export async function compileTemplate (template: NuxtTemplate, ctx: any) {
|
||||||
const data = { ...ctx, options: template.options }
|
const data = { ...ctx, options: template.options }
|
||||||
if (template.src) {
|
if (template.src) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
|
import type { JSValue } from 'untyped'
|
||||||
import { applyDefaults } from 'untyped'
|
import { applyDefaults } from 'untyped'
|
||||||
import type { LoadConfigOptions } from 'c12'
|
import type { LoadConfigOptions } from 'c12'
|
||||||
import { loadConfig } from 'c12'
|
import { loadConfig } from 'c12'
|
||||||
@ -50,5 +51,5 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resolve and apply defaults
|
// Resolve and apply defaults
|
||||||
return await applyDefaults(NuxtConfigSchema, nuxtConfig) as NuxtOptions
|
return await applyDefaults(NuxtConfigSchema, nuxtConfig as NuxtConfig & Record<string, JSValue>) as unknown as NuxtOptions
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
"deep-object-diff": "1.1.9",
|
"deep-object-diff": "1.1.9",
|
||||||
"defu": "6.1.2",
|
"defu": "6.1.2",
|
||||||
"destr": "2.0.0",
|
"destr": "2.0.0",
|
||||||
"execa": "7.1.1",
|
"execa": "7.2.0",
|
||||||
"flat": "5.0.2",
|
"flat": "5.0.2",
|
||||||
"giget": "1.1.2",
|
"giget": "1.1.2",
|
||||||
"h3": "1.7.1",
|
"h3": "1.7.1",
|
||||||
@ -47,7 +47,7 @@
|
|||||||
"pkg-types": "1.0.3",
|
"pkg-types": "1.0.3",
|
||||||
"scule": "1.0.0",
|
"scule": "1.0.0",
|
||||||
"semver": "7.5.4",
|
"semver": "7.5.4",
|
||||||
"ufo": "1.1.2",
|
"ufo": "1.2.0",
|
||||||
"unbuild": "latest"
|
"unbuild": "latest"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
@ -73,10 +73,14 @@ export const writeTypes = async (nuxt: Nuxt) => {
|
|||||||
tsConfig.include.push(`${absolutePath}/*`)
|
tsConfig.include.push(`${absolutePath}/*`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tsConfig.compilerOptions.paths[alias] = [absolutePath.replace(/(?<=\w)\.\w+$/g, '')] /* remove extension */
|
const path = stats?.isFile()
|
||||||
|
? absolutePath.replace(/(?<=\w)\.\w+$/g, '') /* remove extension */
|
||||||
|
: absolutePath
|
||||||
|
|
||||||
|
tsConfig.compilerOptions.paths[alias] = [path]
|
||||||
|
|
||||||
if (!absolutePath.startsWith(rootDirWithSlash)) {
|
if (!absolutePath.startsWith(rootDirWithSlash)) {
|
||||||
tsConfig.include.push(absolutePath.replace(/(?<=\w)\.\w+$/g, ''))
|
tsConfig.include.push(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,10 @@
|
|||||||
"@nuxt/kit": "workspace:../kit",
|
"@nuxt/kit": "workspace:../kit",
|
||||||
"@nuxt/schema": "workspace:../schema",
|
"@nuxt/schema": "workspace:../schema",
|
||||||
"@nuxt/telemetry": "^2.3.2",
|
"@nuxt/telemetry": "^2.3.2",
|
||||||
"@nuxt/ui-templates": "^1.2.1",
|
"@nuxt/ui-templates": "^1.3.1",
|
||||||
"@nuxt/vite-builder": "workspace:../vite",
|
"@nuxt/vite-builder": "workspace:../vite",
|
||||||
"@unhead/ssr": "^1.1.32",
|
"@unhead/ssr": "^1.1.33",
|
||||||
"@unhead/vue": "^1.1.32",
|
"@unhead/vue": "^1.1.33",
|
||||||
"@vue/shared": "^3.3.4",
|
"@vue/shared": "^3.3.4",
|
||||||
"acorn": "8.10.0",
|
"acorn": "8.10.0",
|
||||||
"c12": "^1.4.2",
|
"c12": "^1.4.2",
|
||||||
@ -68,7 +68,7 @@
|
|||||||
"defu": "^6.1.2",
|
"defu": "^6.1.2",
|
||||||
"destr": "^2.0.0",
|
"destr": "^2.0.0",
|
||||||
"devalue": "^4.3.2",
|
"devalue": "^4.3.2",
|
||||||
"esbuild": "^0.18.16",
|
"esbuild": "^0.18.17",
|
||||||
"escape-string-regexp": "^5.0.0",
|
"escape-string-regexp": "^5.0.0",
|
||||||
"estree-walker": "^3.0.3",
|
"estree-walker": "^3.0.3",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
@ -79,7 +79,7 @@
|
|||||||
"klona": "^2.0.6",
|
"klona": "^2.0.6",
|
||||||
"knitwork": "^1.0.0",
|
"knitwork": "^1.0.0",
|
||||||
"local-pkg": "^0.4.3",
|
"local-pkg": "^0.4.3",
|
||||||
"magic-string": "^0.30.1",
|
"magic-string": "^0.30.2",
|
||||||
"mlly": "^1.4.0",
|
"mlly": "^1.4.0",
|
||||||
"nitropack": "^2.5.2",
|
"nitropack": "^2.5.2",
|
||||||
"nuxi": "workspace:../nuxi",
|
"nuxi": "workspace:../nuxi",
|
||||||
@ -91,7 +91,7 @@
|
|||||||
"prompts": "^2.4.2",
|
"prompts": "^2.4.2",
|
||||||
"scule": "^1.0.0",
|
"scule": "^1.0.0",
|
||||||
"strip-literal": "^1.0.1",
|
"strip-literal": "^1.0.1",
|
||||||
"ufo": "^1.1.2",
|
"ufo": "^1.2.0",
|
||||||
"ultrahtml": "^1.3.0",
|
"ultrahtml": "^1.3.0",
|
||||||
"uncrypto": "^0.1.3",
|
"uncrypto": "^0.1.3",
|
||||||
"unctx": "^2.3.1",
|
"unctx": "^2.3.1",
|
||||||
@ -99,7 +99,7 @@
|
|||||||
"unimport": "^3.1.0",
|
"unimport": "^3.1.0",
|
||||||
"unplugin": "^1.4.0",
|
"unplugin": "^1.4.0",
|
||||||
"unplugin-vue-router": "^0.6.4",
|
"unplugin-vue-router": "^0.6.4",
|
||||||
"untyped": "^1.3.2",
|
"untyped": "^1.4.0",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
"vue-bundle-renderer": "^1.0.3",
|
"vue-bundle-renderer": "^1.0.3",
|
||||||
"vue-devtools-stub": "^0.1.0",
|
"vue-devtools-stub": "^0.1.0",
|
||||||
|
@ -2,7 +2,7 @@ import { getCurrentInstance, hasInjectionContext, inject, onUnmounted } from 'vu
|
|||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import type { NavigationFailure, NavigationGuard, RouteLocationNormalized, RouteLocationPathRaw, RouteLocationRaw, Router, useRoute as _useRoute, useRouter as _useRouter } from '#vue-router'
|
import type { NavigationFailure, NavigationGuard, RouteLocationNormalized, RouteLocationPathRaw, RouteLocationRaw, Router, useRoute as _useRoute, useRouter as _useRouter } from '#vue-router'
|
||||||
import { sanitizeStatusCode } from 'h3'
|
import { sanitizeStatusCode } from 'h3'
|
||||||
import { hasProtocol, joinURL, parseURL, withQuery } from 'ufo'
|
import { hasProtocol, isScriptProtocol, joinURL, parseURL, withQuery } from 'ufo'
|
||||||
|
|
||||||
import { useNuxtApp, useRuntimeConfig } from '../nuxt'
|
import { useNuxtApp, useRuntimeConfig } from '../nuxt'
|
||||||
import type { NuxtError } from './error'
|
import type { NuxtError } from './error'
|
||||||
@ -133,11 +133,14 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isExternal = options?.external || hasProtocol(toPath, { acceptRelative: true })
|
const isExternal = options?.external || hasProtocol(toPath, { acceptRelative: true })
|
||||||
if (isExternal && !options?.external) {
|
if (isExternal) {
|
||||||
throw new Error('Navigating to external URL is not allowed by default. Use `navigateTo (url, { external: true })`.')
|
if (!options?.external) {
|
||||||
|
throw new Error('Navigating to an external URL is not allowed by default. Use `navigateTo(url, { external: true })`.')
|
||||||
|
}
|
||||||
|
const protocol = parseURL(toPath).protocol
|
||||||
|
if (protocol && isScriptProtocol(protocol)) {
|
||||||
|
throw new Error(`Cannot navigate to a URL with '${protocol}' protocol.`)
|
||||||
}
|
}
|
||||||
if (isExternal && parseURL(toPath).protocol === 'script:') {
|
|
||||||
throw new Error('Cannot navigate to an URL with script protocol.')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const inMiddleware = isProcessingMiddleware()
|
const inMiddleware = isProcessingMiddleware()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { promises as fsp } from 'node:fs'
|
import { promises as fsp, mkdirSync, writeFileSync } from 'node:fs'
|
||||||
import { dirname, join, resolve } from 'pathe'
|
import { dirname, join, resolve } from 'pathe'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { compileTemplate, findPath, normalizePlugin, normalizeTemplate, resolveAlias, resolveFiles, resolvePath, templateUtils, tryResolveModule } from '@nuxt/kit'
|
import { compileTemplate, findPath, normalizePlugin, normalizeTemplate, resolveAlias, resolveFiles, resolvePath, templateUtils, tryResolveModule } from '@nuxt/kit'
|
||||||
@ -32,13 +32,21 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?:
|
|||||||
app.templates = app.templates.map(tmpl => normalizeTemplate(tmpl))
|
app.templates = app.templates.map(tmpl => normalizeTemplate(tmpl))
|
||||||
|
|
||||||
// Compile templates into vfs
|
// Compile templates into vfs
|
||||||
|
// TODO: remove utils in v4
|
||||||
const templateContext = { utils: templateUtils, nuxt, app }
|
const templateContext = { utils: templateUtils, nuxt, app }
|
||||||
await Promise.all((app.templates as Array<ReturnType<typeof normalizeTemplate>>)
|
const filteredTemplates = (app.templates as Array<ReturnType<typeof normalizeTemplate>>)
|
||||||
.filter(template => !options.filter || options.filter(template))
|
.filter(template => !options.filter || options.filter(template))
|
||||||
.map(async (template) => {
|
|
||||||
const contents = await compileTemplate(template, templateContext)
|
|
||||||
|
|
||||||
|
const writes: Array<() => void> = []
|
||||||
|
await Promise.allSettled(filteredTemplates
|
||||||
|
.map(async (template) => {
|
||||||
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename!)
|
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename!)
|
||||||
|
const mark = performance.mark(fullPath)
|
||||||
|
const contents = await compileTemplate(template, templateContext).catch((e) => {
|
||||||
|
console.error(`[nuxt] Could not compile template \`${template.filename}\`.`)
|
||||||
|
throw e
|
||||||
|
})
|
||||||
|
|
||||||
nuxt.vfs[fullPath] = contents
|
nuxt.vfs[fullPath] = contents
|
||||||
|
|
||||||
const aliasPath = '#build/' + template.filename!.replace(/\.\w+$/, '')
|
const aliasPath = '#build/' + template.filename!.replace(/\.\w+$/, '')
|
||||||
@ -49,13 +57,26 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?:
|
|||||||
nuxt.vfs[fullPath.replace(/\//g, '\\')] = contents
|
nuxt.vfs[fullPath.replace(/\//g, '\\')] = contents
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const perf = performance.measure(fullPath, mark?.name) // TODO: remove when Node 14 reaches EOL
|
||||||
|
const setupTime = perf ? Math.round((perf.duration * 100)) / 100 : 0 // TODO: remove when Node 14 reaches EOL
|
||||||
|
|
||||||
|
if (nuxt.options.debug || setupTime > 500) {
|
||||||
|
console.info(`[nuxt] compiled \`${template.filename}\` in ${setupTime}ms`)
|
||||||
|
}
|
||||||
|
|
||||||
if (template.write) {
|
if (template.write) {
|
||||||
await fsp.mkdir(dirname(fullPath), { recursive: true })
|
writes.push(() => {
|
||||||
await fsp.writeFile(fullPath, contents, 'utf8')
|
mkdirSync(dirname(fullPath), { recursive: true })
|
||||||
|
writeFileSync(fullPath, contents, 'utf8')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
await nuxt.callHook('app:templatesGenerated', app)
|
// Write template files in single synchronous step to avoid (possible) additional
|
||||||
|
// runtime overhead of cascading HMRs from vite/webpack
|
||||||
|
for (const write of writes) { write() }
|
||||||
|
|
||||||
|
await nuxt.callHook('app:templatesGenerated', app, filteredTemplates, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { existsSync } from 'node:fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { genArrayFromRaw, genDynamicImport, genExport, genImport, genObjectFromRawEntries, genSafeVariableName, genString } from 'knitwork'
|
import { genArrayFromRaw, genDynamicImport, genExport, genImport, genObjectFromRawEntries, genSafeVariableName, genString } from 'knitwork'
|
||||||
import { isAbsolute, join, relative, resolve } from 'pathe'
|
import { isAbsolute, join, relative, resolve } from 'pathe'
|
||||||
|
import type { JSValue } from 'untyped'
|
||||||
import { generateTypes, resolveSchema } from 'untyped'
|
import { generateTypes, resolveSchema } from 'untyped'
|
||||||
import escapeRE from 'escape-string-regexp'
|
import escapeRE from 'escape-string-regexp'
|
||||||
import { hash } from 'ohash'
|
import { hash } from 'ohash'
|
||||||
@ -144,7 +145,7 @@ export const schemaTemplate: NuxtTemplate<TemplateContext> = {
|
|||||||
),
|
),
|
||||||
modules.length > 0 ? ` modules?: (undefined | null | false | NuxtModule | string | [NuxtModule | string, Record<string, any>] | ${modules.map(([configKey, importName]) => `[${genString(importName)}, Exclude<NuxtConfig[${configKey}], boolean>]`).join(' | ')})[],` : '',
|
modules.length > 0 ? ` modules?: (undefined | null | false | NuxtModule | string | [NuxtModule | string, Record<string, any>] | ${modules.map(([configKey, importName]) => `[${genString(importName)}, Exclude<NuxtConfig[${configKey}], boolean>]`).join(' | ')})[],` : '',
|
||||||
' }',
|
' }',
|
||||||
generateTypes(await resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== 'public'))),
|
generateTypes(await resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== 'public')) as Record<string, JSValue>),
|
||||||
{
|
{
|
||||||
interfaceName: 'RuntimeConfig',
|
interfaceName: 'RuntimeConfig',
|
||||||
addExport: false,
|
addExport: false,
|
||||||
@ -152,7 +153,7 @@ export const schemaTemplate: NuxtTemplate<TemplateContext> = {
|
|||||||
allowExtraKeys: false,
|
allowExtraKeys: false,
|
||||||
indentation: 2
|
indentation: 2
|
||||||
}),
|
}),
|
||||||
generateTypes(await resolveSchema(nuxt.options.runtimeConfig.public),
|
generateTypes(await resolveSchema(nuxt.options.runtimeConfig.public as Record<string, JSValue>),
|
||||||
{
|
{
|
||||||
interfaceName: 'PublicRuntimeConfig',
|
interfaceName: 'PublicRuntimeConfig',
|
||||||
addExport: false,
|
addExport: false,
|
||||||
|
@ -36,7 +36,7 @@ export interface PageMeta {
|
|||||||
/** You may define a path matcher, if you have a more complex pattern than can be expressed with the file name. */
|
/** You may define a path matcher, if you have a more complex pattern than can be expressed with the file name. */
|
||||||
path?: string
|
path?: string
|
||||||
/** Set to `false` to avoid scrolling to top on page navigations */
|
/** Set to `false` to avoid scrolling to top on page navigations */
|
||||||
scrollToTop?: boolean
|
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'vue-router' {
|
declare module 'vue-router' {
|
||||||
|
@ -20,8 +20,10 @@ export default <RouterConfig> {
|
|||||||
// savedPosition is only available for popstate navigations (back button)
|
// savedPosition is only available for popstate navigations (back button)
|
||||||
let position: ScrollPosition = savedPosition || undefined
|
let position: ScrollPosition = savedPosition || undefined
|
||||||
|
|
||||||
|
const routeAllowsScrollToTop = typeof to.meta.scrollToTop === 'function' ? to.meta.scrollToTop(to, from) : to.meta.scrollToTop
|
||||||
|
|
||||||
// Scroll to top if route is changed by default
|
// Scroll to top if route is changed by default
|
||||||
if (!position && from && to && to.meta.scrollToTop !== false && _isDifferentRoute(from, to)) {
|
if (!position && from && to && routeAllowsScrollToTop !== false && _isDifferentRoute(from, to)) {
|
||||||
position = { left: 0, top: 0 }
|
position = { left: 0, top: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"@types/file-loader": "5.0.1",
|
"@types/file-loader": "5.0.1",
|
||||||
"@types/pug": "2.0.6",
|
"@types/pug": "2.0.6",
|
||||||
"@types/sass-loader": "8.0.5",
|
"@types/sass-loader": "8.0.5",
|
||||||
"@unhead/schema": "1.1.32",
|
"@unhead/schema": "1.1.33",
|
||||||
"@vitejs/plugin-vue": "4.2.3",
|
"@vitejs/plugin-vue": "4.2.3",
|
||||||
"@vitejs/plugin-vue-jsx": "3.0.1",
|
"@vitejs/plugin-vue-jsx": "3.0.1",
|
||||||
"@vue/compiler-core": "3.3.4",
|
"@vue/compiler-core": "3.3.4",
|
||||||
@ -49,16 +49,16 @@
|
|||||||
"webpack-dev-middleware": "6.1.1"
|
"webpack-dev-middleware": "6.1.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/ui-templates": "^1.2.1",
|
"@nuxt/ui-templates": "^1.3.1",
|
||||||
"defu": "^6.1.2",
|
"defu": "^6.1.2",
|
||||||
"hookable": "^5.5.3",
|
"hookable": "^5.5.3",
|
||||||
"pathe": "^1.1.1",
|
"pathe": "^1.1.1",
|
||||||
"pkg-types": "^1.0.3",
|
"pkg-types": "^1.0.3",
|
||||||
"postcss-import-resolver": "^2.0.0",
|
"postcss-import-resolver": "^2.0.0",
|
||||||
"std-env": "^3.3.3",
|
"std-env": "^3.3.3",
|
||||||
"ufo": "^1.1.2",
|
"ufo": "^1.2.0",
|
||||||
"unimport": "^3.1.0",
|
"unimport": "^3.1.0",
|
||||||
"untyped": "^1.3.2"
|
"untyped": "^1.4.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.18.0 || >=16.10.0"
|
"node": "^14.18.0 || >=16.10.0"
|
||||||
|
@ -123,7 +123,7 @@ export interface NuxtHooks {
|
|||||||
* @param app The configured `NuxtApp` object
|
* @param app The configured `NuxtApp` object
|
||||||
* @returns Promise
|
* @returns Promise
|
||||||
*/
|
*/
|
||||||
'app:templatesGenerated': (app: NuxtApp) => HookResult
|
'app:templatesGenerated': (app: NuxtApp, templates: ResolvedNuxtTemplate[], options?: GenerateAppOptions) => HookResult
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before Nuxt bundle builder.
|
* Called before Nuxt bundle builder.
|
||||||
|
@ -26,15 +26,15 @@
|
|||||||
"@nuxt/schema": "workspace:../schema",
|
"@nuxt/schema": "workspace:../schema",
|
||||||
"consola": "^3.2.3",
|
"consola": "^3.2.3",
|
||||||
"defu": "^6.1.2",
|
"defu": "^6.1.2",
|
||||||
"execa": "^7.1.1",
|
"execa": "^7.2.0",
|
||||||
"get-port-please": "^3.0.1",
|
"get-port-please": "^3.0.1",
|
||||||
"ofetch": "^1.1.1",
|
"ofetch": "^1.1.1",
|
||||||
"pathe": "^1.1.1",
|
"pathe": "^1.1.1",
|
||||||
"ufo": "^1.1.2"
|
"ufo": "^1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@jest/globals": "29.6.1",
|
"@jest/globals": "29.6.2",
|
||||||
"playwright-core": "1.36.1",
|
"playwright-core": "1.36.2",
|
||||||
"unbuild": "latest",
|
"unbuild": "latest",
|
||||||
"vitest": "0.33.0"
|
"vitest": "0.33.0"
|
||||||
},
|
},
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
"consola": "^3.2.3",
|
"consola": "^3.2.3",
|
||||||
"cssnano": "^6.0.1",
|
"cssnano": "^6.0.1",
|
||||||
"defu": "^6.1.2",
|
"defu": "^6.1.2",
|
||||||
"esbuild": "^0.18.16",
|
"esbuild": "^0.18.17",
|
||||||
"escape-string-regexp": "^5.0.0",
|
"escape-string-regexp": "^5.0.0",
|
||||||
"estree-walker": "^3.0.3",
|
"estree-walker": "^3.0.3",
|
||||||
"externality": "^1.0.2",
|
"externality": "^1.0.2",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"get-port-please": "^3.0.1",
|
"get-port-please": "^3.0.1",
|
||||||
"h3": "^1.7.1",
|
"h3": "^1.7.1",
|
||||||
"knitwork": "^1.0.0",
|
"knitwork": "^1.0.0",
|
||||||
"magic-string": "^0.30.1",
|
"magic-string": "^0.30.2",
|
||||||
"mlly": "^1.4.0",
|
"mlly": "^1.4.0",
|
||||||
"ohash": "^1.1.2",
|
"ohash": "^1.1.2",
|
||||||
"pathe": "^1.1.1",
|
"pathe": "^1.1.1",
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
"std-env": "^3.3.3",
|
"std-env": "^3.3.3",
|
||||||
"strip-literal": "^1.0.1",
|
"strip-literal": "^1.0.1",
|
||||||
"ufo": "^1.1.2",
|
"ufo": "^1.2.0",
|
||||||
"unplugin": "^1.4.0",
|
"unplugin": "^1.4.0",
|
||||||
"vite": "^4.4.7",
|
"vite": "^4.4.7",
|
||||||
"vite-node": "^0.33.0",
|
"vite-node": "^0.33.0",
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
"h3": "^1.7.1",
|
"h3": "^1.7.1",
|
||||||
"hash-sum": "^2.0.0",
|
"hash-sum": "^2.0.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"magic-string": "^0.30.1",
|
"magic-string": "^0.30.2",
|
||||||
"memfs": "^4.2.0",
|
"memfs": "^4.2.0",
|
||||||
"mini-css-extract-plugin": "^2.7.6",
|
"mini-css-extract-plugin": "^2.7.6",
|
||||||
"mlly": "^1.4.0",
|
"mlly": "^1.4.0",
|
||||||
@ -49,7 +49,7 @@
|
|||||||
"pug-plain-loader": "^1.1.0",
|
"pug-plain-loader": "^1.1.0",
|
||||||
"std-env": "^3.3.3",
|
"std-env": "^3.3.3",
|
||||||
"time-fix-plugin": "^2.0.7",
|
"time-fix-plugin": "^2.0.7",
|
||||||
"ufo": "^1.1.2",
|
"ufo": "^1.2.0",
|
||||||
"unplugin": "^1.4.0",
|
"unplugin": "^1.4.0",
|
||||||
"url-loader": "^4.1.1",
|
"url-loader": "^4.1.1",
|
||||||
"vue-bundle-renderer": "^1.0.3",
|
"vue-bundle-renderer": "^1.0.3",
|
||||||
|
984
pnpm-lock.yaml
984
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,6 @@
|
|||||||
"main"
|
"main"
|
||||||
],
|
],
|
||||||
"ignoreDeps": [
|
"ignoreDeps": [
|
||||||
"typescript",
|
|
||||||
"markdownlint-cli",
|
"markdownlint-cli",
|
||||||
"nuxt",
|
"nuxt",
|
||||||
"nuxt3",
|
"nuxt3",
|
||||||
|
@ -19,7 +19,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
for (const outputDir of ['.output', '.output-inline']) {
|
for (const outputDir of ['.output', '.output-inline']) {
|
||||||
it('default client bundle size', async () => {
|
it('default client bundle size', async () => {
|
||||||
const clientStats = await analyzeSizes('**/*.js', join(rootDir, outputDir, 'public'))
|
const clientStats = await analyzeSizes('**/*.js', join(rootDir, outputDir, 'public'))
|
||||||
expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"97.3k"')
|
expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"97.5k"')
|
||||||
expect(clientStats.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(`
|
expect(clientStats.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
"_nuxt/entry.js",
|
"_nuxt/entry.js",
|
||||||
@ -32,7 +32,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
const serverDir = join(rootDir, '.output/server')
|
const serverDir = join(rootDir, '.output/server')
|
||||||
|
|
||||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"64.4k"')
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"64.5k"')
|
||||||
|
|
||||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2330k"')
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2330k"')
|
||||||
|
Loading…
Reference in New Issue
Block a user