I have to execute an ansync function before execute an express server, because I'm going to get a aparameter to pass it to the API. So I guess I can call the async funcion and on the promise I will get, call my express server (until now I have exectued it with "node my_server.js")
How can I do that? How can I call my_server.js on my new js ?
Usually the server does not get created while merely running node server.js. It will just execute javascript contained in server.js. The server will be created when your code reaches express() if you are creating server via express or createServer from plain nodejs.
That means you can probably do
var param = await someSync();
// Set the param in global context and then create your server
var app = express();
// or
var app = createHttpServer()
So now before your app starts you will have that param and you can use it in your api
If you are using promise instead of async, just create your server in then part of your promise, this will also make sure that your app will have that param before your server starts
You can fork a new process using the child_process module in node.
const { fork } = require('child_process')
const path = require('path')
const newProcess = fork(path.join(__dirname, 'path/to/jsfile'), [...otherArgs])
Related
I have created windows service from nodeJs application using node-windows package. Below is my code.
Main.js
var Service = require('node-windows').Service;
// Create a new service object
var svc = new Service({
name:'SNMPCollector',
description: 'SNMP collector',
script: './app.js',
nodeOptions: [
'--harmony',
'--max_old_space_size=4096'
]
//, workingDirectory: '...'
});
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
svc.start();
});
svc.install();
/* svc.uninstall(); */
App.js
const { workerData, parentPort, isMainThread, Worker } = require('worker_threads')
var NodesList = ["xxxxxxx", "xxxxxxx"]
module.exports.run = function (Nodes) {
if (isMainThread) {
while (Nodes.length > 0) {
// my logic
})
}
}
}
Now when I run main.js, it creates a windows service and I can see the service running in services.msc
But, how can I call this run() method which is inside the running service, from any outside application? I couldn't find any solution for this, any help would be great.
You might consider simply importing your run function where you need it and run it there, then there is no need for a windows service or main.js - this assumes that "any outside application" is a Node application.
In your other application you you do the folowing:
const app = require('<path to App.js>');
app.run(someNodes)
For broader usage or if you do need to run it as a service, you could be starting an express (or another webserver) in your App.js with an endpoint that invokes your run function. Then from anywhere else you'll need to make an http call to that endpoint.
App.js
const express = require('express')
const bodyParser = require('body-parser')
const { workerData, parentPort, isMainThread, Worker } = require('worker_threads')
const app = express()
const port = 3000
var NodesList = ["xxxxxxx", "xxxxxxx"]
const run = function (Nodes) {
if (isMainThread) {
while (Nodes.length > 0) {
// my logic
})
}
}
}
app.use(bodyParser.json())
app.post('/', (req, res) => res.send(run(req.body)))
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
(Based off of example for express - https://expressjs.com/en/starter/hello-world.html)
You'll need to install both express and body-parser: $ npm install --save express body-parser from the directory of App.js.
From your other applications you will need to call the endpoint http://localhost:3000 with a POST request and the Nodes as a JSON array.
You can expose it on a port like the other answer mentions, though you'll want to make sure you don't expose it more broadly depending on the environment you're running in. There's a good answer here on ensuring the port is locked down.
As an alternative to exposing it on a port you can simply call the function by running the command in any other application:
node -e 'require("/somePathToYourJS/app").run()'
One concern is that app.js will now run at whatever permissions the calling application has. Although that can be resolved by running runas prior. More details here. But an example is:
runas /user:domainname\username "node -e 'require(^"/somePathToYourJS/app^").run()'"
Assume the following scenario :
Rest client is a module, which has many middlewares; which are themselves modules.
Now, we're trying to create a new middleware that requires client itself to fetch/update metadata for the client input url.
Testing this middleware, will bring in a published version of the client from npm registry, because middleware has a devDependency on the client. But we want to serve our local client.
Also, the published version of client does not contain this new middleware, so it will not allow testing the request pipeline with this middleware.
We want to initiate the client with this middleware, when we're testing the middleware itself to send a request to fetch data.
The middleware is smart enough to not request metadata for metadata, so it will skip the second call. The new flow should be like the diagram below :
Wrap the nodejs module loader, to return local client instead of published one when client is requested during test execution.
describe(()=>{
const localClient = require('../client');
const m = require('module');
const orig = m._load;
before(()=>{
m._load = function(name){
if(name==='client'){
return localClient;
}
return orig.appy(this, arguments)
}
});
after(()=>{
m._load = orig;
});
it('test goes here',()=>{...})
})
I am a bit confused, about how to require and use modules in Node.js.
My scenario is the following:
I wrote a complete server in one single file, which uses Socket.io for realtime communication.
Now the index.js became pretty big, and I want to split the code into several modules to make it more managable.
For example I have some functions for serving a Survey to the clients, and getting back their answers. I put all those functions in a seperate module, and require it in the index.js. Works fine so far.
The only thing I am concerned about is, if there is another way to use the SAME socket instance inside the module.
My current coding looks like this:
index.js:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Survey = require('./survey');
io.on('connection', function (client) {
client.on('getCurrentQuestion', function (data) {
Survey.getCurrentQuestion(parseInt(data.survey_id), client.id);
});
});
server.listen(port, server_url, function () {
Survey.init(io);
});
survey.js:
var io = null;
var Survey = {};
Survey.init = function(socketio) {
io = socketio;
};
Survey.getCurrentQuestion = function(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
module.exports = Survey;
This way it works, but I'm not happy passing io inside an init function to the required module.
What would be "the right way" to do this?
If I require('socket.io') inside the survey module, will it be the same instance as in index.js?
How would I even require that, since it needs the server, which needs the app, which is created in index.js?
I am confused and hope that somebody can help me. Thanks!
When you import a node.JS library you can also pass in objects. In your case the index.js file should be changed to the following:
//index.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Survey = require('./survey')(io);
Then just change your survey.js code to take the io object:
//survey.js
module.exports = function (io) {
var Survey = {};
Survey.getCurrentQuestion = function(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
return Survey;
};
To answer your other question:
If you require('socket.io') inside the survey module, it will be a different instance from index.js.
EDIT
If you want a more modern way of doing it...You could use ES6 format and create a class to do this better:
'ES6 index.js
import SurveyClass from './Survey';
import * as express from 'express';
let app = express();
let server = require('http').createServer(app);
let io = require('socket.io')(server);
let MySurveyClass= SurveyClass(io);
let myInstance = new MySurveyClass();
myInstance.getCurrentQuestion(5, "some-socket-id");
'ES6 survey.js
export default class Survey{
constructor(io){
this.io= io;
};
getCurrentQuestion(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
this.io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
}
When you do this in multiple modules:
var socketio = require('socket.io');
then it will be the same object for all requires.
But if you do this:
var io = require('socket.io')(server);
even if you have the same object in server in both places, io would be a different value because it would come from different invocations of the function returned by require('socket.io') even though those functions would be the same.
If you want to make sure that the io is the same then you'd have do e.g. something like this: Make a module that exports a promise of io and some way to initialize it - a function that gets the server and everything needed. Now, in the place where you have the server you can require the module and initialize it with that exported function, and in other places you can import the module and use a promise.
Instead of a promise you could use callbacks or even just a property on the exported object that could be initially undefined and gets defined when the socket.io is initialized but using a promise would probably be most simple solution to make sure that you're not using it while it's not ready yet.
You didn't mention in your question whether or not you use some framework and which one if any, but some of the frameworks like Hapi give you an easy way to share functionality like that. E.g. see:
https://hapijs.com/tutorials/plugins
If you use Hapi then you should use plugins. If other framework then search for a similar feature.
This has been driving me crazy. I'm new to NodeJS. I love it so far but some things have been throwing me off. I was handed a very basic starting point to a node project and I'm unsure how to search google for this.
//myapp/server.js
var config = require('./config');
var app = express();
var api = require('./app/routes/api')(app, express); // <-- this?
app.use('/', api);
var server = app.listen(3000, function () {
console.log('\n============================');
console.log(' Server Running on Port 3000 ');
console.log('============================\n');
});
Then there's the api.js file that contains the routes.
//myapp/app/routes/api.js
var config = require('../../config');
var mysql = require('mysql');
module.exports = function(app, express) {
var api = express.Router();
api.all('/', function(req, res) {...});
api.all('/route-two', function(req, res) {...});
api.all('/another-route', function(req, res) {...});
return api;
}
Ideally I'd like to break up what's going on here into a more organized structure but, I want to understand what I'm doing exactly.
The main thing that is confusing me is this line
var api = require('./app/routes/api')(app, express);
I was unaware that you can have ()() next to each other without a . or something joining them. Can someone explain what is happening?
Also what is the point of (app, express)? It appears that app and express are getting passed to the api part of the application so it's scope can be reached? Am I way off?
If there is a cleaner approach to this I would love to get some insight. I appreciate any thoughts.
Thanks!
EDIT
To make sure I am understanding...
var api = require('require this file')(params available to this file);
Moving any requires from api.js to server.js then include those as parameters
var api = require('./app/routes/api')(config, app, express, mysql);
EDIT
After more helpful feedback from #AhmadAssaf #Gurbakhshish Singh and #guy mograbi
Modules I want to use in another file other than where they are require()ed should be passed in through the second set of ()
//.server.js
var config = require('./config');
var app = express();
var api = require('./app/routes/api')(config, app, express);
| | |
_____________/______/________/
/ / /
//.app/routes/api.js | | |
module.exports = function(config, app, express) {
var api = express.Router();
// code to handle routes
}
Could be wrong with this part but based on what I think I am understanding.
//.server.js
var config = require('./config');
var app = express();
var register = require('./app/routes/register')(config, app, express);
var login = require('./app/routes/login')(config, app, express);
| | |
_________________/______/________/
/ / /
//.app/routes/login.js | | |
module.exports = function(config, app, express) {...handle login...}
//.app/routes/register.js
module.exports = function(config, app, express) {...handle registration...}
etc. etc.
Hopefully my thinking is about right. I appreciate everyones help on this! :)
So basically you have to understand few thing
module.exports wraps a Javascript object and export it to be used as a pluggable piece of code around a node.js application
The wrapped javascript object can be a JSON object, Javascript variable, function, etc.
What you have up there in the api module is a function that takes two parameters. When you require that module you want to pass some constructors to that function and thats the use of the second () after the module name in the first ()
requiring express once in your program and passing the variable around is more or less a singleton pattern. What you can also do is pass the config object as well to the api module instead of requiring it again :)
var api = require('./app/routes/api')(app, express);
is Equivalent to:
var myFunc = require('./app/routes/api');
var api = myFunc(app, express);
and becauase of NodeJS's module loading procedure, the require('...') will be
plugged in by the piece of code that was exported at the path, it can be a object, function, simple variable, etc.
And as far as ()() goes the require() nodeJS will make it something like function(){}() in your case and this is valid javascript and rather very useful to write IIFE(Immediately-Invoked Function Expression) code
Quesiton 1
explain ()()
every language where a function can return a function you can have this syntax. imagine the following
function world(){ ... }
function hello(){
return world;
}
// ===>
hello()() // ==> would invoke hello and then world.
So when you see require('..')() then it means require('..') returns a function. You do this by writing the following:
module.exports = function(){}
and that function returns yet another function - in your case this means express.Router(); returns a function.
Question 2
is there a cleaner way to write this?
this is a discussion.. which is hard to answer. depends on your preferences. The only thing I can think of that might help you reach an answer is to use the express generator and see the structure the express team uses.. which is probably as clean as it gets.
express can generate a project for you with some code to start with. simply install it with npm install -g express and then run express - it will generate the project for you in the same directory where you ran it.
go over the generated project. I suggest follow the same pattern - this is what i do whenever i cick-off a project.
If something is still unclear or if you need me to elaborate, please comment so and I will edit the answer.
module.exports from api.js is a function, which takes two arguments: app, and express. Therefore, when you require it in server.js with require('./app/routes/api'), the value returned is that function. Since it's a function, you can just call it by putting parentheses after it, and passing in the arguments it expects (app and express), like so : require('./app/routes/api')(app, express).
This is how my app.js looks
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
static = require('node-static'); // for serving files
var game = require('./game.js').createGame();
// This will make all the files in the current folder
// accessible from the web
var fileServer = new static.Server('./');
// This is the port for our web server.
// you will need to go to http://localhost:8080 to see it
app.listen(8080);
// Listen for incoming connections from clients
io.sockets.on('connection', function (socket) {
handle Events ...
});
exports.io = io;
exports.game = game;
when I try to access the created socket.io listner or the game instance I get error saying its undefined.
This how I am trying to access it in trick,js
var game = require('./app.js').game;
var socketio = require('./app.js').io;
var PlayerMove = require('./playerMove.js');
This might be because trick.js is actually executed before app.js (I put debug points and it was confirmed there). How do I avoid this? Is there a better way of exposing object instances in node.js, some pattern that i should probably use ?
declaring a variable does not export it. If you need to export something for your module, you should use exports.myVariable = myValue.
requiring your app.js file for the first time will run it. So everything you export in it will be available once you're out of the require() call