feat(vue-renderer/vue-app): report SSR console logs to the browser with consola (#5673)

This commit is contained in:
Sébastien Chopin 2019-05-09 09:06:17 +02:00 committed by Pooya Parsa
parent 3c1196de74
commit 4b11dcc9ad
3 changed files with 35 additions and 9 deletions

View File

@ -18,6 +18,7 @@ import {
} from './utils.js' } from './utils.js'
import { createApp, NuxtError } from './index.js' import { createApp, NuxtError } from './index.js'
import NuxtLink from './components/nuxt-link.<%= router.prefetchLinks ? "client" : "server" %>.js' // should be included after ./index.js import NuxtLink from './components/nuxt-link.<%= router.prefetchLinks ? "client" : "server" %>.js' // should be included after ./index.js
<% if (isDev) { %>import consola from 'consola'<% } %>
// Component: <NuxtLink> // Component: <NuxtLink>
Vue.component(NuxtLink.name, NuxtLink) Vue.component(NuxtLink.name, NuxtLink)
@ -36,6 +37,12 @@ const NUXT = window.<%= globals.context %> || {}
Object.assign(Vue.config, <%= serialize(vue.config) %>)<%= isTest ? '// eslint-disable-line' : '' %> Object.assign(Vue.config, <%= serialize(vue.config) %>)<%= isTest ? '// eslint-disable-line' : '' %>
<% if (isDev) { %>
const logger = consola.withScope('nuxt:ssr')
const logs = NUXT.logs || []
logs.forEach(logObj => logger[logObj.type](logObj))
delete NUXT.logs
<% } %>
<% if (debug) { %> <% if (debug) { %>
// Setup global Vue error handler // Setup global Vue error handler
if (!Vue.config.$nuxt) { if (!Vue.config.$nuxt) {

View File

@ -1,4 +1,5 @@
import { stringify } from 'querystring' import { stringify } from 'querystring'
import consola from 'consola'
import Vue from 'vue' import Vue from 'vue'
<% if (fetch.server) { %>import fetch from 'node-fetch'<% } %> <% if (fetch.server) { %>import fetch from 'node-fetch'<% } %>
import middleware from './middleware.js' import middleware from './middleware.js'
@ -12,9 +13,6 @@ Vue.component('NLink', NuxtLink)
<% if (fetch.server) { %>if (!global.fetch) { global.fetch = fetch }<% } %> <% if (fetch.server) { %>if (!global.fetch) { global.fetch = fetch }<% } %>
const debug = require('debug')('nuxt:render')
debug.color = 4 // force blue color
const noopApp = () => new Vue({ render: h => h('div') }) const noopApp = () => new Vue({ render: h => h('div') })
const createNext = ssrContext => (opts) => { const createNext = ssrContext => (opts) => {
@ -66,10 +64,12 @@ export default async (ssrContext) => {
const beforeRender = async () => { const beforeRender = async () => {
// Call beforeNuxtRender() methods // Call beforeNuxtRender() methods
await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt }))) await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt })))
ssrContext.rendered = () => {
<% if (store) { %> <% if (store) { %>
// Add the state from the vuex store // Add the state from the vuex store
ssrContext.nuxt.state = store.state ssrContext.nuxt.state = store.state
<% } %> <% } %>
}
} }
const renderErrorPage = async () => { const renderErrorPage = async () => {
// Load layout for error page // Load layout for error page
@ -85,7 +85,7 @@ export default async (ssrContext) => {
return renderErrorPage() return renderErrorPage()
} }
<% if (isDev) { %>const s = Date.now()<% } %> <% if (debug) { %>const s = Date.now()<% } %>
// Components are already resolved by setContext -> getRouteData (app/utils.js) // Components are already resolved by setContext -> getRouteData (app/utils.js)
const Components = getMatchedComponents(router.match(ssrContext.url)) const Components = getMatchedComponents(router.match(ssrContext.url))
@ -98,7 +98,7 @@ export default async (ssrContext) => {
try { try {
await store.dispatch('nuxtServerInit', app.context) await store.dispatch('nuxtServerInit', app.context)
} catch (err) { } catch (err) {
debug('error occurred when calling nuxtServerInit: ', err.message) consola.debug('Error occurred when calling nuxtServerInit: ', err.message)
throw err throw err
} }
} }
@ -219,7 +219,7 @@ export default async (ssrContext) => {
return Promise.all(promises) return Promise.all(promises)
})) }))
<% if (isDev) { %>if (asyncDatas.length) debug('Data fetching ' + ssrContext.url + ': ' + (Date.now() - s) + 'ms')<% } %> <% if (debug) { %>if (asyncDatas.length) consola.debug('Data fetching ' + ssrContext.url + ': ' + (Date.now() - s) + 'ms')<% } %>
// datas are the first row of each // datas are the first row of each
ssrContext.nuxt.data = asyncDatas.map(r => r[0] || {}) ssrContext.nuxt.data = asyncDatas.map(r => r[0] || {})

View File

@ -1,6 +1,7 @@
import path from 'path' import path from 'path'
import crypto from 'crypto' import crypto from 'crypto'
import fs from 'fs-extra' import fs from 'fs-extra'
import consola from 'consola'
import devalue from '@nuxt/devalue' import devalue from '@nuxt/devalue'
import { createBundleRenderer } from 'vue-server-renderer' import { createBundleRenderer } from 'vue-server-renderer'
import BaseRenderer from './base' import BaseRenderer from './base'
@ -37,12 +38,30 @@ export default class SSRRenderer extends BaseRenderer {
) )
} }
async devRenderToString(renderContext) {
const logs = []
const devReporter = {
log(logObj) {
if (logObj.args[0] instanceof Error) {
logObj.args[0] = logObj.args[0].stack
}
logs.push(logObj)
}
}
consola.addReporter(devReporter)
const APP = await this.vueRenderer.renderToString(renderContext)
consola.removeReporter(devReporter)
renderContext.nuxt.logs = logs
return APP
}
async render(renderContext) { async render(renderContext) {
// Call ssr:context hook to extend context from modules // Call ssr:context hook to extend context from modules
await this.serverContext.nuxt.callHook('vue-renderer:ssr:prepareContext', renderContext) await this.serverContext.nuxt.callHook('vue-renderer:ssr:prepareContext', renderContext)
// Call Vue renderer renderToString // Call Vue renderer renderToString
let APP = await this.vueRenderer.renderToString(renderContext) let APP = await (this.options.dev ? this.devRenderToString(renderContext) : this.vueRenderer.renderToString(renderContext))
// Call ssr:context hook // Call ssr:context hook
await this.serverContext.nuxt.callHook('vue-renderer:ssr:context', renderContext) await this.serverContext.nuxt.callHook('vue-renderer:ssr:context', renderContext)