feat: use @nuxt/design (#322)

Co-authored-by: pooya parsa <pyapar@gmail.com>
This commit is contained in:
Daniel Roe 2021-07-15 10:47:15 +01:00 committed by GitHub
parent 6d0bb7c740
commit ea0d2788a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 70 additions and 71 deletions

View File

@ -20,6 +20,7 @@
"fsevents": "~2.3.2"
},
"devDependencies": {
"@nuxt/design": "0.0.4",
"@nuxt/kit": "^0.6.4",
"@types/clear": "^0",
"@types/debounce-promise": "^3",

View File

@ -22,7 +22,7 @@ export async function invoke (args) {
const load = async (isRestart) => {
try {
const message = `${isRestart ? 'Restarting' : 'Starting'} nuxt...`
server.setApp(createLoadingHandler(message, 1))
server.setApp(createLoadingHandler(message))
if (isRestart) {
console.log(message)
}

View File

@ -1,7 +1,8 @@
import type { RequestListener } from 'http'
import { loading } from '@nuxt/design'
export function createServer () {
const listener = createDynamicFunction(createLoadingHandler('Loading...', 1))
const listener = createDynamicFunction(createLoadingHandler('Loading...'))
async function listen (opts) {
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) => {
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
res.statusCode = 503 /* Service Unavailable */
res.setHeader('Retry-After', retryAfter)
res.end(`<!DOCTYPE html><html><head><meta http-equiv="refresh" content="${retryAfter || 60}"></head><body>${message}</body>`)
res.end(loading({ loading: message }))
}
}

View File

@ -15,6 +15,7 @@
"dependencies": {
"@cloudflare/kv-asset-handler": "^0.1.3",
"@netlify/functions": "^0.7.2",
"@nuxt/design": "0.0.4",
"@nuxt/devalue": "^2.0.0",
"@nuxt/kit": "^0.6.4",
"@rollup/plugin-alias": "^3.1.2",

View File

@ -47,6 +47,11 @@ export async function renderMiddleware (req, res) {
const renderer = await loadRenderer()
const rendered = await renderer.renderToString(ssrContext)
// Handle errors
if (ssrContext.error) {
throw ssrContext.error
}
if (ssrContext.nuxt.hooks) {
await ssrContext.nuxt.hooks.callHook('app:rendered')
}

View File

@ -1,8 +1,15 @@
// import ansiHTML from 'ansi-html'
import type { IncomingMessage, ServerResponse } from 'http'
import { error500, error404, errorDev } from '@nuxt/design'
const cwd = process.cwd()
// TODO: Handle process.env.DEBUG
export function handleError (error, req, res) {
const hasReqHeader = (req, header, includes) => req.headers[header] && req.headers[header].toLowerCase().includes(includes)
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 || '')
.split('\n')
.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 = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Nuxt Error</title>
<style>
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>
`
const errorObject = {
statusCode: error.statusCode || 500,
statusMessage: is404 ? 'Page Not Found' : 'Internal Server Error',
description: isDev && !is404
? `
<h1>${error.message}</h1>
<pre>${stack.map(i => `<span class="stack${i.internal ? ' internal' : ''}">${i.text}</span>`).join('\n')}</pre>
`
: ''
}
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)
}

View File

@ -1,5 +1,6 @@
import { Worker } from 'worker_threads'
import { loading as loadingTemplate } from '@nuxt/design'
import chokidar, { FSWatcher } from 'chokidar'
import debounce from 'debounce'
import { stat } from 'fs-extra'
@ -74,7 +75,7 @@ export function createDevServer (nitroContext: NitroContext) {
})
} else {
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({}))
}
})

View File

@ -36,17 +36,6 @@ export default defineNuxtModule({
// Resolve routes
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
app.templates.push({
path: 'routes.js',

View File

@ -1,5 +0,0 @@
<template>
<div>
404 | Page Not Found
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<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">
<!-- <keep-alive> -->
<Suspense @pending="() => onSuspensePending(Component)" @resolve="() => onSuspenseResolved(Component)">
@ -9,6 +9,7 @@
<!-- <keep-alive -->
</transition>
</NuxtLayout>
<!-- TODO: Handle 404 placeholder -->
</RouterView>
</template>

View File

@ -43,13 +43,15 @@ export default defineNuxtPlugin((nuxt) => {
if (process.server) {
router.push(nuxt.ssrContext.url)
}
try {
await router.isReady()
if (!router.currentRoute.value.matched.length) {
// TODO
}
} catch (err) {
// TODO
await router.isReady()
const is404 = router.currentRoute.value.matched.length === 0
if (process.server && is404) {
const error = new Error(`Page not found: ${nuxt.ssrContext.url}`)
// @ts-ignore
error.statusCode = 404
nuxt.ssrContext.error = error
}
})
})

View File

@ -1305,6 +1305,13 @@ __metadata:
languageName: unknown
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":
version: 2.0.0
resolution: "@nuxt/devalue@npm:2.0.0"
@ -1354,6 +1361,7 @@ __metadata:
dependencies:
"@cloudflare/kv-asset-handler": ^0.1.3
"@netlify/functions": ^0.7.2
"@nuxt/design": 0.0.4
"@nuxt/devalue": ^2.0.0
"@nuxt/kit": ^0.6.4
"@rollup/plugin-alias": ^3.1.2
@ -8531,6 +8539,7 @@ fsevents@~2.3.2:
version: 0.0.0-use.local
resolution: "nuxt-cli@workspace:packages/cli"
dependencies:
"@nuxt/design": 0.0.4
"@nuxt/kit": ^0.6.4
"@types/clear": ^0
"@types/debounce-promise": ^3