【问题标题】:Simple no frameworks Node.JS server to host a SPA React App简单的无框架 Node.JS 服务器来托管 SPA React 应用程序
【发布时间】:2020-12-15 19:24:19
【问题描述】:

在 create-react-app 网站上,我们找到了一个 Express 教程来托管 SPA React 应用程序(注意 * 在每个有效路径请求中返回单个 index.html):

https://create-react-app.dev/docs/deployment

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'build')));

app.get('/*', function (req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(9000);

有没有办法在没有框架的情况下在纯 Node.js 上复制这种行为?它处理每个有效路径的方式,但是当路径不存在时响应错误等等。我没有找到任何关于这样做的信息,这可能与没有太多代码或分叉Express ?

【问题讨论】:

  • 你到底想做什么?只是没有表达和使用节点 js'http 库?你甚至需要节点吗?只需使用 nginx
  • 不要使用/*,它会捕获所有请求并返回您的index.html。只使用你的有效路径,你的无效路径会出错:D
  • @azium 我正在构建一个 rest api 并希望使用纯节点部署我的 React SPA。
  • @John 你有here 的例子来说明如何做到这一点。只需为资产定义一个模式。你也可以阅读here如何处理无效路由。
  • 好的,这是http 的节点文件,你可以用它做你需要的一切nodejs.org/api/http.html

标签: node.js


【解决方案1】:

简单的答案是:响应任何与您的 MIME 类型不匹配或没有扩展名的 GET 请求,使用 index.html 并在您的前端处理 404 请求。

我遵循了我的讲师讲座和源代码 - https://github.com/HowProgrammingWorks/ServeStatic - 并对其进行了一些修改以与 React SPA 一起使用。在这里发布简化代码,希望你能明白:

const fs = require('fs');
const http = require('http');
const path = require('path');

// postOrder and updateJson are predifined async fucntions.
const postTypes = {
  '/api/order': postOrder,
  '/api/update_json': updateJson,
};

const STATIC_PATH = path.join(process.cwd(), './public');

const MIME_TYPES = {
  html: 'text/html; charset=UTF-8',
  js: 'application/javascript; charset=UTF-8',
  css: 'text/css',
  json: 'application/json',
  png: 'image/png',
  jpg: 'image/jpeg',
  jpeg: 'image/jpeg',
  ico: 'image/x-icon',
  svg: 'image/svg+xml',
};

const serveFile = name => {
  const filePath = path.join(STATIC_PATH, name);
  if (!filePath.startsWith(STATIC_PATH)) {
    console.log(`Can't be served: ${name}`);
    return null;
  }
  const stream = fs.createReadStream(filePath);
  console.log(`Served: ${name}`);
  return stream;
};

http
  .createServer(async (req, res) => {
    const { url } = req;
    if (req.method === 'GET') {
      const fileExt = path.extname(url).substring(1);
      const mimeType = MIME_TYPES[fileExt] || MIME_TYPES.html;
      res.writeHead(200, { 'Content-Type': mimeType });
      const stream = fileExt === '' ? serveFile('/index.html') : serveFile(url);
      if (stream) stream.pipe(res);
    } else if (req.method === 'POST') {
      const postType = postTypes[url];
      let response = postType ? await postType(req) : `Woops, no ${url} post type!`;
      res.writeHead(response ? 200 : 500, { 'Content-Type': 'text/plain' });
      response ||= `Woops, your response failed to arrive!`;
      res.end(response);
    }
  })
  .listen(3000);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多