在 firebase 的 public 目录中托管静态内容

Hosting static content in public directory on firebase

我正在使用 cloud functions and hosting 在 Firebase 上托管一个应用程序。前者以包含 API 的 NodeJS Express 应用程序形式提供动态内容,后者为我的 Express 应用程序提供静态内容,例如 css、javascript 等。

Here 是设置 express 和 firebase 托管的好教程)

通常在具有 standard structure 设置的 Express 应用程序中,会创建一些文件夹,例如 binroutesviewspublic .其中大部分都可以轻松复制到您的 firebase 应用中。

问题:

此问题与 hostingfunctions 同时发生。

使用以下 index.js(表达为 app.js),我可以使用 firebase 模拟器(函数、托管等)在本地成功查看和模拟我的应用程序

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const express = require("express");
const engines = require("consolidate");
...

admin.initializeApp({
    credential: admin.credential.applicationDefault(),
    databaseURL: "https://....firebaseio.com"
});

// app routes
const usersRouter = require('./app/users');
...

const app = express();

// #Working locally only - for deplopyment, all static linkes must load resources as [hosting-domain.app.com]/css/styles.css
app.use("/public", express.static(path.join(__dirname,'../public')));

app.use(flash());

app.engine('pug', require('pug').__express)
app.set('views', __dirname + '/views');
app.set('view engine', 'pug');

// Use the createSession endpoint for login & verify each session
app.use(authenticate);

...
app.use('/user', usersRouter);
app.get('/', (req, res) => {
    return res.redirect("/user/login");
});

app.get('*', (req, res, next) => {
    res.render("404");
})

exports.app = functions.https.onRequest(app);

// api routes
exports.api = require('./api/api.js');

如何在将 firebase 函数用于动态内容的同时在 firebase 托管上成功提供静态内容?

(答案如下)

您可以将静态文件添加到 Firebase 托管的 public 目录中。

在这种情况下 'public' 是我的托管目录。要将文件存储在 <domain>/css/..,只需如图所示创建一个名为 'css' 的新文件夹并添加您的文件。

滚动到底部以获得 TL;DR 和解决方案

在写问题时 - 我在思考每个 firebase 功能以及它们各自的作用后找到了解决方案。

在本地托管静态内容与部署在 firebase 上

部署时,资产的路径,例如[my-domain.web.com]/public/styles/my-styles.css 我可以在本地获取的内容在部署时不会加载。相反,我需要使用 [my-domain.web.com]/styles/my-styles.css.

在本地工作,但在部署时不工作:

[my-domain.web.com or localhost:5000]/public/styles/my-styles.css

在本地和部署后工作

[my-domain.web.com or localhost:5000]/styles/my-styles.css

这是因为 public directory 中的任何内容都直接托管在您的域中。因此,使用 express.static 需要相同的文件夹结构等。但是 public 目录的内容是(自动)从您域的根目录托管的。

在 express 中,需要指定在哪里可以找到您的静态内容,然后由 nodejs 或您选择的其他托管功能托管。

但是 Firebase 会自动为您托管静态内容。 因此,无需包含甚至没有以下行:

app.use("/public", express.static(path.join(__dirname,'../public')));

因为它只是一个混淆点(并且也只在本地提供文件,即混淆点)。请记住,public folder takes precedence over dynamic content.

内的任何内容

参见 little blue note right above the middleware section:

Note: The static files in the public directory take precedence over the rewrites, so any static files will be served alongside the Cloud Functions endpoints.

public 目录是:

my-firebase-app
    \ functions
    \ public               < ------ this one
    \ ..other files

TL;DR

鉴于文件夹结构:

my-firebase-app
    \ functions /
        \ views /
            \ root.pub     < ---- pug template file
    \ public \             < ------ this one
        \ styles /
            \ my-styles.css < ----- styles file
    \ ..other files

确保所有 pug/handlebars/ejs 等模板假定 public 目录是您域的根目录,因此您的静态内容加载为[localhost:5000yourdomain.web.app]/styles/my-styles.css

普通快递应用程序 通常托管您的快递应用程序会使用类似的东西:

app.use("/public", express.static(path.join(__dirname,'../public')));

在你的酒吧(模板文件)中你会有类似

的东西
link(rel="stylesheet", href="/public/styles/my-styles.css")

Firebase Functions + Hosting App,这应该改为:

  • 删除 app.use("/public"...) 功能(firebase 托管将其托管到您的根域)

  • 任何link静态内容应该使用

    link(rel="stylesheet", href="/styles/my-styles.css")

注意在href

中省略了“/public”