简体   繁体   English

在 Firebase 上托管 Nuxt.js SSR 应用时出现问题

[英]Problem hosting Nuxt.js SSR app on Firebase

I'm trying to host a Nuxt.js app on Firebase, and I've followed this tutorial , and I got stuck at #10 , when trying to do sudo firebase serve --only functions, hosting .我正在尝试在 Firebase 上托管 Nuxt.js 应用程序,并且我已经按照本教程进行了操作,但在尝试执行sudo firebase serve --only functions, hosting卡在了#10处。 I kept getting this Timed out waiting for function to respond.我一直在Timed out waiting for function to respond. . .

Upon further investigating I found out that the problem is in /functions/index.js.经过进一步调查,我发现问题出在 /functions/index.js 中。 The line nuxt.renderRoute('/').then(...) is taking forever to run, because the console.log('After render') is never called.线nuxt.renderRoute('/').then(...)永远运行,因为console.log('After render')永远不会被调用。 Here's how the /functions/index.js looks like这是 /functions/index.js 的样子

/functions/index.js /功能/index.js

const functions = require('firebase-functions')
const express = require('express')
const { Nuxt } = require('nuxt')

const app = express()

const config = {
  dev: false,
  buildDir: 'nuxt',
  build: {
    publicPath: '/public/'
  }
}
const nuxt = new Nuxt(config)

app.get('**', function (req, res) {
  res.set('Cache-Control', 'public, max-age=600, s-maxage=1200')
  console.log('it still works here')

  nuxt.renderRoute('/').then(result => {
    console.log(result.html)
    res.send(result.html)
  }).catch(e => {
    console.log(e)
    res.send(e)
  })
  console.log('After render')
})

module.exports.nuxtApp = functions.https.onRequest(app)

And this is how my terminal output looks like:这就是我的终端输出的样子: 在此处输入图片说明

I am a little late, but glad to share my approach:我有点晚了,但很高兴分享我的方法:

This is how my index.js looked like, after I got it to work with Firebase hosting.这就是我的 index.js 在使用 Firebase 托管后的样子。 Note: I ended up taking an entirely different approach by simply using prerendering instead of ssr for hosting my nuxt app on firebase.注意:我最终采用了一种完全不同的方法,只需使用预渲染而不是 ssr 在 firebase 上托管我的 nuxt 应用程序。 However if you need to use SSR for your project, this works nicely:但是,如果您需要为您的项目使用 SSR,这很有效:

const functions = require('firebase-functions')
const { Nuxt } = require('nuxt')
const express = require('express')
const admin = require('firebase-admin')

const app = express()

// Initialize Firebase (only if you use the Admin SDK, otherwise not needed)
admin.initializeApp({
  credential: admin.credential.cert(require('YOUR_KEY'))
});

// Nuxt Server Side Render Setup

const config = {
  dev: false
}

const nuxt = new Nuxt(config)

let isReady = false
const readyPromise = nuxt
  .ready()
  .then(() => {
    isReady = true
  })
  .catch(() => {
    process.exit(1)
  })

async function handleRequest(req, res) {
  if (!isReady) {
    await readyPromise
  }
  res.set('Cache-Control', 'public, max-age=1, s-maxage=1')
  await nuxt.render(req, res)
}

app.get('*', handleRequest)
app.use(handleRequest)
exports.nuxtssr = functions.https.onRequest(app)

You have two approach, the first one is request the page and create a behavior based on json or api .您有两种方法,第一种是请求页面并基于jsonapi创建行为。

Try using:尝试使用:

const Nuxt = require('nuxt')
const nuxt = new Nuxt()
nuxt.build()
.then(() => {
  // here you can use nuxt.renderRoute() or nuxt.render(req, res)
});

For example:例如:

nuxt.build()
.then(() => nuxt.renderRoute('/'))
.then(({ html, error, redirected }) => {
  // Use Html as string

  // `error` not null when the error layout is displayed, the error format is:
  // { statusCode: 500, message: 'My error message' }

  // `redirected` is not `false` when `redirect()` has been used in `data()` or `fetch()`
  // { path: '/other-path', query: {}, status: 302 }
})

The second approach is generating the route:第二种方法是生成路线:

app.get( '/', ( req, res, next ) => {
        doThePromise( req.query )
                .then( data => {
                        console.log( "rendering", res.renderRoute );
                        res.renderRoute( 'pages/foo', { data: data } );
                } );
} );

Or so simple like:或者像这样简单:

app.get('/route', (req, res) => {
  res.render('foo')
})

You're expecting your console.log to fire after, but in fact it may fire even before the promise is called ( .then ).你期望你的console.log在之后触发,但实际上它甚至可能在调用 promise 之前触发( .then )。 It might be that your logger is overwriting its output.可能是您的记录器正在覆盖其输出。 Try writing it like this:试着这样写:

nuxt.renderRoute('/').then(result => {
  console.log(result.html)
  res.send(result.html)
  console.log('After render')
}).catch(e => {
  console.log(e)
  res.send(e)
})

Alternatively rewrite the whole function using promises like this:或者,使用如下 Promise 重写整个函数:

app.get('**', async function (req, res) {
  res.set('Cache-Control', 'public, max-age=600, s-maxage=1200')
  console.log('it still works here')

  try {
    let result = await nuxt.renderRoute('/')
    console.log(result.html)
    res.send(result.html)
  } catch (e) {
    console.log(e)
    res.send(e)
  }
  console.log('After render')
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM