簡體   English   中英

簡單的無框架 Node.JS 服務器來托管 SPA React 應用程序

[英]Simple no frameworks Node.JS server to host a SPA React App

在 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相關嗎?

簡單的答案是:使用index.html響應任何與您的 MIME 類型不匹配或沒有擴展名的GET請求,並在您的前端處理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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM