Next.js App reloads frequently in production - reactjs

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.

Related

Shopify CLI 3.0 Ruby app not rendering UI in production

I've been trying to deploy the default shopify rails+react app generated via shopify cli
Deployment is successful but the UI doesn't get rendered. I get a blank screen with the message "This app does not appear to be loading and may be outdated. Try reloading the app in the legacy admin or contact the app's developer to update the app."
The same issue persists when I load the app in legacy admin (.myshopify.com/admin instead of admin.myshopify.com/)
For now, I've tried the following:
Running the Dockerfile locally
Run all commands from Dockerfile locally - bundle install, npm install, rake build:all and rails server -b 0.0.0.0 -e production
Deploy the app to production on cloud66 (which runs the default Dockerfile)
All 3 have the same issue. Don't see any errors in Rails logs as well.
Can anyone help please?
Turns out I missed RAILS_SERVE_STATIC_FILES flag as mentioned here. Not sure why it needs to be added explicitly, but it worked after I added it!

How to inject environment variables in Vercel Non-Next.js apps?

I deployed a regular React app to Vercel and would like to have a API_BASE_URL environment setting with different values for development, preview and production environments.
Typically, I'd use dotenv npm package with my webpack config setting up the variables for local or production depending on the build by looking into env.local and env.production respectively.
The env.production would look like this:
API_BASE_URL=#{API_BASE_URL}
Then, I'd have my deployment pipeline replace all instances of #{___} with the respective values available in the pipeline.
However, the regular way in Vercel seems to be to make a Next.js app and the environment variables in the project will be automatically available in the process.env variable in the backend code.
Is there anyway for us to have environment variables in a non-Next.js in Vercel?
I'm thinking I have 2 ways forward:
There is actually an easy way 🍀
Create my own build and deployment pipeline to replace the #{___} placeholders and deploy using vercel deploy command.
Had a similar issue on my SPA (React + Webpack) app on deployed on Vercel. This is what worked for me.
https://github.com/mrsteele/dotenv-webpack#properties
webpack.config.js
const Dotenv = require('dotenv-webpack');
module.exports = {
// OTHER CONFIGS
plugins: [
new Dotenv({
systemvars: true
})
]
};
Doing it like this I was able to read env vars from:
Vercel build runtime (ex: VERCEL_ENV)
.env file in my src folder
Env variables defined in Vercel console
Initially, I was overlooking an important fact. Vercel deploys builds and deploys changes in the same step.
2 commits in preview branch which are merge them both to main in 1 single commit: that's a totally new thing (a new build is created for every single commit in every environment).
This goes against the build once, deploy to multiple environments principle but I suppose Vercel's team considered that in their quest to make the development process as simple as possible.
Anyway, I worked out 2 solutions:
In the build command, insert the environment variables e.g. in the package.json:
scripts: {
"build": "webpack --env production --env VERCEL_ENV=$VERCEL_ENV"
}
Create my own build and deployment pipeline and then deploy to vercel using vercel deploy command. It also works but I think I'm going to stick to the option for simplicity, at least in the meantime.

process.env.NODE_ENV === "developement" even in production

I want to deploy a React app (made with Create React App) + a Node server with Heroku,
I did it, but my app can't fetch data from the server,
In production, my process.env.NODE_ENV is equal to "development" which causes a lot of wrong stuff in my code,
Do you know what can put process.env.NODE_ENV always at "development"? At the build, this environment variable is supposed to switch to "production", no?
Your package.json add this.
"scripts": {
"start": "export NODE_ENV=development; {your start code}",
Your env variables can be set per environment, in this case in Heroku: https://devcenter.heroku.com/articles/config-vars#using-the-heroku-dashboard
If you want to make sure build always runs with the same NODE_ENV, you can follow #seunggabi 's answer. I'd also use cross-env to make it work cross-platform in such case. Per-process variable can be forced on heroku-postbuild task (after &&).
You can take control of your Environment with env-cmd. They make easy to switch between your local development, testing, staging, UAT or production.
You can refer to this article. This is was very helpful for me

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

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).

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. :)

Resources