在 Express 中使用客户端路由为多个 React 应用程序提供服务 [英] Serving multiple react apps with client-side routing in Express

查看:35
本文介绍了在 Express 中使用客户端路由为多个 React 应用程序提供服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于一项服务,我有不同的软件产品,需要将其部署到单个服务器上.客户端使用 react 构建,通过 create-react-app 构建设置,而服务器运行 Node.js 和 Express.

I have different software products for one single service, which needs to be deployed to a single server. The clients are built with react, with a build setup by create-react-app, while the server runs Node.js and Express.

当我从服务器提供单个应用程序时,它是通过以下方式完成的:

When I serve a single application from the server it is done the following way:

// App.js
// ...
// Entry point for data routes (API)
app.use('/data', indexRoute);

if(process.env.NODE_ENV !== 'development') {
  app.use(express.static(path.join(__dirname, 'build-client')));

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

我希望能够从服务器提供多个应用程序.我该怎么做?

I want to be able to serve multiple apps from the server. How should I do that?

我尝试的是为资产连接不同的静态路径,并将具有不同名称的客户端分开,尽管它不起作用.像这样:

What I tried is to wire in different static paths for the assets and separate the clients with different names, although it did not work. Like this:

// App.js
// ...
// Entry point for data routes (API)
app.use('/data', indexRoute);

if(process.env.NODE_ENV !== 'development') {
  app.use(express.static(path.join(__dirname, 'build-client')));
  app.use(express.static(path.join(__dirname, 'build-admin')));

  app.get('/client/*', function(req, res) {
    return res.sendFile(path.resolve( __dirname, 'build-client' , 'index.html'));
  });
  app.get('/admin/*', function(req, res) {
    return res.sendFile(path.resolve( __dirname, 'build-client' , 'index.html'));
  });
}

我也尝试过这样做,但 Express 抛出错误:未指定默认引擎且未提供扩展:

I have also tried to do it this way, but Express throw Error: No default engine was specified and no extension was provided:

if(process.env.NODE_ENV !== 'development') {
  // Admin paths
  app.use('/admin', express.static(path.join(__dirname, 'build-admin')));
  app.get('/admin/*', function(req, res) {
    return res.sendFile(path.resolve( __dirname, 'build-admin' , 'index.html'));
  });

  // Site paths
  app.use('/', express.static(path.join(__dirname, 'build-client')));
  app.get('/*', function(req, res) {
    return res.sendFile(path.resolve( __dirname, 'build-client' , 'index.html'));
  });
}

我怎样才能做到这一点或类似的事情?

How could I accomplish this or something similar?

推荐答案

在解决这个问题一段时间后,我找到了一个不影响原始设置的可行解决方案.

After struggling for a while with this problem I've found a possible solution without compromising the original setup.

我们使用 Express vhost 包来设置通过虚拟域处理请求.

We used Express vhost package to setup handling of requests through virtual domains.

当你创建你的应用实例时,你应该使用 express 初始化尽可能多的应用,因为你想单独公开(在我们的例子中是三个单独的应用加上原始应用实例)

When you create your app instance, you should initialize as many apps with express as you want to expose separately (in our case its three separate apps plus the original app instance)

// Create an express instance
const app = express();
const appAdmin = express();
const appClient = express();
const appVendor = express();

之后,您需要安装 vhost 并导入它.然后通过为每个应用程序指定静态文件夹,您可以分别处理静态文件的服务,而其余部分分别处理对给定子域的请求.

After that you need to install vhost and import it. Then with specifying the static folder for each app you can handle serving the static files separately, while the remaining part deals with handling the request for the given subdomains respectively.

  appAdmin.use(express.static(path.join(__dirname, 'build-admin')));
  appClient.use(express.static(path.join(__dirname, 'build-client')));
  appVendor.use(express.static(path.join(__dirname, 'build-vendor')));

  appAdmin.use((req, res, next) => {
    return res.sendFile(path.resolve( __dirname, 'build-admin' , 'index.html'));
  });

  appClient.use((req, res, next) => {
    return res.sendFile(path.resolve( __dirname, 'build-client' , 'index.html'));
  });

  appVendor.use((req, res, next) => {
    return res.sendFile(path.resolve( __dirname, 'build-vendor' , 'index.html'));
  });

  app.use(vhost('domain.com', appClient));
  app.use(vhost('www.domain.com', appClient));
  app.use(vhost('a.domain.com', appAdmin));
  app.use(vhost('b.domain.com', appVendor));

不要忘记在您域的 DNS 注册表中添加所需的子域.示例:

Don't forget to add the desired subdomains in your domain's DNS registry. Example:

...records
CNAME   vendor  @
CNAME   admin   @

这篇关于在 Express 中使用客户端路由为多个 React 应用程序提供服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆