This is the question mostly asked by the beginners, as I had this question when I was starting out
How to set port for express without needing to hardcode or even choose port yourself? This is the question I had when I was starting out in node and express (I am still a beginner, have lots of things to learn). Things I wanted know other than that included,
What is difference between using app.set('port', portNum) and directly using port number in app.listen(portNum)?
How to set port for express without needing to hardcode or even choose port yourself?
###Option 1: Environment variable (recommended)
Often times you will deploy your app to a hosting provider like Heroku. Depending on how the host is configured, the system will dynamically set an environment variable and your app will need to get the port from this variable. For example, the hosting provider might run a command like this when it runs your app:
$ PORT=1234 npm start
... and within your code, you can access this variable like this:
const port = process.env.PORT;
app.listen(port);
Pro tip: Most hosting providers let you define custom environment variables too. You can test this locally by creating arbitrary variables like this:
$ FOO=bar ADMIN_EMAIL=joe#example.com npm start
...and access those variables from code like this:
const foo = process.env.FOO; //-> "bar"
const adminEmail = process.env.ADMIN_EMAIL; //-> "joe#example.com"
Option 2 - environment-specific config files (also highly recommended)
Using a config library like config and/or dotenv allows you to easily manage environment-specific config options. Your folder structure would look like this (note the names of the files):
|- config
|- default.json
|- testing.json
|- production.json
|- src
|- app.js
You then define your "default" variables and environment-specific variables:
default.json
{
"port": "3030",
"adminEmail": "dev#example.com"
}
testing.json
{
"port": "5555"
}
production.json
{
"adminEmail": "admin#example.com"
}
The config library will always use the default variables. When you are on testing it will use the default admin email and a different port. When you are on production it will use the default port but a different admin email. The way you define your "node environment" is like this (notice we use the same name as the JSON config files):
$ NODE_ENV=testing npm start
$ NODE_ENV=production npm start
Pro tip: Your configuration files can reference environment variables too! Continuing with our example from Option 1 above, you can define your production config like this:
production.json
{
"port": "PORT"
}
The config library will look for any environment variables named "PORT" and will use that value. Putting it all together, your final command to run your app might look like this:
$ NODE_ENV=production PORT=47861 npm start
Pro tip: - dotenv can be used alongside the config library for ultimate environment variable management!!
2. What is the difference between using app.set('port', portNum) and directly using port number in app.listen(portNum)?
Express allows you to set application variables using app.set - but this is just a fancy way for defining variables. You can later get the values for these variables using app.get.
Sooner or later, you are going to need to tell your app to listen for traffic on a specific port. You could do something like this:
const app = express();
app.set('port', process.env.PORT);
app.use((req, res) => { ... });
app.listen(app.get('port'));
Answers that I found to my questions
1. How to set port dynamically?
I found out that you can use number 0 in app.listen() to let express select the port randomly, then I soon found out that I now had a problem I didn't know which port to access to know if my server was running or not. So simple answer to that was to output the app.address().port in console
so a Simple express server will look like this
let http = require('http');
let express = require('express');
let app = express();
app.use('/', serveStatic('./public'));
app.get('/', (req, res) => {res.render('index')});
let server = http.createServer(app);
server.listen(0, () => {
console.log(server.address().port)
})
2. What is difference between using app.set('port', 1234) and directly using port number in app.listen(1234)?
In my experience/knowledge (honestly speaking its almost equivalent to zero) I came to believe that, app.set() sets the property in app.locals and allows retrieving of that information later (which is somewhat similar to creating a variable), but I recently read that app.set() allows the value stored to be used in you template engine and other places, which makes it quite different.
What is the difference between setting a property on app.locals and calling app.set()?
Unix [1]:
$ PORT=1234 node app.js
More permanently (for a login session) [2]:
$ export PORT=1234
$ node app.js
In Windows:
set PORT=1234
In Windows PowerShell:
$env:PORT = 1234
[1] Process-lived, while the parent process that initiates is still running. If you close terminal, variable dies.
[2] Close terminal, open a new one, variable still alive.
config.js
let config = {};
// PORTS
config.port = {};
config.port.alpha = 4050; // Server 1
config.port.beta = 4051; // Server 2
.....
module.exports = config;
app.js
const express = require("express"),
config = require("./config");
....
app.set('port',config.port[process.env.SERVER_NAME]);
app.listen(app.get('port'),function(){
console.log("Server running at "+app.get('port'));
});
Starting server
SERVER_NAME=alpha node app.js
SERVER_NAME=beta node app.js
Related
I have a Nuxt app running successfully on my local server and all API requests are successfully running from the same server (using the serverMiddleware property in nuxt.config.js). When I run a yarn generate, the path to the API server is lost and no data is loaded. Below are a few screenshots.
Loads data successfully from the API.
Unable to find API
Here is an example of an api call in project_dir api/index.js file
const express = require("express");
const passport = require("passport");
const allRoutes = require("../api/routes/routes");
const guestRoutes = require("../api/routes/guest");
const fileUpload = require("express-fileupload");
const path = require("path");
// Create express instance
const app = express();
// Init body-parser options (inbuilt with express)
app.use(express.json());
app.use(fileUpload());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "../", "dist")));
/**
* -------------- PASSPORT AUTHENTICATION ----------------
*/
// Need to require the entire Passport config module so index.js knows about it
require("./config/passport-jwt");
// Initialize Passport
app.use(passport.initialize());
/**
* -------------- ROUTES ----------------
*/
// Imports all of the routes from ./routes/index.js
app.use(guestRoutes);
app.use(passport.authenticate("jwt", { session: false }), allRoutes);
console.log("express");
console.log(path.join(__dirname, "../", "dist"));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "../", "dist", "index.html"));
});
// Export express app
module.exports = app;
I don't know why I'm not able to get data from the API routes which I'm running on the same server.
Here is an in-depth answer on how to run an Express server alongside Nuxt: https://stackoverflow.com/a/72102209/8816585
First thing to know, is that you cannot have a Node.js server with yarn generate because it's using target: 'static' and as you can guess, when something is static, it doesn't need a Node.js server to be served to the end-user (only the html + css + js static files are hosted on a CDN or alike).
This mode is meant to host the code on Netlify, Vercel or alike, with no Node.js server available there.
Why is it working locally? Because you do have a Webpack dev server running (with a Node.js server so) for debugging purposes like HMR etc...
TDLR: this is normal (works as intended so far). More info on the given link above on how to make it work.
After much research and debugging I came up with a new idea.
Instead of running npm run start or yarn start containing script "nuxt start" inside the package.json file. I added a new script with the name "express-start": "cross-env NODE_ENV=production node api/index.js". Which runs the express server and nuxt static files.
I'm currently creating a template to make it easier for those who'll face this challenge.
Link to a boilerplate I created after solving the issue.
ExpressJs & NuxtJs Boilerplate
I am grouping my files like so:
node_modules
structures
{HTML Files}
styles
{CSS Files}
app.js
package-lock.json
package.json
I've already required those:
const express = require('express');
const app = express();
const path = require('path')
what do I do next?
I assume that you're somewhat of a beginner with Node/Express.
I recommend you learn more about how express works before deploying this into an actual app.
Let's get something straight: I believe that you only have a group of HTML files that you want to show to the user under the file names eg. example.com/about.html with the homepage HTML file being called index.html so that express knows what to show where.
This is the simplest way I could think i'd achieve this effect.
const express = require('express');
const app = express();
const path = require('path');
// This is the port where the application is running on
// Uses the server's enviroment variable named PORT if is defined else
// this will use port 5000
// the page can be seen locally at http://localhost:5000/
const PORT = process.env.PORT || 5000;
// This line makes the app created earlier use the middleware that express provides for "rendering" static files
// inside the express.static method we give a path to the static files
// to create that path we use the path.join method provided by the path module we imported earlier
// this method takes in all the paths that need to be joined.
// the __dirname is the directory the application was launced from (you can use process.cwd() to get the root)
// and ofcourse the structures is the folder which contains all your HTML files
app.use(express.static(path.join(__dirname, "structures")));
// Now we do the same thing we did before but we add the middleware for the styles under the "/styles" URI.
app.use("/styles", express.static(path.join(__dirname, "styles")));
// This will start the server at the PORT which we defined earlier.
app.listen(PORT);
Is it possible to convert a nodejs API server into a node module, which can be used for other projects without making much code changes?
Details: There are several API's(get, post, put) in the node js server. So if I use this server as a node module inside another node server, I must be able to access the API's in the node modules directly from the client. Is this possible? If yes, how?
I am required to do a POC on this for a client requirement and so far did not find it possible. Can you please help? I am relatively new to node js development
main script
const express = require('express');
const app = express()
/*
use some middlewares
*/
require('my-module')(app)
const server = http.createServer(app).listen(process.env.PORT);
module.exports = app;
module
module.exports = (app) =>{
app.get('/',(req,res) =>{
res.send('hi im a diffrent module;')
}
}
I've an application with ES6/js/react UI and Spring boot server side. In my config.js I have host server URL and other properties that changes based on Env. I can use spring active profile to pick up diff set of properties. How do I do similar thing on the js part?
The application is deployed as spring boot application with embedded Tomcat.
Another way to put the question is How can I do Spring profile equivalent in NodeJs/JavaScript world?
My suggestion is to create a server using nodejs to host your static files and act as a proxy server to your backend.
Lately I've used this this seed for my react-projects. I like it a lot, it uses webpack for building the frontend and also provideds you with a handy proxy server that you can use during development (which also gets rid of any CORS issues).
Settings for proxy server: environments.js
I had exactly the need as you: how to use the same idea behind spring profile active environment variable. I used process.env:
const profile = process.env.NODEJS_PROFILES_ACTIVE;
I tested with Windows and Docker as an environment variable.
I have implemented the following and it seems to work .
Set up files like config-dev.js, config-QA.js, config-prod.js . These hold the configuration specific to each environment
Ex config-dev.js
const config_params = {dburl:"mongodb://localhost/mydb", port:5000};
module.exports = config_params
Set up file - config.js which has the below logic
let loadmodule = "./config-" + process.env.profile + ".js";
const setting = require(loadmodule);
module.exports = setting;
In the index file or server.js, import config.js
const config = require('./config.js');
Start the application as 'profile=dev node server.js'
I am new to expressjs and am trying to get my express application (done with the express generator) working on my website, I currently uploaded the directory which is is contained in like so..
http://www.example.com/express-app-here
so I could see it working online. However, when I navigate to where the App is, I seem to only get the directory structure, and express isn't routing me to the appropriate place like it is when I go to localhost:3000.
I take it this has something to do with the fact that express isn't executing my application? Locally,
npm start
needs to be run on the console in order to get it to run, is there some kind of log I need to execute this command in? Or something I need to change in the app.js or /bin directory?
As it was said in the comments, you need to have nodejs installed on your server. It's not as simple as just copying the node app directory over to the server.
You will have to install node and npm on the server, and then run your app from the server, probably using npm start like you were doing on your local machine.
From there, you will want to go into your app code and make sure a route exists for /express-app-here unless you want www.example.com:3000 to take you directly to the express app.
Basically do it like this:`
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
var port = process.env.PORT || config.webServer.port || 3000;
server.listen(port, function () {
console.log('server running');
console.log(port);
console.log(server);
});
exports.module = exports = app;
save it app.js
Go to path via cmd. Now run:-
1)npm install express
2)npm install http
3)node app.js
Will be enough to run express server