mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 15:42:09 +00:00
feat: use @nuxt/design
(#322)
Co-authored-by: pooya parsa <pyapar@gmail.com>
This commit is contained in:
parent
6d0bb7c740
commit
ea0d2788a4
@ -20,6 +20,7 @@
|
|||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@nuxt/design": "0.0.4",
|
||||||
"@nuxt/kit": "^0.6.4",
|
"@nuxt/kit": "^0.6.4",
|
||||||
"@types/clear": "^0",
|
"@types/clear": "^0",
|
||||||
"@types/debounce-promise": "^3",
|
"@types/debounce-promise": "^3",
|
||||||
|
@ -22,7 +22,7 @@ export async function invoke (args) {
|
|||||||
const load = async (isRestart) => {
|
const load = async (isRestart) => {
|
||||||
try {
|
try {
|
||||||
const message = `${isRestart ? 'Restarting' : 'Starting'} nuxt...`
|
const message = `${isRestart ? 'Restarting' : 'Starting'} nuxt...`
|
||||||
server.setApp(createLoadingHandler(message, 1))
|
server.setApp(createLoadingHandler(message))
|
||||||
if (isRestart) {
|
if (isRestart) {
|
||||||
console.log(message)
|
console.log(message)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import type { RequestListener } from 'http'
|
import type { RequestListener } from 'http'
|
||||||
|
import { loading } from '@nuxt/design'
|
||||||
|
|
||||||
export function createServer () {
|
export function createServer () {
|
||||||
const listener = createDynamicFunction(createLoadingHandler('Loading...', 1))
|
const listener = createDynamicFunction(createLoadingHandler('Loading...'))
|
||||||
|
|
||||||
async function listen (opts) {
|
async function listen (opts) {
|
||||||
const { listen } = await import('listhen')
|
const { listen } = await import('listhen')
|
||||||
@ -14,12 +15,11 @@ export function createServer () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createLoadingHandler (message: string, retryAfter = 60): RequestListener {
|
export function createLoadingHandler (message: string): RequestListener {
|
||||||
return (_req, res) => {
|
return (_req, res) => {
|
||||||
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
||||||
res.statusCode = 503 /* Service Unavailable */
|
res.statusCode = 503 /* Service Unavailable */
|
||||||
res.setHeader('Retry-After', retryAfter)
|
res.end(loading({ loading: message }))
|
||||||
res.end(`<!DOCTYPE html><html><head><meta http-equiv="refresh" content="${retryAfter || 60}"></head><body>${message}</body>`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cloudflare/kv-asset-handler": "^0.1.3",
|
"@cloudflare/kv-asset-handler": "^0.1.3",
|
||||||
"@netlify/functions": "^0.7.2",
|
"@netlify/functions": "^0.7.2",
|
||||||
|
"@nuxt/design": "0.0.4",
|
||||||
"@nuxt/devalue": "^2.0.0",
|
"@nuxt/devalue": "^2.0.0",
|
||||||
"@nuxt/kit": "^0.6.4",
|
"@nuxt/kit": "^0.6.4",
|
||||||
"@rollup/plugin-alias": "^3.1.2",
|
"@rollup/plugin-alias": "^3.1.2",
|
||||||
|
@ -47,6 +47,11 @@ export async function renderMiddleware (req, res) {
|
|||||||
const renderer = await loadRenderer()
|
const renderer = await loadRenderer()
|
||||||
const rendered = await renderer.renderToString(ssrContext)
|
const rendered = await renderer.renderToString(ssrContext)
|
||||||
|
|
||||||
|
// Handle errors
|
||||||
|
if (ssrContext.error) {
|
||||||
|
throw ssrContext.error
|
||||||
|
}
|
||||||
|
|
||||||
if (ssrContext.nuxt.hooks) {
|
if (ssrContext.nuxt.hooks) {
|
||||||
await ssrContext.nuxt.hooks.callHook('app:rendered')
|
await ssrContext.nuxt.hooks.callHook('app:rendered')
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
// import ansiHTML from 'ansi-html'
|
// import ansiHTML from 'ansi-html'
|
||||||
|
import type { IncomingMessage, ServerResponse } from 'http'
|
||||||
|
import { error500, error404, errorDev } from '@nuxt/design'
|
||||||
const cwd = process.cwd()
|
const cwd = process.cwd()
|
||||||
|
|
||||||
// TODO: Handle process.env.DEBUG
|
const hasReqHeader = (req, header, includes) => req.headers[header] && req.headers[header].toLowerCase().includes(includes)
|
||||||
export function handleError (error, req, res) {
|
|
||||||
|
const isDev = process.env.NODE_ENV === 'development'
|
||||||
|
|
||||||
|
export function handleError (error, req: IncomingMessage, res: ServerResponse) {
|
||||||
|
const isJsonRequest = hasReqHeader(req, 'accept', 'application/json') || hasReqHeader(req, 'user-agent', 'curl/') || hasReqHeader(req, 'user-agent', 'httpie/')
|
||||||
|
|
||||||
const stack = (error.stack || '')
|
const stack = (error.stack || '')
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.splice(1)
|
.splice(1)
|
||||||
@ -21,47 +28,35 @@ export function handleError (error, req, res) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
console.error(error.message + '\n' + stack.map(l => ' ' + l.text).join(' \n'))
|
const is404 = error.statusCode === 404
|
||||||
|
|
||||||
const html = `
|
const errorObject = {
|
||||||
<!DOCTYPE html>
|
statusCode: error.statusCode || 500,
|
||||||
<html>
|
statusMessage: is404 ? 'Page Not Found' : 'Internal Server Error',
|
||||||
<head>
|
description: isDev && !is404
|
||||||
<meta charset="utf-8">
|
? `
|
||||||
<title>Nuxt Error</title>
|
<h1>${error.message}</h1>
|
||||||
<style>
|
<pre>${stack.map(i => `<span class="stack${i.internal ? ' internal' : ''}">${i.text}</span>`).join('\n')}</pre>
|
||||||
html, body {
|
`
|
||||||
background: white;
|
: ''
|
||||||
color: red;
|
}
|
||||||
font-family: monospace;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.stack {
|
|
||||||
padding-left: 2em;
|
|
||||||
}
|
|
||||||
.stack.internal {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
<div>${req.method} ${req.url}</div><br>
|
|
||||||
<h1>${error.toString()}</h1>
|
|
||||||
<pre>${stack.map(i =>
|
|
||||||
`<span class="stack${i.internal ? ' internal' : ''}">${i.text}</span>`
|
|
||||||
).join('\n')
|
|
||||||
}</pre>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`
|
|
||||||
|
|
||||||
res.statusCode = error.statusCode || 500
|
res.statusCode = error.statusCode || 500
|
||||||
res.statusMessage = error.statusMessage || 'Internal Error'
|
res.statusMessage = error.statusMessage || 'Internal Server Error'
|
||||||
|
|
||||||
|
// Console output
|
||||||
|
if (!is404) {
|
||||||
|
console.error(error.message + '\n' + stack.map(l => ' ' + l.text).join(' \n'))
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON response
|
||||||
|
if (isJsonRequest) {
|
||||||
|
res.setHeader('Content-Type', 'application/json')
|
||||||
|
return res.end(JSON.stringify(errorObject))
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTML response
|
||||||
|
const errorTemplate = is404 ? error404 : (isDev ? errorDev : error500)
|
||||||
|
const html = errorTemplate(errorObject)
|
||||||
res.end(html)
|
res.end(html)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Worker } from 'worker_threads'
|
import { Worker } from 'worker_threads'
|
||||||
|
|
||||||
|
import { loading as loadingTemplate } from '@nuxt/design'
|
||||||
import chokidar, { FSWatcher } from 'chokidar'
|
import chokidar, { FSWatcher } from 'chokidar'
|
||||||
import debounce from 'debounce'
|
import debounce from 'debounce'
|
||||||
import { stat } from 'fs-extra'
|
import { stat } from 'fs-extra'
|
||||||
@ -74,7 +75,7 @@ export function createDevServer (nitroContext: NitroContext) {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
||||||
res.end('<!DOCTYPE html><html><head><meta http-equiv="refresh" content="1"><head><body>...')
|
res.end(loadingTemplate({}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -36,17 +36,6 @@ export default defineNuxtModule({
|
|||||||
// Resolve routes
|
// Resolve routes
|
||||||
const routes = await resolvePagesRoutes(nuxt)
|
const routes = await resolvePagesRoutes(nuxt)
|
||||||
|
|
||||||
// Add 404 page is not added
|
|
||||||
const page404 = routes.find(route => route.name === '404')
|
|
||||||
if (!page404) {
|
|
||||||
routes.push({
|
|
||||||
name: '404',
|
|
||||||
path: '/:catchAll(.*)*',
|
|
||||||
file: resolve(runtimeDir, '404.vue'),
|
|
||||||
children: []
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add routes.js
|
// Add routes.js
|
||||||
app.templates.push({
|
app.templates.push({
|
||||||
path: 'routes.js',
|
path: 'routes.js',
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
404 | Page Not Found
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<RouterView v-slot="{ Component }">
|
<RouterView v-slot="{ Component }">
|
||||||
<NuxtLayout :name="layout || updatedComponentLayout || Component.type.layout">
|
<NuxtLayout v-if="Component" :name="layout || updatedComponentLayout || Component.type.layout">
|
||||||
<transition name="page" mode="out-in">
|
<transition name="page" mode="out-in">
|
||||||
<!-- <keep-alive> -->
|
<!-- <keep-alive> -->
|
||||||
<Suspense @pending="() => onSuspensePending(Component)" @resolve="() => onSuspenseResolved(Component)">
|
<Suspense @pending="() => onSuspensePending(Component)" @resolve="() => onSuspenseResolved(Component)">
|
||||||
@ -9,6 +9,7 @@
|
|||||||
<!-- <keep-alive -->
|
<!-- <keep-alive -->
|
||||||
</transition>
|
</transition>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
<!-- TODO: Handle 404 placeholder -->
|
||||||
</RouterView>
|
</RouterView>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -43,13 +43,15 @@ export default defineNuxtPlugin((nuxt) => {
|
|||||||
if (process.server) {
|
if (process.server) {
|
||||||
router.push(nuxt.ssrContext.url)
|
router.push(nuxt.ssrContext.url)
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
await router.isReady()
|
await router.isReady()
|
||||||
if (!router.currentRoute.value.matched.length) {
|
|
||||||
// TODO
|
const is404 = router.currentRoute.value.matched.length === 0
|
||||||
}
|
if (process.server && is404) {
|
||||||
} catch (err) {
|
const error = new Error(`Page not found: ${nuxt.ssrContext.url}`)
|
||||||
// TODO
|
// @ts-ignore
|
||||||
|
error.statusCode = 404
|
||||||
|
nuxt.ssrContext.error = error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1305,6 +1305,13 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"@nuxt/design@npm:0.0.4":
|
||||||
|
version: 0.0.4
|
||||||
|
resolution: "@nuxt/design@npm:0.0.4"
|
||||||
|
checksum: c28506ff41e26721dc1f3a3101d9d2824b3b44e17b4abf1ab246bc2777a49d743fc42b8b1e056460934461892b3af28c4ee96524a1c61d099ad02c23fc22f115
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@nuxt/devalue@npm:^2.0.0":
|
"@nuxt/devalue@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "@nuxt/devalue@npm:2.0.0"
|
resolution: "@nuxt/devalue@npm:2.0.0"
|
||||||
@ -1354,6 +1361,7 @@ __metadata:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@cloudflare/kv-asset-handler": ^0.1.3
|
"@cloudflare/kv-asset-handler": ^0.1.3
|
||||||
"@netlify/functions": ^0.7.2
|
"@netlify/functions": ^0.7.2
|
||||||
|
"@nuxt/design": 0.0.4
|
||||||
"@nuxt/devalue": ^2.0.0
|
"@nuxt/devalue": ^2.0.0
|
||||||
"@nuxt/kit": ^0.6.4
|
"@nuxt/kit": ^0.6.4
|
||||||
"@rollup/plugin-alias": ^3.1.2
|
"@rollup/plugin-alias": ^3.1.2
|
||||||
@ -8531,6 +8539,7 @@ fsevents@~2.3.2:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "nuxt-cli@workspace:packages/cli"
|
resolution: "nuxt-cli@workspace:packages/cli"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@nuxt/design": 0.0.4
|
||||||
"@nuxt/kit": ^0.6.4
|
"@nuxt/kit": ^0.6.4
|
||||||
"@types/clear": ^0
|
"@types/clear": ^0
|
||||||
"@types/debounce-promise": ^3
|
"@types/debounce-promise": ^3
|
||||||
|
Loading…
Reference in New Issue
Block a user