How to run react-scripts start from an express server? - reactjs

I'd like to run a react app served by an express server. Even though it's not the solution, the effect what I'd like to earn is app.use("/", "react-scripts start"), so if the server gets a request at "/", it starts the react app, and serves it's files.
I read about the solution of building the app, and serve bundle.js, or just adding a proxy with the server's URL to the client app's package.json, but that's not what I want, and haven't found anything similar to the effect I'd like to earn.
I'm not sure what react-scripts start does, and how it's working, but the reason why I need it is that I don't want to restart the whole server, and wait until the app builds every time I change something in the front-end.
Any ideas?

react-scripts start sets up the development environment and starts a server along with hot module reloading. Basically, create-react-app helps you kick off your project without going into the intricacies of WebPack configurations.
Run react-scripts build to build your project files into build folder & then, you can create a server.js file that uses Express to serve your build folder.
server.js
const path = require('path');
const express = require('express');
const app = express();
const publicPath = path.join(__dirname, 'build');
app.use(express.static(publicPath));
app.get('*', (req, res) => {
res.sendFile(path.join(publicPath, 'index.html'));
});
app.listen(3000, () => {
console.log('Server is up!');
});
run node server.js to start your server.

What exactly is the outcome you're trying to achieve? Using create-react-app (for which react-scripts is a utility), or webpack in general, the app must always be rebuilt at some point for the changes to be seen, since JSX is not browser-compatible and must be transpiled to regular JS. Also, it's not necessary to restart the server if you're only making changes to the front end.
Running react-scripts start basically runs webpack-dev-server (WDS) which is built into CRA's configuration. WDS does not actually build the project in the sense of outputting build files, but it still must build it in-memory to be able to even display the changes at all. On a normal application, rebuilding through WDS shouldn't take more than a handful of seconds, and that's about the fastest feedback loop you're going to get for seeing changes manifest.
If you're running an Express server alongside a CRA app, I'd recommend looking into concurrently and nodemon, the former of which will allow you to run your server and React client with one command, and the latter of which will automatically restart your server for you (only when back end changes are made, a front end change will not trigger a server restart).

Related

Next.js App reloads frequently in production

I've just deployed my first Next.js app in production through Nginx and pm2. Everything seems okay but the app frequently reloads after some interval on browser. I'm seeing the webpack-hmr is also running in my production server. (Which I think isn't necessary in production)
I am using a custom server.js and I run my app on production using next build then NODE_ENV=production node server.js command, and restarting my server using pm2.
I've added below a screenshot of my dev-tool's network tab which is showing the HMR running on production. If HMR is the possible cause of browser reload, then what should I do to disable it on production?
And also if the "frequent reload" isn't happening because of HMR then what will be the cause of it?
Have you guys experienced the same issue on production? If so, please share your knowledge and experience. Thanks.
Edit: I am also using next-pwa and a warning keeps showing on my console for it -
GenerateSW has been called multiple times, perhaps due to running webpack in --watch mode. The precache manifest generated after the first call may be inaccurate! Please see https://github.com/GoogleChrome/workbox/issues/1790 for more information.
Fixed it by disabling pwa when in development
const prod = process.env.NODE_ENV === 'production'
module.exports = withPWA({
pwa: {
dest: 'public',
disable: prod ? false : true
}
})
Finally found a solution. I had to tell my env mode when starting pm2 as pm2 start server --env production. And it works perfectly on my browser.

How to merge React App and Express App to deploy on single project?

I recently create Express and MongoDB API and after that, I connect that API to my React Application successfully and which is running well. But one situation occurring during deployment now I need to deploy both projects separately means I need two hosting plan for them. So, I want that both project running on the same host. Is it possible? and How?
A build of any React application creates (unless webpack-dev-server is used to compile it) the output which consists of static files: script bundles and .html file(s) that reference the bundles in <script> tag.
Those files can and should be copied to Express in production build. Then you have one server on one host. When React application runs inside a client (e.g. browser) it gets everything including .html files, script bundles, API responses from the single source: Express backend/server. Which by the way excludes any possibility of getting CORS issues so many people are asking about here on SO.
Example, e.g. a boilerplate project that demonstrates all that.
If you execute commands:
git clone https://github.com/winwiz1/crisp-react.git
cd crisp-react
yarn install && yarn start:prod
and then point your browser to localhost:3000, you will have React app running inside your browser and it got everything from one single Express backend.
crisp-react has two subdirectories: client with React client app and server with Express backend. The build command copies the build artifacts from one subdirectory to another. So you can even rename or delete the client subdirectory after a build, it won't affect the Express backend.

npm run build does not use proxy

I have a working react.js application, which works using npm start (app built using create-react-app).
When I try to run npm run build, it builds the application. I serve it using
serve -s build -l 3000
It loads the first dashboard page but does not communicate with the server. I have put console.log statements in server to check for any requests coming in, but it never logs anything... which means the client does not talk to the server.
I have proxy statement in package.json to connect to server on port 3300. This works in development mode but in production mode it seems to not pickup the proxy settings in the package.json.
Please guide... this is my first time switching to production mode... any guidance on switching to production mode would help.
BTW I use react-loadable as well...
The proxy field in package.json is only used in development by webpack-dev-server. You can learn more about this here
Thanks for all the help guys....
Finally, I understood that "npm run build" just creates the static files to deploy. But how to use it, is our hands. :)
I copied the build folder inside the /server folder and added the following line in my root server.js file itself. Basically, served the static files from /server/build folder and it all works beautifully.
app.use('/', express.static(__dirname+'/server/build'))
Thanks for the support. :)

Adding server side rendering to an existing React app

I'm trying to build a react app starter that suits my needs. I've read, downloaded, tested countless react boilerplate to try to understand how to add SSR but I'm kind of stuck right now.
The github repo is here
So far I've got React running with hot reload. Webpack 4 bundles the client code. I use a proxy with webpack-dev-server (WDS) to serve my backend express api as well as my client for development.
WDS hot reload change when I update app client code. The express server doesn't restart that way.
I use nodemon to watch the change of the server so that only the backend restarts when I'm coding api features.
For production I simply build the server and client to the dist folder and serve the application with node.
Later I plan to add React router, redux, etc but this is the easy part.
So what I'd like to add now is server side rendering (SSR) for the production mode as I don't need it for development.
Any idea on how I could implement that ?
Thank you
I'll post a further analysis.
Right now I start a webpack-dev-server that allows me to serve and hot reload the client app on localhost:3000
I also launch an express server on localhost:8080 and connect it to the client using the proxy attribute of the devServer
If I modify code on the client app only the hot reload is triggered
If I modify code on the express api only the server api is restarted
From what I understand of SSR and hot reload being put together is that webpack now needs to be compiled in the express server and I add a dev server and a hot reload middleware.
But if I do that each time I modify code of the api nodemon will restart the server and then webpack will compile the client code but I don't need that since I only modified the api.
What I think I need to do is leave things as they are for the development part (because I don't need SSR for dev) but add a production code that will be executed only if NODE_ENV=production, add a template dedicated to serve the html for production with all the renderToString logic
How's that sound ?
Check out Paragons. It has Webpack 4, router, redux, and more all working with SSR. Plus it has both development and production modes.

Heroku and Angular routing

I am working on an Angular front end site built with the Yoeman Angular package. The project is being hosted in Heroku using the Node.js build pack.
Heroku builds the project without errors, it runs Gulp and Bower to install dependencies. After the startup scripts have been executed and the project compiled, the index page loads with no problem but any other page that is not the homepage (like the login page for example) will fall into a “Cannot GET /login” message.
This seems to be a common problem as I have read many posts on how to resolve the Angular routing on Heroku. These are all the actions that I have taken without any success at the moment:
Creating a Node.js web server in Express (I have tried many flavours of this script)
var gzippo = require('gzippo');
var express = require('express');
var morgan = require('morgan');
var app = express();
app.use(morgan('dev'));
app.use(gzippo.staticGzip("" + __dirname + "/dist"));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.listen(process.env.PORT || 5000);
Commenting the dist folder in .gitignore for Heroku to work with it. The dist folder gets push into Git.
Creating the env variables NODE_ENV: true, NODE_PATH: true, NPM_CONFIG_PRODUCTION: false
The site runs perfectly locally when running the dist files as stand-alone on an Apache server or with the Node.js script above.
I would appreciate any comments that would help me resolve this issue on Heroku and Angular. Thanks in advance.
I guess after all this time you were already able to fix this (or you moved on to something else).
In any case, and for anyone running into similar issues, I created a public repo with an Angular2 + Express app that's already configured for deployment on Heroku.
https://github.com/pabloruiz55/Angular-Express-Heroku
I can't fully answer this question as I'm missing info like what errors you are running into, but hopefully, taking a look at my starter project anyone can figure it out.

Resources