mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
Merge branch 'main' into docs/kit
This commit is contained in:
commit
5fda425e86
1
.github/assets/banner.svg
vendored
Normal file
1
.github/assets/banner.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 10 KiB |
145
README.md
145
README.md
@ -1,113 +1,52 @@
|
|||||||
|
[![Nuxt banner](./.github/assets/banner.svg)](https://nuxt.com)
|
||||||
|
|
||||||
[![Nuxt banner](./.github/assets/banner.png)](https://nuxt.com)
|
# Nuxt
|
||||||
|
|
||||||
# 👋 Welcome to Nuxt
|
<p>
|
||||||
|
|
||||||
|
|
||||||
Nuxt's goal is to make web development intuitive and performant, with a great developer experience.<br>Learn more in the ['What is Nuxt?'](https://nuxt.com/docs/getting-started/introduction) section of our documentation.
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/v/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a>
|
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/v/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a>
|
||||||
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/dm/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a>
|
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/dm/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a>
|
||||||
<a href="./LICENSE"><img src="https://img.shields.io/github/license/nuxt/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="License"></a>
|
<a href="./LICENSE"><img src="https://img.shields.io/github/license/nuxt/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="License"></a>
|
||||||
<a href="https://nuxt.com"><img src="https://img.shields.io/badge/Open%20Documentation-18181B?logo=nuxt.js" alt="Website"></a>
|
<a href="https://nuxt.com"><img src="https://img.shields.io/badge/Nuxt%20Docs-18181B?logo=nuxt.js" alt="Website"></a>
|
||||||
<a href="https://volta.net/nuxt/nuxt?utm_source=nuxt_readme"><img src="https://user-images.githubusercontent.com/904724/209143798-32345f6c-3cf8-4e06-9659-f4ace4a6acde.svg" alt="Volta board"></a>
|
<a href="https://chat.nuxt.dev"><img src="https://img.shields.io/badge/Nuxt%20Discord-18181B?logo=discord" alt="Discord"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table>
|
Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th width="2000" colspan="2">
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td width="80" align="center" valign="top">
|
|
||||||
<br>
|
|
||||||
<a href="https://nuxt.com/docs"><img src="./.github/assets/documentation.png"></a>
|
|
||||||
</td>
|
|
||||||
<td valign="top">
|
|
||||||
<h3>Documentation</h3>
|
|
||||||
<p>
|
|
||||||
We highly recommend you take a look at <a href="https://nuxt.com">the Nuxt documentation</a> to level up.
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="80" align="center" valign="top">
|
|
||||||
<br>
|
|
||||||
<a href="https://nuxt.com/modules"><img src="./.github/assets/modules.png"></a>
|
|
||||||
</td>
|
|
||||||
<td valign="top">
|
|
||||||
<h3>Modules</h3>
|
|
||||||
<p>
|
|
||||||
Discover our <a href="https://nuxt.com/modules">list of modules</a> to supercharge your Nuxt project. Created by the Nuxt team and community.
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="80" align="center" valign="top">
|
|
||||||
<br>
|
|
||||||
<a href="https://nuxt.com/docs/examples/hello-world"><img src="./.github/assets/examples.png"></a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<h3>Examples</h3>
|
|
||||||
<p>
|
|
||||||
Explore different ways of using Nuxt features and get inspired with <a href="https://nuxt.com/docs/examples/hello-world">our list of examples</a>.
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<table>
|
It provides a number of features that make it easy to build fast, SEO-friendly, and scalable web applications, including:
|
||||||
<thead>
|
- Server-side rendering, Static Site Generation or Hybrid Rendering
|
||||||
<tr>
|
- Automatic routing with code-splitting
|
||||||
<th width="2000" colspan="2">
|
- State management
|
||||||
</th>
|
- SEO Optimization
|
||||||
</tr>
|
- Extandable with [100+ modules](https://nuxt.com/modules)
|
||||||
</thead>
|
- Deployment to a variety of hosting platforms
|
||||||
<tbody>
|
- ...[and much more](https://nuxt.com) 🚀
|
||||||
<tr>
|
|
||||||
<td width="80" align="center" valign="top">
|
## Getting Started
|
||||||
<br>
|
|
||||||
<a href="https://nuxt.com/docs/community/reporting-bugs"><img src="./.github/assets/reporting-bugs.png"></a>
|
Use the following command to create a new starter project. This will create a starter project with all the necessary files and dependencies:
|
||||||
</td>
|
|
||||||
<td valign="top">
|
```bash
|
||||||
<h3>Reporting bugs</h3>
|
npx nuxi@latest nuxi init <my-project>
|
||||||
<p>
|
```
|
||||||
Check out the <a href="https://nuxt.com/docs/community/reporting-bugs">Reporting Bugs</a> page.</p>
|
|
||||||
</p>
|
Discover also [nuxt.new](https://nuxt.new): Open a Nuxt starter on CodeSandbox, StackBlitz or locally to get up and running in a few seconds.
|
||||||
</td>
|
|
||||||
</tr>
|
## Documentation
|
||||||
<tr>
|
|
||||||
<td width="80" align="center" valign="top">
|
We highly recommend you take a look at the [Nuxt documentation](https://nuxt.com/docs) to level up. It’s a great resource for learning more about the framework. It covers everything from getting started to advanced topics.
|
||||||
<br>
|
|
||||||
<a href="https://nuxt.com/docs/community/contribution"><img src="./.github/assets/suggestions.png"></a>
|
## Modules
|
||||||
</td>
|
|
||||||
<td valign="top">
|
Discover our [list of modules](https://nuxt.com/modules) to supercharge your Nuxt project, created by the Nuxt team and community.
|
||||||
<h3>Suggestions</h3>
|
|
||||||
<p>
|
## Contribute
|
||||||
Check out the <a href="https://nuxt.com/docs/community/contribution">Contribution</a> page.
|
|
||||||
</p>
|
We invite you to contribute and help improve Nuxt 💚
|
||||||
</td>
|
|
||||||
</tr>
|
Here are a few ways you can get involved:
|
||||||
<tr>
|
- **Reporting Bugs:** If you come across any bugs or issues, please check out the [reporting bugs guide](https://nuxt.com/docs/community/reporting-bugs) to learn how to submit a bug report.
|
||||||
<td width="80" align="center" valign="top">
|
- **Suggestions:** Have ideas to enhance Nuxt? We'd love to hear them! Check out the [contribution guide](https://nuxt.com/docs/community/contribution#creating-an-issue) to share your suggestions.
|
||||||
<br>
|
- **Questions:** If you have questions or need assistance, the [getting help guide](https://nuxt.com/docs/community/getting-help) provides resources to help you out.
|
||||||
<a href="https://nuxt.com/docs/community/getting-help"><img src="./.github/assets/questions.png"></a>
|
|
||||||
</td>
|
|
||||||
<td valign="top">
|
|
||||||
<h3>Questions</h3>
|
|
||||||
<p>
|
|
||||||
Check out the <a href="https://nuxt.com/docs/community/getting-help">Getting Help</a> page.
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## Local Development
|
## Local Development
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ If you want more control over when the `<NuxtPage>` component is re-rendered (fo
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1>I am the parent view</h1>
|
<h1>I am the parent view</h1>
|
||||||
<NuxtPage :page-key="someKey" />
|
<NuxtPage :page-key="route => route.fullPath" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
@ -34,7 +34,7 @@ If you have a [`pages/`](/docs/guide/directory-structure/pages) directory, to di
|
|||||||
```
|
```
|
||||||
|
|
||||||
::alert{type=danger}
|
::alert{type=danger}
|
||||||
Since Nuxt 3 uses [`<Suspense>`](https://vuejs.org/guide/built-ins/suspense.html#suspense) inside `<NuxtPage>`, it cannot be set as a root element.
|
Since `<NuxtPage>` internally uses the [`<Suspense>`](https://vuejs.org/guide/built-ins/suspense.html#suspense) component, `<NuxtPage>` cannot be set as a root element.
|
||||||
::
|
::
|
||||||
|
|
||||||
::alert{type=warning}
|
::alert{type=warning}
|
||||||
|
@ -34,6 +34,12 @@ For example, passing `static` key, `NuxtPage` component is rendered only once wh
|
|||||||
<NuxtPage page-key="static" />
|
<NuxtPage page-key="static" />
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also use a dynamic key based on the current route. (Don't use `$route` object here as it can cause problems with how `<NuxtPage>` renders pages with `<Suspense>`.)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<NuxtPage :page-key="route => route.fullPath" />
|
||||||
|
```
|
||||||
|
|
||||||
Alternatively, `pageKey` can be passed as a `key` value via `definePageMeta` from the `<script>` section of your Vue component in the `/pages` directory.
|
Alternatively, `pageKey` can be passed as a `key` value via `definePageMeta` from the `<script>` section of your Vue component in the `/pages` directory.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -13,8 +13,7 @@ There is a range of different ways you might be able to contribute to the Nuxt e
|
|||||||
The Nuxt ecosystem includes many different projects and organizations. For example:
|
The Nuxt ecosystem includes many different projects and organizations. For example:
|
||||||
|
|
||||||
* [nuxt/](https://github.com/nuxt) - core repositories for the Nuxt framework itself. [**nuxt/nuxt**](https://github.com/nuxt/nuxt) contains the Nuxt framework (both versions 2 and 3).
|
* [nuxt/](https://github.com/nuxt) - core repositories for the Nuxt framework itself. [**nuxt/nuxt**](https://github.com/nuxt/nuxt) contains the Nuxt framework (both versions 2 and 3).
|
||||||
* [nuxt-community/](https://github.com/nuxt-community) - community-contributed and maintained modules and libraries. There is a [process to migrate a module](/docs/guide/going-further/modules/#joining-nuxt-community) to `nuxt-community`. While these modules have individual maintainers, they are not dependent on a single person.
|
* [nuxt-modules/](https://github.com/nuxt-modules) - community-contributed and maintained modules and libraries. There is a [process to migrate a module](/docs/guide/going-further/modules/#joining-nuxt-modules-and-nuxtjs) to `nuxt-modules`. While these modules have individual maintainers, they are not dependent on a single person.
|
||||||
* [nuxt-contrib/](https://github.com/nuxt-contrib) - the previous home for libraries that are not specific to Nuxt but produced and used by the Nuxt team.
|
|
||||||
* [unjs/](https://github.com/unjs) - many of these libraries are used throughout the Nuxt ecosystem. They are designed to be universal libraries that are framework- and environment-agnostic. We welcome contributions and usage by other frameworks and projects.
|
* [unjs/](https://github.com/unjs) - many of these libraries are used throughout the Nuxt ecosystem. They are designed to be universal libraries that are framework- and environment-agnostic. We welcome contributions and usage by other frameworks and projects.
|
||||||
|
|
||||||
## How To Contribute
|
## How To Contribute
|
||||||
|
@ -12,6 +12,7 @@ export async function addComponentsDir (dir: ComponentsDir) {
|
|||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
await assertNuxtCompatibility({ nuxt: '>=2.13' }, nuxt)
|
await assertNuxtCompatibility({ nuxt: '>=2.13' }, nuxt)
|
||||||
nuxt.options.components = nuxt.options.components || []
|
nuxt.options.components = nuxt.options.components || []
|
||||||
|
dir.priority ||= 0
|
||||||
nuxt.hook('components:dirs', (dirs) => { dirs.push(dir) })
|
nuxt.hook('components:dirs', (dirs) => { dirs.push(dir) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { useNuxt } from './context'
|
|||||||
import { logger } from './logger'
|
import { logger } from './logger'
|
||||||
import { addTemplate } from './template'
|
import { addTemplate } from './template'
|
||||||
|
|
||||||
export function addLayout (this: any, template: NuxtTemplate, name?: string) {
|
export function addLayout (this: any, template: NuxtTemplate | string, name?: string) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
const { filename, src } = addTemplate(template)
|
const { filename, src } = addTemplate(template)
|
||||||
const layoutName = kebabCase(name || parse(filename).name).replace(/["']/g, '')
|
const layoutName = kebabCase(name || parse(filename).name).replace(/["']/g, '')
|
||||||
|
@ -58,7 +58,7 @@ function getRouteFromPath (fullPath: string | Partial<Route>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type RouteGuardReturn = void | Error | string | false
|
type RouteGuardReturn = void | Error | string | boolean
|
||||||
|
|
||||||
interface RouteGuard {
|
interface RouteGuard {
|
||||||
(to: Route, from: Route): RouteGuardReturn | Promise<RouteGuardReturn>
|
(to: Route, from: Route): RouteGuardReturn | Promise<RouteGuardReturn>
|
||||||
@ -130,7 +130,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
|
|||||||
// Cancel navigation
|
// Cancel navigation
|
||||||
if (result === false || result instanceof Error) { return }
|
if (result === false || result instanceof Error) { return }
|
||||||
// Redirect
|
// Redirect
|
||||||
if (result) { return handleNavigation(result, true) }
|
if (typeof result === 'string' && result.length) { return handleNavigation(result, true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const handler of hooks['resolve:before']) {
|
for (const handler of hooks['resolve:before']) {
|
||||||
@ -250,6 +250,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
|
|||||||
return nuxtApp.runWithContext(() => showError(error))
|
return nuxtApp.runWithContext(() => showError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result === true) { continue }
|
||||||
if (result || result === false) { return result }
|
if (result || result === false) { return result }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
|
|||||||
shortPath,
|
shortPath,
|
||||||
export: 'default',
|
export: 'default',
|
||||||
// by default, give priority to scanned components
|
// by default, give priority to scanned components
|
||||||
priority: 1
|
priority: dir.priority ?? 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof dir.extendComponent === 'function') {
|
if (typeof dir.extendComponent === 'function') {
|
||||||
@ -135,9 +135,15 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
const existingComponent = components.find(c => c.pascalName === component.pascalName && ['all', component.mode].includes(c.mode))
|
const existingComponent = components.find(c => c.pascalName === component.pascalName && ['all', component.mode].includes(c.mode))
|
||||||
if (existingComponent) {
|
|
||||||
// Ignore component if component is already defined (with same mode)
|
// Ignore component if component is already defined (with same mode)
|
||||||
|
if (existingComponent) {
|
||||||
|
const existingPriority = existingComponent.priority ?? 0
|
||||||
|
const newPriority = component.priority ?? 0
|
||||||
|
|
||||||
|
if (newPriority >= existingPriority) {
|
||||||
warnAboutDuplicateComponent(componentName, filePath, existingComponent.filePath)
|
warnAboutDuplicateComponent(componentName, filePath, existingComponent.filePath)
|
||||||
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ export default defineNuxtPlugin({
|
|||||||
nuxtApp.hooks.hook('page:start', () => { pauseDOMUpdates = true })
|
nuxtApp.hooks.hook('page:start', () => { pauseDOMUpdates = true })
|
||||||
// wait for new page before unpausing dom updates (triggered after suspense resolved)
|
// wait for new page before unpausing dom updates (triggered after suspense resolved)
|
||||||
nuxtApp.hooks.hook('page:finish', syncHead)
|
nuxtApp.hooks.hook('page:finish', syncHead)
|
||||||
|
// unpause on error
|
||||||
|
nuxtApp.hooks.hook('app:error', syncHead)
|
||||||
// unpause the DOM once the mount suspense is resolved
|
// unpause the DOM once the mount suspense is resolved
|
||||||
nuxtApp.hooks.hook('app:suspense:resolve', syncHead)
|
nuxtApp.hooks.hook('app:suspense:resolve', syncHead)
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result === true) { continue }
|
||||||
if (result || result === false) {
|
if (result || result === false) {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,14 @@ export interface ComponentsDir extends ScanDir {
|
|||||||
* By default ('auto') it will set transpile: true if node_modules/ is in path.
|
* By default ('auto') it will set transpile: true if node_modules/ is in path.
|
||||||
*/
|
*/
|
||||||
transpile?: 'auto' | boolean
|
transpile?: 'auto' | boolean
|
||||||
|
/**
|
||||||
|
* This number allows configuring the behavior of overriding Nuxt components.
|
||||||
|
* It will be inherited by any components within the directory.
|
||||||
|
*
|
||||||
|
* If multiple components are provided with the same name, then higher priority
|
||||||
|
* components will be used instead of lower priority components.
|
||||||
|
*/
|
||||||
|
priority?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentsOptions {
|
export interface ComponentsOptions {
|
||||||
|
@ -5,7 +5,7 @@ import { determineBumpType, loadWorkspace } from './_utils'
|
|||||||
const nightlyPackages = {
|
const nightlyPackages = {
|
||||||
nitropack: 'nitropack-edge',
|
nitropack: 'nitropack-edge',
|
||||||
h3: 'h3-nightly',
|
h3: 'h3-nightly',
|
||||||
nuxi: 'nuxi-ng'
|
nuxi: 'nuxi-edge'
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main () {
|
async function main () {
|
||||||
|
@ -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('"96.9k"')
|
expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"97.0k"')
|
||||||
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",
|
||||||
|
@ -4,4 +4,5 @@ export default defineNuxtRouteMiddleware((to) => {
|
|||||||
statusCode: 401
|
statusCode: 401
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user