如何在Firebase托管基于Node.js与Handlebars的Web应用?相关问题求助
index.html Issue Hey there, I get your frustration—Firebase Hosting’s default setup expects static assets like index.html, but Handlebars relies on server-side rendering (or preprocessing) to generate HTML. Don’t worry, there are two solid approaches to make this work, neither of which require you to manually write HTML files.
Option 1: Pre-Render Handlebars to Static HTML (Best for Static Sites)
If your app doesn’t need dynamic content (e.g., a portfolio or blog with fixed content), you can precompile your Handlebars templates into static HTML files before deploying to Firebase Hosting. Here’s how:
Set up a simple Node.js script to render templates
Create a file likerender.jsin your project root:const fs = require('fs'); const path = require('path'); const handlebars = require('handlebars'); // Read your Handlebars template const templatePath = path.join(__dirname, 'views', 'index.hbs'); const templateSource = fs.readFileSync(templatePath, 'utf8'); const template = handlebars.compile(templateSource); // Define your data (replace with your actual content) const data = { title: 'My Firebase + Handlebars App', content: 'Hello from pre-rendered Handlebars!' }; // Render to HTML and save to public directory const html = template(data); const outputPath = path.join(__dirname, 'public', 'index.html'); fs.writeFileSync(outputPath, html); // Repeat for other templates as neededInstall dependencies
Run this in your terminal:npm install handlebarsAdd a build script to package.json
Add this line to yourpackage.jsonscripts section:"scripts": { "build": "node render.js" }Deploy to Firebase Hosting
Before deploying, runnpm run buildto generate theindex.html(and other HTML files) in thepublicdirectory. Then deploy as usual:firebase deploy --only hosting
Option 2: Dynamic Rendering with Firebase Cloud Functions (Best for Dynamic Apps)
If your app needs dynamic content (e.g., user-specific data, real-time updates), you’ll need to run a Node.js server that renders Handlebars templates on the fly. Firebase Cloud Functions lets you host this server, and you can route all requests from Firebase Hosting to your function.
Step 1: Set up Cloud Functions and Express
Initialize Firebase Functions in your project (if not already done):
firebase init functionsChoose JavaScript as the language, and follow the prompts.
Install required dependencies in the
functionsdirectory:cd functions npm install express handlebarsCreate your Express server with Handlebars rendering
Replace the code infunctions/index.jswith this:const functions = require("firebase-functions"); const express = require('express'); const exphbs = require('express-handlebars'); const app = express(); // Configure Handlebars as the view engine app.engine('hbs', exphbs({ extname: 'hbs' })); app.set('view engine', 'hbs'); app.set('views', './views'); // Make sure your .hbs files are in functions/views // Define routes app.get('/', (req, res) => { // Pass dynamic data to your template res.render('index', { title: 'Dynamic Handlebars App', user: { name: 'Guest' } // Replace with real data (e.g., from Firebase Auth/Firestore) }); }); // Export the Express app as a Cloud Function exports.app = functions.https.onRequest(app);
Step 2: Configure Firebase Hosting to Route Requests to the Function
Open your firebase.json file and update the hosting section to add rewrites:
{ "hosting": { "public": "public", // Optional: keep static assets in public if needed "rewrites": [ { "source": "**", "function": "app" } ] } }
This tells Firebase Hosting to send all requests to your app Cloud Function instead of looking for static HTML files.
Step 3: Deploy
Deploy both the functions and hosting:
firebase deploy --only functions,hosting
Why This Works
Firebase Hosting’s static mode expects pre-built HTML, but combining it with Cloud Functions lets you run a full Node.js server that handles Handlebars rendering dynamically. Pre-rendering is great for static content since it’s faster and cheaper, while Cloud Functions are perfect for dynamic apps that need server-side logic.
I’ve used both approaches for projects, so they’re definitely viable—Firebase’s docs don’t always cover every stack combination, but these workarounds fill the gap.
内容的提问来源于stack exchange,提问作者Jor Khachatryan

