如何通过云功能将Nuxt SSR应用程序部署到Firebase?

时间:2020-04-06 13:12:52

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

我遵循此medium post作为指导,将我的nuxt应用程序托管在Firebase托管上。

但是,当我随后访问url时,部署过程已经完成,我收到一条Cannot GET /错误消息。如果我检查功能日志,会发现该功能完成并显示404错误。

这是我的 functions / index.js

const functions = require('firebase-functions')
const admin = require("firebase-admin")
const { Nuxt } = require('nuxt-start')
const nuxtConfig = require('./nuxt.config.js')

admin.initializeApp()

const config = {
  ...nuxtConfig,
  dev: false,
  debug: true,
  buildDir: "nuxt",
  publicPath: "public",
}

const nuxt = new Nuxt(config)

exports.ssrapp = functions.https.onRequest(async (req, res) => {
  await nuxt.ready()
  nuxt.render(req, res)
})

这是Firebase配置

{
  "functions": {
    "source": "functions",
    "predeploy": [
      "npm --prefix src run build && rm -rf functions/nuxt && cp -r src/nuxt/ functions/nuxt/ && cp src/nuxt.config.js functions/"
    ]
  },
  "hosting": {
    "predeploy": [
      "rm -rf public/* && mkdir -p public/_nuxt && cp -a src/nuxt/dist/client/. public/_nuxt && cp -a src/static/. public/ && cp -a public_base/. public/"
    ],
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "ssrapp"
      }
    ]
  }
}

项目结构是这个

/
 /src
 /functions
 /public
 /public_base

运行firebase deploy时,我确实看到/ src的内容被复制到/ functions / nuxt。为了测试,我的 /functions/package.json 文件还包含了 /src/package.json 文件中的所有依赖项。

如何启动并运行该应用程序?如果您需要更多详细信息,请告诉我。

更新#1

我尝试使用命令firebase serve --only functions,hosting -p 5004服务托管和功能。

像这样运行服务器给了我更多的见解。具体来说,我在加载时收到了此警告消息,然后在加载页面时导致了实际错误消息。

WARN  Module @firebase/app not found. Silently ignoring module as programatic usage detected

我没有将此软件包安装在functions目录中,因为我的src目录中也没有该软件包。但是,将其安装在/ functions内并重新启动开发服务器后,该警告消息消失了,并且还出现了我在页面加载时遇到的错误。

我还发现了一些与vue有关的警告,vue-server-renderer和vue-template-compiler没有运行相同的版本。

现在一切似乎都正常了!

3 个答案:

答案 0 :(得分:2)

您的配置和结构看起来正确。

大约一年前,我也使用我的应用程序进行了此操作,但遇到了同样的问题。它与功能代码本身有关。我也尝试使用nuxt.render(req, res)Docs),但是它对我没有用,所以我最终使用了nuxt.renderRoute(route)Docs)。效果很好。

您可以将代码更改为以下内容:

const { Nuxt } = require('nuxt')

...

exports.ssrapp = functions.https.onRequest(async (req, res) => {
  await nuxt.ready()

  const result = await nuxt.renderRoute(req.path) // Returns { html, error, redirected }
  res.send(result.html) // Sends html as response
})

这对我有用。您应该考虑捕获任何错误。我希望这能解决您的问题。

这只是一个变通办法,如果有人知道为什么nuxt.render不能正常工作,我很想知道。因此,我的应用程序浪费了很多时间...

答案 1 :(得分:0)

我尝试使用命令firebase serve --only functions,hosting -p 5004在本地提供托管和功能。

这样做,我可以发现很多警告和错误,例如

FATAL 

Vue packages version mismatch:

- vue@2.5.21
- vue-server-renderer@2.6.11

This may cause things to work incorrectly. Make sure to use the same version for both.

WARN  Module @firebase/app not found. Silently ignoring module as programatic usage detected

然后,我确保这些vue软件包确实在运行相同版本。然后,我还在@firebase/app中添加了/functions/package.json程序包(但是在/src/package.json中不存在。

我再次运行本地服务器,一切正常。然后,我部署到了Firebase,一切都按预期进行。

答案 2 :(得分:0)

以下对我有用(使用 nuxt-start 代替):

const functions = require("firebase-functions");
const { Nuxt } = require("nuxt-start");

const config = {
  dev: false
};

const nuxt = new Nuxt(config);

let isReady = false;

async function handleRequest(req, res) {
  if (!isReady) {
    try {
      isReady = await nuxt.ready();
    } catch (error) {
      process.exit(1);
    }
  }
  await nuxt.render(req, res);
}

exports.nuxtssr = functions.https.onRequest(handleRequest);