Project deployed on heroku works wrong with routes - node.js

I deployed project on Heroku.
It was working well on dev, but on production it has problems with routing. It always tries to use server api routes on client side. What is wrong with this code?
app.use("/api/games", games);
app.use('/public', express.static(path.join(__dirname, '/public')));
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
I also wrote Heroku-postbuild script in package.json
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
Client side works on React

Please try to run app in production mode or set NODE_ENV to production.
I think this NPM_CONFIG_PRODUCTION=false will run your app in development mode so you have to set it to true ( NPM_CONFIG_PRODUCTION=true ).
Please also print process.env.NODE_ENV before if statement to check your env mode.

After scripts list in package.json I added engines with node and npm versions and it started to work well
"scripts": {
...
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"engines": {
"node": "10.15.3",
"npm": "6.4.1"
},

Related

Heroku Error 404, "ENOENT: no such file or directory, stat '/app/client/build/index.html'"

I am trying to deploy MERN website in heroku but getting following error:
"ENOENT: no such file or directory, stat '/app/client/build/index.html'"
I have ran the project locally, and everything is working fine.
I have added the following in package.json:
"heoku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
also here is the code in my server.js
// Deployment
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "../client/build")));
app.get("*", (req, res) =>
// res.sendFile(path.resolve(__dirname, "../client", "public", "index.html"))
res.sendFile(path.resolve(__dirname, "../client/build/index.html"))
);
} else {
app.get("/", (req, res) => {
res.send("API IS RUNNING.");
});
}
It should create react build folder by running npm run build but I think heroku-postbuildcommand is not working.
I misspelled heroku to heoku so the actual command in package.json should be:
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"

React.js Production Deployment that runs at the background/does not affect from windows log-off and restart

I have an react.js frontend application that is created with creact-react-app utility. I intend to run the app on a windows server machine and it has the following build/run tasks that are defined in my package.json file:
"scripts": {
"build:dev": "env-cmd -f .env.dev npm run build",
"build:test": "env-cmd -f .env.test npm run build",
"build:prep": "env-cmd -f .env.prep npm run build",
"build:prod": "env-cmd -f .env.prod npm run build",
"start-server": "env-cmd -f .env.prod node server/server.js"
}
So, for preparing my app for deployment on a windows server, I issue the following while I am inside the OS with an open command console:
npm run build:prod
npm run start-server
As a result of "npm run build:prod", the bundle is placed under my build directory in my project root. On the other hand, executing "npm run start-server" executes the following script, which is server/server.js.
const path = require('path');
const express = require('express');
const app = express();
const publicPath = path.join(__dirname, '..', 'build');
const port = process.env.REACT_APP_PORT;
app.use(express.static(publicPath));
app.get('*', (req, res) => {
res.sendFile(path.join(publicPath, 'index.html'));
});
app.listen(port, () => {
console.log('Server has started listening at port ' + port);
});
Everything is fine until here, my application works but it keeps the command console busy. What I need is to run the app in the background and even if I log out windows, the app should continue to run and respond to requests. Moreover, it should start after windows restart. What would be the most convenient approach to realize this? I have read the create-react-app documentation but I did not get much help. In addition I noticed there is an npm package named pm2, but my corporate regulations dont let me install it unfortunately.
QUESTION: So, briefly I need your suggesstions on what would be the best practice approach to run my react.js front-end app at the background such that it keeps alive after log off and get restarted after windows restart? Thanks.

How can I run a node server with a next.js application?

I'm setting up a webapp in next.js that runs in parallel with a node express server which does some middleware work to interface with an API server.
I have everything working however I don't know how to make it all work together when making a npm run start. The only way it works is with a "node server.js" in one terminal and a "npm run start" in another.
I've tried to add a package.json script like this:
"start-server": "next start && node server.js"
but it only starts the next.js instance, and if I reverse the order then it only starts the node instance.
How do I make them both work so I can deploy this project?
Also since Next is a server-side package, you can build the next app to use your server.js code before deploying the server.
like so:
/* eslint-disable no-undef */
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const options = {
...
};
app.prepare().then(() => {
const server = express();
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen('8700', err => {
if (err) throw err;
console.log(`> Ready on Port 8700`);
});
});
Install Concurrently npm package to your node dependencies.
npm install concurrently
Add the following scripts to node server's package.json
"frontend-install": "npm install --prefix frontend",
"start": "node server.js",
"server": "nodemon server.js",
"frontend": "cd ./frontend && npm run start",
"dev": "concurrently \"npm run server\" \"npm run frontend\""
i am assuming that your next application is in a folder/directory called "frontend".
3. Add the following code to package.json of the nextjs application.
"proxy": "http://localhost:5000"
Now npm run start command to start node server and nextjs app together.

can i use heroku post build script on azure?

hi i have a nodejs and reactjs application in my local , developed the application from a boiler plate code , in boiler plate code package.json i have these following scripts
"scripts": {
"client-install": "npm install --prefix client",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
}
as of i know it can be deployed on heroku with these scripts , can i use same scripts to deploy on azure , do i need to change anything here .
// Serve static assets if in production
if (process.env.NODE_ENV === "production") {
// Set static folder
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
and this is what i have in my server.js as a starting point. i don't have any config folder to diff environments.for an example
// i don't have this folder structure and am not using webpack
-- config
|-- dev.json
|-- prod.json
can some one suggest , what is the best way to deploy it , or can i use same post-build script by changing it key like azure-postbuild
edited : i think i should use postinstall instead of heroku-postbuild

How to run production site after build vue cli

I'm using VueCLI 2 and build as production. THe build.js is built and compiled into 200KB. When I re-run the server as development, it loaded 3MB. I'm sure the build.js inside dist folder is 200KB. I tried to open index.html but it doesn't work and redirect to root directory on website.
Package.json
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
Webpack
module.exports = { ...
module:{
...
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
jQuery: 'jquery'
})
],
devtool: '#eval-source-map'
},
...
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: true
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
return module.context && module.context.indexOf('node_modules') !== -1;
}
})
])
}
HTML
<body>
<script src="/dist/vendor.js"></script>
<script src="/dist/main.js"></script>
</body>
Command
npm run build
npm run dev
npm run build creates a dist directory with a production build of your app.
In order to serve index.html in a browser you need an HTTP server.
For example serve:
npm install -g serve
serve -s dist
The default port is 5000, but can be adjusted using the -l or --listen flags:
serve -s build -l 4000
Docs:
https://create-react-app.dev/docs/deployment#static-server
https://github.com/zeit/serve
https://cli.vuejs.org/guide/deployment.html#previewing-locally
Production build can be run locally by utilizing Vue CLI's tooling simply by running:
vue-cli-service serve --mode production
For convenience, this can be added to package.json scripts:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"production": "vue-cli-service serve --mode production"
}
Command:
$ npm run production
Very easy with express, and highly extensible/configurable.
Install
npm install -D express
Compose
server.js
// optional: allow environment to specify port
const port = process.env.PORT || 8080
// wire up the module
const express = require('express')
// create server instance
const app = express()
// bind the request to an absolute path or relative to the CWD
app.use(express.static('dist'))
// start the server
app.listen(port, () => console.log(`Listening on port ${port}`))
Execute
node server.js
The Vue CLI tooling (vue-cli-service serve --mode production) still seemed to be serving the development files for me, albeit with process.env.NODE_ENV === 'production'.
To serve the contents of dist, the following worked for me without having to install any extra packages:
npm run build
npx serve dist
With custom port and SSL key/certificate:
npx serve dist -l 8095 --ssl-cert .\cert.pem --ssl-key .\cert-key.pem
You can also put this command into your package.json, e.g.
"scripts": {
"serve": "vue-cli-service serve",
"prod": "npx serve dist",
...
}
Then just do:
npm run prod
Build should be deployed to the server, Hence, I don't think that there is any inbuilt way in vue-cli to run build locally.
To run build locally, we need to configure the server separately and run the build on the server as follow,
1) Install lite server via below command
$ npm install -g lite-server
2) Add below scripts in package.json
"lite": "lite-server –port 10001",
"start": "npm run lite"
3) In root directory create bs-config.js file and add below script
module.exports = {
port: 3000,
server: {
baseDir: './dist'
}
}
4) Lastly, Run it via below command
$ npm run start

Resources