如何在 Express 中使用带有 Firebase 功能的 webpack-hot-server-middleware

Posted

技术标签:

【中文标题】如何在 Express 中使用带有 Firebase 功能的 webpack-hot-server-middleware【英文标题】:How to use webpack-hot-server-middleware with Firebase functions in express 【发布时间】:2018-06-23 06:06:27 【问题描述】:

我正在尝试在服务器端渲染 React 项目中为 Firebase 使用云功能。

首先,当我尝试在 webpack 中使用 babel-watch 运行 express 服务器时,它正在工作!所以我希望能够使用 babel-watch 在 express 服务器中创建 firebase 功能,我阅读了functions-samples/isomorphic-react-app/ 存储库并制作了以下代码。但也许我不明白..

那么,有没有办法在开发中使用带有functions.https.onRequest(app); 的 webpack-hot-server-middleware 和 babel-watch

或者在我的情况下firebase serve --only functions,hosting 是正确的吗?

服务器/index.js

import express from "express";
import webpack from "webpack";
import webpackDevMiddleware from "webpack-dev-middleware";
import webpackHotServerMiddleware from "webpack-hot-server-middleware";
import clientConfig from "../webpack/client";
import serverConfig from "../webpack/server";

const app = express();
const compiler = webpack([clientConfig, serverConfig]);

app.use(webpackDevMiddleware(compiler));
app.use(webpackHotServerMiddleware(compiler));

export let firebaseTrigger = functions.https.onRequest(app);

webpack/server.js

const path = require("path");

module.exports = 
  name: "server",
  target: "node",
  entry: [path.resolve(__dirname, "../server/render.js")],
  output: 
    filename: "index.js",
    path: path.resolve(__dirname, "../functions"),
    libraryTarget: "commonjs2"
  ,
  module: 
    rules: [
      
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      
    ]
  
;

firebase.json


  "hosting": 
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      
        "source": "**",
        "function": "firebaseTrigger"
      
    ]
  

package.json


  "name": "react-firebase",
  "version": "1.0.0",
  "main": "functions/index.js",
  "license": "MIT",
  "scripts": 
    "babel": "NODE_ENV=development babel-watch server/index.js",
    "dev-server": "firebase serve --only functions,hosting"
  ,
  "dependencies": 
    "express": "^4.16.2",
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  ,
  "devDependencies": 
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "babel-watch": "^2.0.7",
    "firebase-admin": "^5.8.0",
    "firebase-functions": "^0.8.0",
    "firebase-tools": "^3.16.0",
    "webpack": "^3.10.0",
    "webpack-dev-middleware": "^2.0.0",
    "webpack-hot-server-middleware": "^0.3.1"
  

【问题讨论】:

【参考方案1】:

最好的办法是不使用 Firebase 模拟器,而只在现有开发服务器上使用 firestore 和函数模拟器。同时运行你的开发服务器和模拟器。

import firebaseSettings from '../../firebase.json'
// other imports

const firebaseConfig =  /* add config */ 

firebase.initializeApp(firebaseConfig)
firebase.auth() // never emulated

const isDev = location.hostname === 'localhost'

if (isDev) 
  // Emulator/Development settings
  const firestorePort = firebaseSettings.emulators.firestore.port
  const functionsPort = firebaseSettings.emulators.functions.port
  const firestoreUrl = `localhost:$firestorePort`
  const functionsUrl = `http://localhost:$functionsPort`
  firebase.firestore().settings(
    host: firestoreUrl,
    ssl: false,
    experimentalForceLongPolling: true, // this is used by cypress
  )
  // if app uses callable functions
  firebase.functions().useFunctionsEmulator(functionsUrl)
 else 
  // Production settings
  firebase.firestore()
  firebase.functions()

【讨论】:

【参考方案2】:

问题不在于 firebase 功能,而在于托管。

Firebase 功能在本地运行时已包含热重载。正如您可以在他们的文档中看到的那样:https://firebase.google.com/docs/functions/local-emulator

对于这两种工具,模拟器会自动重新加载您在活动会话期间所做的代码更改。如果您的代码需要被转译(TypeScript、React),请确保在运行模拟器之前这样做。

但是对于托管部分,它并没有真正起作用(还): https://github.com/firebase/firebase-tools/issues/594

【讨论】:

以上是关于如何在 Express 中使用带有 Firebase 功能的 webpack-hot-server-middleware的主要内容,如果未能解决你的问题,请参考以下文章

如何在本地使用带有 express 的 graphql 和带有 mongoose 的 mongodb 来检索文档?

如何使用 jest 在 javascript 中测试 try catch 代码并在 express 中包含带有中间件的 next() 调用?

如何在生产环境中使用 Express 和 Parceljs 中间件

如何使用 Node、Express、Axios 在 ReactJS 前端设置带有 JWT 令牌的 cookie

如何在授权标头中将带有 fetch 和 cors 的 JWT 令牌发送到 Express 服务器?

使用 Multer 将带有 fetch 的图像上传到 Express