Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
394 views
in Technique[技术] by (71.8m points)

node.js - Serving multiple react apps with client-side routing in 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'));
  });
}

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After some tinkering I was able to achieve this without using virtual hosts. I used the first idea you gave in the question, except I left the main app at the root (i.e. /).

// when going to `/app2`, serve the files at app2/build/* as static files
app.use('/app2', express.static(path.join(__dirname, 'app2/build')))
// when going to `/`, serve the files at mainApp/build/* as static files
app.use(express.static(path.join(__dirname, 'mainApp/build')))


// These are necessary for routing within react
app.get('app2/*', (req, res) => {
  res.sendFile(path.join(__dirname + '/app2/build/index.html'))
})

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

After this, I went into mainApp/package.json and added

"proxy": "http://localhost:4141"

:4141 is the port that the express server is running on. This line will make calls to fetch('/some/route') go back to the server instead of into your react app itself.

Finally, we go to app2/package.json and add

"proxy": "http://localhost:4141/app2",
"homepage": "/app2"

I believe that the key here is the "homepage" key. The way I understand it, when react starts it searches for some static files at its homepage, and without the "homepage" piece I was only able to get either a blank white screen or the mainApp.

I hope this helps someone out there!


EDIT

I have since changed from serving my create-react-apps through my express server to serving them through netlify. Now I don't need to worry about this express setup, or the homepage key in package.json. The express server lives by itself, and the react apps can still both use the same api, and deployment is much easier. Setup with netlify is trivial.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...