mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
chore(ts): fix types in renderer (#16)
This commit is contained in:
parent
d6ae2c73d9
commit
b82d75d883
@ -5,7 +5,7 @@ type Plugin = string | { mode?: 'all' | 'client' | 'server', src: string, ssr?:
|
||||
|
||||
interface AppOptions {
|
||||
css: string[]
|
||||
head: MetaInfo
|
||||
head: MetaInfo | (() => MetaInfo)
|
||||
ErrorPage: null | string
|
||||
extendPlugins: null | ((plugins: Plugin[]) => Plugin[])
|
||||
features: {
|
||||
|
@ -108,7 +108,7 @@ interface CommonConfiguration {
|
||||
ignore: Array<string | IgnoreInstance>
|
||||
// TODO: remove in Nuxt 3
|
||||
mode: Mode
|
||||
modern?: boolean
|
||||
modern?: boolean | 'client' | 'server'
|
||||
modules: NuxtModule[]
|
||||
privateRuntimeConfig: Record<string, any> | ((env: NodeJS.ProcessEnv) => Record<string, any>)
|
||||
publicRuntimeConfig: Record<string, any> | ((env: NodeJS.ProcessEnv) => Record<string, any>)
|
||||
|
@ -27,7 +27,7 @@ type CspPolicyName = 'child-src' | 'connect-src' | 'default-src' | 'font-src' |
|
||||
|
||||
interface RenderOptions {
|
||||
bundleRenderer: {
|
||||
shouldPrefetch: () => boolean
|
||||
shouldPrefetch: (fileWithoutQuery: string, asType: string) => boolean
|
||||
shouldPreload: (fileWithoutQuery: string, asType: string) => boolean
|
||||
runInNewContext?: boolean
|
||||
}
|
||||
@ -63,6 +63,7 @@ interface RenderOptions {
|
||||
preloadFiles: PreloadFile[]
|
||||
) => string[])
|
||||
}
|
||||
injectScripts?: boolean
|
||||
resourceHints: boolean
|
||||
ssr?: boolean
|
||||
ssrLog?: boolean | 'collapsed'
|
||||
|
@ -21,6 +21,8 @@ import createTimingMiddleware from './middleware/timing'
|
||||
interface Manifest {
|
||||
assetsMapping: Record<string, string[]>
|
||||
publicPath: string
|
||||
initial: Array<string>
|
||||
async: Array<string>
|
||||
}
|
||||
|
||||
export default class Server {
|
||||
@ -37,6 +39,7 @@ export default class Server {
|
||||
renderer: VueRenderer
|
||||
resources: {
|
||||
clientManifest?: Manifest
|
||||
loadingHTML?: string
|
||||
modernManifest?: Manifest
|
||||
serverManifest?: Manifest
|
||||
ssrTemplate?: TemplateExecutor
|
||||
|
@ -65,7 +65,7 @@ export const isModernBrowser = (ua: string) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const isModernRequest = (req: NuxtRequest, modernMode = false) => {
|
||||
export const isModernRequest = (req: NuxtRequest, modernMode: boolean | string = false) => {
|
||||
if (modernMode === false) {
|
||||
return false
|
||||
}
|
||||
|
@ -2,19 +2,37 @@ import path from 'path'
|
||||
import fs from 'fs-extra'
|
||||
import consola from 'consola'
|
||||
import template from 'lodash/template'
|
||||
import { TARGETS, isModernRequest, waitFor } from 'src/utils'
|
||||
import { Target, TARGETS, isModernRequest, waitFor } from 'src/utils'
|
||||
|
||||
import ServerContext from 'src/server/context'
|
||||
import SPARenderer from './renderers/spa'
|
||||
import SSRRenderer from './renderers/ssr'
|
||||
import ModernRenderer from './renderers/modern'
|
||||
|
||||
declare module 'fs-extra' {
|
||||
export function exists(path: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface RenderContext {
|
||||
target?: Target
|
||||
spa?: boolean
|
||||
modern?: boolean
|
||||
req?: any
|
||||
res?: any
|
||||
runtimeConfig?: {
|
||||
private: ServerContext['options']['privateRuntimeConfig'],
|
||||
public: ServerContext['options']['publicRuntimeConfig']
|
||||
}
|
||||
url?: string
|
||||
}
|
||||
|
||||
export default class VueRenderer {
|
||||
__closed?: boolean
|
||||
_state?: 'created' | 'loading' | 'ready' | 'error'
|
||||
_error?: null
|
||||
_readyPromise?: Promise<any>
|
||||
distPath: string
|
||||
options: ServerContext['options']
|
||||
serverContext: ServerContext
|
||||
renderer: {
|
||||
ssr: any
|
||||
@ -252,7 +270,7 @@ export default class VueRenderer {
|
||||
return renderer.render(renderContext)
|
||||
}
|
||||
|
||||
async renderRoute (url, renderContext = {}, _retried = 0) {
|
||||
async renderRoute (url, renderContext : RenderContext = {}, _retried = 0) {
|
||||
/* istanbul ignore if */
|
||||
if (!this.isReady) {
|
||||
// Fall-back to loading-screen if enabled
|
||||
|
@ -1,4 +1,5 @@
|
||||
import ServerContext from 'nuxt/server/context'
|
||||
import ServerContext from 'src/server/context'
|
||||
import { RenderContext } from '../renderer'
|
||||
|
||||
export default class BaseRenderer {
|
||||
serverContext: ServerContext
|
||||
@ -18,7 +19,7 @@ export default class BaseRenderer {
|
||||
return templateFn(opts)
|
||||
}
|
||||
|
||||
render (renderContext) {
|
||||
render (_renderContext: RenderContext) {
|
||||
throw new Error('`render()` needs to be implemented')
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export default class SPARenderer extends BaseRenderer {
|
||||
const modernMode = this.options.modern
|
||||
const modern = (modernMode && this.options.target === TARGETS.static) || isModernRequest(req, modernMode)
|
||||
const cacheKey = `${modern ? 'modern:' : 'legacy:'}${url}`
|
||||
let meta = this.cache.get(cacheKey)
|
||||
let meta : Record<string, any> = this.cache.get(cacheKey)
|
||||
|
||||
if (meta) {
|
||||
// Return a copy of the content, so that future
|
||||
@ -127,7 +127,7 @@ export default class SPARenderer extends BaseRenderer {
|
||||
.map(file => ({ ...file, modern }))
|
||||
|
||||
meta.resourceHints += meta.preloadFiles
|
||||
.map(({ file, extension, fileWithoutQuery, asType, modern }) => {
|
||||
.map(({ file, extension, asType, modern }) => {
|
||||
let extra = ''
|
||||
if (asType === 'font') {
|
||||
extra = ` type="font/${extension}"${cors ? '' : ' crossorigin'}`
|
||||
|
@ -11,6 +11,8 @@ import ServerContext from 'src/server/context'
|
||||
import BaseRenderer from './base'
|
||||
|
||||
export default class SSRRenderer extends BaseRenderer {
|
||||
vueRenderer: typeof import('@vue/server-renderer')
|
||||
|
||||
constructor (serverContext: ServerContext) {
|
||||
super(serverContext)
|
||||
this.createRenderer()
|
||||
@ -170,9 +172,14 @@ export default class SSRRenderer extends BaseRenderer {
|
||||
}
|
||||
|
||||
const { csp } = this.options.render
|
||||
let shouldHashCspScriptSrc = false
|
||||
if (typeof csp === 'object') {
|
||||
const { policies, unsafeInlineCompatibility } = csp
|
||||
shouldHashCspScriptSrc = unsafeInlineCompatibility ||
|
||||
// Only add the hash if 'unsafe-inline' rule isn't present to avoid conflicts (#5387)
|
||||
const containsUnsafeInlineScriptSrc = csp.policies && csp.policies['script-src'] && csp.policies['script-src'].includes('\'unsafe-inline\'')
|
||||
const shouldHashCspScriptSrc = csp && (csp.unsafeInlineCompatibility || !containsUnsafeInlineScriptSrc)
|
||||
!(policies && policies['script-src'] && policies['script-src'].includes('\'unsafe-inline\''))
|
||||
}
|
||||
|
||||
const inlineScripts = []
|
||||
|
||||
if (renderContext.staticAssetsBase) {
|
||||
@ -228,7 +235,7 @@ export default class SSRRenderer extends BaseRenderer {
|
||||
|
||||
// Calculate CSP hashes
|
||||
const cspScriptSrcHashes = []
|
||||
if (csp) {
|
||||
if (typeof csp === 'object') {
|
||||
if (shouldHashCspScriptSrc) {
|
||||
for (const script of inlineScripts) {
|
||||
const hash = crypto.createHash(csp.hashAlgorithm)
|
||||
|
Loading…
Reference in New Issue
Block a user