【问题标题】:Problem hosting Nuxt.js SSR app on Firebase在 Firebase 上托管 Nuxt.js SSR 应用时出现问题
【发布时间】:2019-03-19 00:32:26
【问题描述】:

我正在尝试在 Firebase 上托管 Nuxt.js 应用程序,并且我已关注此 tutorial,但在尝试执行 sudo firebase serve --only functions, hosting 时遇到了 #10。我一直收到这个Timed out waiting for function to respond.

经过进一步调查,我发现问题出在 /functions/index.js 中。 nuxt.renderRoute('/').then(...) 行将永远运行,因为从未调用过 console.log('After render')。这是 /functions/index.js 的样子

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

这就是我的终端输出的样子:

【问题讨论】:

  • 我正在检查图像。日志说:It still works here,但在您发布的代码中,没有出现。你能粘贴整个代码吗?我认为您在index.js 中的方法签名是错误的。
  • @MrMins 哎呀我的错误。它应该打印it still works here。我已经更新了这个问题。谢谢

标签: javascript firebase google-cloud-functions nuxt.js


【解决方案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)

【讨论】:

    【解决方案2】:

    您有两种方法,第一种是请求页面并基于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')
    })
    

    【讨论】:

      【解决方案3】:

      您希望您的 console.log 在之后触发,但实际上它甚至可能在调用 promise 之前触发 (.then)。可能是您的记录器正在覆盖其输出。试试这样写:

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

      或者使用这样的 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')
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多