Express 静态中间件在日志中返回错误

Express static middleware returning error in log

我在本地机器上完成了一个项目,目前正在学习如何将其部署到生产环境中。我在生产文档等方面想出了很多东西,但现在我一直停留在如何告诉我的服务器为我的静态资产提供服务的部分,这些静态资产包含我用 web pack 执行的构建文件。作为记录,我没有使用 create-react-app 我使用的是 webpack-dev-server cli。

我只成功连接到我的服务器并且 运行 使用 MySQL 路由通过它,但是当我的开发准备好投入生产时,我从未测试过在服务器上提供静态文件。当我尝试提供我的静态构建文件时,控制台出现错误。我不知道这个错误是因为我的路由在我的服务器上提供错误还是我的 index.html 构建中存在问题。

这是我的代码,服务器文件很大,所以我只会显示与我遇到的问题相关的部分:

服务器文件:

const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const cors = require("cors");
const router = express.Router();

const app = express();
const port = 5000;

app.use(cors());
// Body Parser Middleware
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ extended: false }));

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});

app.get("*", function(request, response) {
  response.sendFile(path.join(__dirname + "/../public/index.html"));
});

// Serve static files on server
app.use("../", express.static(__dirname + "public/index.html"));

app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

构建Index.html文件

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="theme-color" content="#000000">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
    crossorigin="anonymous">
  <link href='https://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700' rel='stylesheet' type='text/css'>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/v4-shims.css">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet">
  <link rel="stylesheet" href="/public/assets/css/pignose.calendar.min.css">
  <link href="/public/assets/css/styles.css" rel="stylesheet" type="text/css">
  <title></title>
</head>

<body>
  <div id="root"></div>

  <script type="text/javascript" src="/public/assets/js/jquery-3.3.1.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
    crossorigin="anonymous"></script>
  <!-- Ck Editor Library -->
  <script src="/public/assets/js/plugins/ckeditor/ckeditor.js"></script>
  <!-- Pignose Calendar -->
  <script src="/public/assets/js/pignose.calendar.full.min.js"></script>
  <script type="text/javascript" src="/public/assets/js/scripts.js"></script>
</body>

</html>

Webpack 生产

const webpack = require("webpack");
const path = require("path");
const CompressionPlugin = require("compression-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
const HtmlWebPackPlugin = require("html-webpack-plugin");

var browserConfig = {
  entry: ["babel-polyfill", __dirname + "/src/index.js"],
  output: {
    path: path.resolve(__dirname + "/build"),
    filename: "bundle.js",
    publicPath: "/"
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          query: {
            presets: ["react", "env", "stage-0"]
          }
        }
      },
      {
        test: /\.css$/,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader" },
          { loader: "sass-loader" }
        ]
      }
    ]
  },
  plugins: [
    new CompressionPlugin({
      filename: "[path].gz[query]",
      algorithm: "gzip",
      minRatio: 0.8,
      threshold: 8192
    }),
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify("production")
    }),
    new HtmlWebPackPlugin({
      template: "./public/index.html"
    })
  ]
};

var serverConfig = {
  target: "node",
  externals: [nodeExternals()],
  entry: __dirname + "/server/main.js",
  output: {
    path: path.resolve(__dirname + "/build"),
    filename: "bundle.js",
    publicPath: "/"
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          query: {
            presets: ["react", "env", "stage-0"]
          }
        }
      }
    ]
  }
};

module.exports = [browserConfig, serverConfig];

文件夹结构

当我尝试连接到我的构建文件端口时收到的错误日志:

第二个错误:

在 express 中间件配置中,顺序很重要,因为 app.get("*", function(request, response) 位于顶部,每个请求都将通过它并发送 index.html。像这样更改顺序

// Serve static files on server

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

app.get("*", function (request, response) {
    response.sendFile(path.join(__dirname + "/../public/index.html"));
});

它应该可以工作


编辑

作为你扩展我的答案的请求,这里发生的事情是因为你没有配置 public 目录,express 服务器将到达下一个请求处理程序,即 app.get("*" , ... 发送index.html 作为响应。所以当你请求这个 javascript 文件时

<script type="text/javascript" src="/public/assets/js/jquery-3.3.1.min.js"></script>

它会像我提到的那样发送 index.html 而不会发送 jquery-3.3.1.min.js 并且对于每个 js 和 css 文件都是一样的,但是你的浏览器需要一个 javascript 文件并尝试解析它,以便文件 <!doctype> .. 正在解析,但由于它不是有效的 javascript,它会打印错误。希望有帮助