在Firebase上托管Nuxt.js SSR应用程序的问题

3
我正在尝试在Firebase上托管一个Nuxt.js应用程序,我已经按照这个教程操作,并在第10步sudo firebase serve --only functions, hosting时遇到了困难。我一直收到Timed out waiting for function to respond.的提示。
进一步调查后,我发现问题出在/functions/index.js中。代码nuxt.renderRoute('/').then(...)运行时间太久,因为永远不会调用console.log('After render')。以下是/functions/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)

这是我的终端输出的样子: 在这里输入图片描述

我正在检查这张图片。日志显示:“它仍然在这里工作”,但是你发布的代码中没有出现。你能把整个代码粘贴过来吗?我认为你在 index.js 中的方法签名是错误的。 - Benjamin RD
@MrMins 抱歉,我的错误。应该打印“它仍然在这里工作”。我已经更新了问题。谢谢。 - Chan Jing Hong
3个回答

1

我有点晚了,但很高兴分享我的方法:

这是我的index.js的样子,在我让它与Firebase托管一起工作后。 注意:最终我采用了完全不同的方法,只是使用预渲染而不是ssr来在Firebase上托管我的nuxt应用程序。然而,如果您需要为您的项目使用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)

0

你有两种方法,第一种是请求页面并基于jsonapi创建行为。

尝试使用:

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

例如:

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 }
})

第二种方法是生成路由:
app.get( '/', ( req, res, next ) => {
        doThePromise( req.query )
                .then( data => {
                        console.log( "rendering", res.renderRoute );
                        res.renderRoute( 'pages/foo', { data: data } );
                } );
} );

或者像这样简单:

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

0
你期望的是在 .then 被调用后才触发 console.log,但实际上它甚至可能在 Promise 被调用之前就触发了。这可能是由于你的日志记录器正在覆盖其输出。尝试像这样编写它:
nuxt.renderRoute('/').then(result => {
  console.log(result.html)
  res.send(result.html)
  console.log('After render')
}).catch(e => {
  console.log(e)
  res.send(e)
})

或者可以像这样使用 promises 重写整个函数:
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')
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接