chore(ts): fix types in server (#18)

* chore(ts): fix types in server

* fix serviceConfig
This commit is contained in:
Xin Du (Clark) 2020-08-17 10:13:46 +01:00 committed by GitHub
parent b82d75d883
commit e266992fac
9 changed files with 52 additions and 22 deletions

View File

@ -67,7 +67,7 @@ interface RenderOptions {
resourceHints: boolean
ssr?: boolean
ssrLog?: boolean | 'collapsed'
static: ServeStaticOptions
static: ServeStaticOptions & { prefix?: string }
}
export default (): RenderOptions => ({

View File

@ -1,3 +1,4 @@
import type { IncomingHttpHeaders } from 'http'
import isPlainObject from 'lodash/isPlainObject'
import consola from 'consola'
@ -20,6 +21,7 @@ export default class Nuxt extends Hookable {
_ready?: Promise<this>
_initCalled?: boolean
error?: Error & { statusCode?: number, headers?: IncomingHttpHeaders }
options: NormalizedConfiguration
resolver: Resolver
moduleContainer: ModuleContainer

View File

@ -1,5 +1,5 @@
import consola from 'consola'
import { BaseOptions, DOMWindow, VirtualConsole } from 'jsdom'
import { BaseOptions, DOMWindow } from 'jsdom'
import { DeterminedGlobals, timeout } from 'src/utils'
interface Options {

View File

@ -6,13 +6,15 @@ import ip from 'ip'
import consola from 'consola'
import pify from 'pify'
import type { NormalizedConfiguration } from 'src/config'
let RANDOM_PORT = '0'
interface ListenerOptions {
port: number | string
host: string
socket: string
https: boolean
https: NormalizedConfiguration['server']['https']
app: any
dev: boolean
baseURL: string
@ -22,7 +24,7 @@ export default class Listener {
port: number | string
host: string
socket: string
https: boolean
https: NormalizedConfiguration['server']['https']
app: any
dev: boolean
baseURL: string
@ -102,7 +104,7 @@ export default class Listener {
try {
this.server = await new Promise((resolve, reject) => {
this._server.on('error', error => reject(error))
const s = this._server.listen(listenArgs, error => error ? reject(error) : resolve(s))
const s = this._server.listen(listenArgs, () => resolve(s))
})
} catch (error) {
return this.serverErrorHandler(error)

View File

@ -1,10 +1,13 @@
import type { IncomingMessage, ServerResponse } from 'http'
import path from 'path'
import fs from 'fs-extra'
import consola from 'consola'
import Youch from '@nuxtjs/youch'
export default ({ resources, options }) => async function errorMiddleware (_error, req, res, next) {
import type { Nuxt } from 'src/core'
export default ({ resources, options }) => async function errorMiddleware (_error, req: IncomingMessage, res: ServerResponse) {
// Normalize error
const error = normalizeError(_error, options)
@ -28,8 +31,12 @@ export default ({ resources, options }) => async function errorMiddleware (_erro
}
// Check if request accepts JSON
const hasReqHeader = (header, includes) =>
req.headers[header] && req.headers[header].toLowerCase().includes(includes)
const hasReqHeader = (header, includes) => {
const headerValue = req.headers[header]
if (typeof headerValue === 'string') {
return headerValue.toLowerCase().includes(includes)
}
}
const isJson =
hasReqHeader('accept', 'application/json') ||
hasReqHeader('user-agent', 'curl/')
@ -76,14 +83,14 @@ export default ({ resources, options }) => async function errorMiddleware (_erro
const sanitizeName = name => name ? name.replace('webpack:///', '').split('?')[0] : null
const normalizeError = (_error, { srcDir, rootDir, buildDir }) => {
const normalizeError = (_error, { srcDir, rootDir, buildDir }) : Nuxt['error'] => {
if (typeof _error === 'string') {
_error = { message: _error }
} else if (!_error) {
_error = { message: '<empty>' }
}
const error = new Error()
const error: Nuxt['error'] = new Error()
error.message = _error.message
error.name = _error.name
error.statusCode = _error.statusCode || 500

View File

@ -1,3 +1,5 @@
import type { RenderContext } from 'src/vue-renderer/renderer'
import generateETag from 'etag'
import fresh from 'fresh'
import consola from 'consola'
@ -6,7 +8,7 @@ import { getContext, TARGETS } from 'src/utils'
export default ({ options, nuxt, renderRoute, resources }) => async function nuxtMiddleware (req, res, next) {
// Get context
const context = getContext(req, res)
const context: RenderContext = getContext(req, res)
try {
const url = decodeURI(req.url)

View File

@ -25,6 +25,12 @@ interface Manifest {
async: Array<string>
}
type NuxtMiddleware = connect.HandleFunction & {
prefix?: string,
entry?: string,
_middleware?: NuxtMiddleware
}
export default class Server {
__closed?: boolean
_readyCalled?: boolean
@ -123,10 +129,11 @@ export default class Server {
}
// For serving static/ files to /
const staticMiddleware = serveStatic(
const staticMiddleware : NuxtMiddleware = serveStatic(
path.resolve(this.options.srcDir, this.options.dir.static),
this.options.render.static
)
staticMiddleware.prefix = this.options.render.static.prefix
this.useMiddleware(staticMiddleware)
@ -234,7 +241,7 @@ export default class Server {
// No handle
if (!middleware.handle) {
middleware.handle = (req, res, next) => {
middleware.handle = (_req, _res, next) => {
next(new Error('ServerMiddleware should expose a handle: ' + middleware.entry))
}
}
@ -266,7 +273,7 @@ export default class Server {
consola.error('ServerMiddleware Error:', error)
// Placeholder for error
middleware = (req, res, next) => { next(error) }
middleware = (_req, _res, next) => { next(error) }
}
// Normalize
@ -314,7 +321,10 @@ export default class Server {
if (typeof query === 'string') {
// Search by entry
serverStackItem = this.app.stack.find(({ handle }) => handle._middleware && handle._middleware.entry === query)
serverStackItem = this.app.stack.find(({ handle }) => {
const middleware = (handle as NuxtMiddleware)._middleware
return middleware && middleware.entry === query
})
} else {
// Search by reference
serverStackItem = this.app.stack.find(({ handle }) => handle === query)
@ -348,7 +358,10 @@ export default class Server {
}
serverMiddlewarePaths () {
return this.app.stack.map(({ handle }) => handle._middleware && handle._middleware.entry).filter(Boolean)
return this.app.stack.map(({ handle }) => {
const middleware = (handle as NuxtMiddleware)._middleware
return middleware && middleware.entry
}).filter(Boolean)
}
renderRoute () {
@ -375,12 +388,14 @@ export default class Server {
// Ensure nuxt is ready
await this.nuxt.ready()
const serviceConfig = typeof this.options.server === 'object' ? this.options.server : {}
// Create a new listener
const listener = new Listener({
port: typeof port !== 'number' && isNaN(parseInt(port)) ? this.options.server.port : port,
host: host || this.options.server.host,
socket: socket || this.options.server.socket,
https: this.options.server.https,
port: typeof port !== 'number' && isNaN(parseInt(port)) ? serviceConfig.port : port,
host: host || serviceConfig.host,
socket: socket || serviceConfig.socket,
https: serviceConfig.https,
app: this.app,
dev: this.options.dev,
baseURL: this.options.router.base

View File

@ -17,6 +17,8 @@ export interface RenderContext {
target?: Target
spa?: boolean
modern?: boolean
nuxt?: ServerContext['nuxt']
redirected?: boolean
req?: any
res?: any
runtimeConfig?: {

View File

@ -210,7 +210,7 @@ export default class SSRRenderer extends BaseRenderer {
// Page level payload.js (async loaded for CSR)
const payloadPath = urlJoin(url, 'payload.js')
const payloadUrl = urlJoin(routerBase, staticAssetsBase, payloadPath)
const routePath = (url.replace(/\/+$/, '') || '/').split('?')[0] // remove trailing slah and query params
const routePath = (url.replace(/\/+$/, '') || '/').split('?')[0] // remove trailing slash and query params
const payloadScript = `__NUXT_JSONP__("${routePath}", ${devalue({ data, fetch, mutations })});`
staticAssets.push({ path: payloadPath, src: payloadScript })
preloadScripts.push(payloadUrl)