how to export modules that requires other modules - javascript

I'm working on a node js project that is getting bigger and bigger, and I'm trying to tidy up my code. This is just a case example.
this is my index.js:
const express = require('express')
const app = express()
const http = require('http').Server(app);
const io = require('socket.io')(http)
io.on('connection', socket => {
socket.on('message', () => doSomething())
})
http.listen(4000, () => console.log('server started'))
and I'd like to import doSomething from another file (say functions.js) like this:
function doSomething(){
console.log(io.sockets.adapter.rooms);
}
module.exports = { doSomething }
modifying index.js as follows:
[...]
const library = require('./functions.js')
[...]
socket.on('message', () => library.doSomething())
but of course:
io is not defined in functions.js.
QUESTION:
How could I import the required modules so that they are shared in both files?

Write your function.js file as below:
function doSomething(){
let self = this;
console.log(self.io.sockets.adapter.rooms);
}
module.exports = function (io) {
let self = this;
self.io = io;
return {
doSomething: doSomething.bind(self)
};
};
And its usage in index.js file will be:
const Library = require('./functions.js');
const library = Library(io);
socket.on('message', () => library.doSomething())

You will have to include the required packages in your functions.js.
Your functions.js should be something like
const io = require('socket.io')(http)
//Include other packages here
function doSomething(){
console.log(io.sockets.adapter.rooms);
}
//Other functions here
//Export all that you need to be exported
module.exports = { doSomething }

Related

Node.js: how to resolve a circular dependency

I know this question has been asked multiple times, but my case is specific:
I have three files, a controller.js, router.js and an app.js,
router.js imports controller.js, app.js imports router.js
I need to import something from app.js to controller.js, how would I do that?
you're probably better off restructuring your code to not need it. Maybe create a third class that uses the other two to accomplish what you need, if you have to use a function in app.js you can do like this:
before requiring you should exports express() and functions
app.js
const express = require("express");
const func = () => {
console.log("I'm in App");
};
var exportFiles = module.exports = {
app: express(),
func: func,
};
var { app } = exportFiles;
const fs = require("fs");
const path = require("path");
const bodyParser = require("body-parser");
app.listen(8080, () => {
console.log("server port is 8080")
})
contolers.js
const {func} = require('../app');
when you call func() in controller result is :
func() // I'm in App

How do you use a JavaScript function from another file

So I have a file:
server.js
const express = require("express");
const app = express();
const rateLimit = require("express-rate-limit");
function rateLimiter(request, ms) {}
function startServer(port, dir) {}
And i want to call those two functions in another file
index.js
const express = require("server.js");
var rate = rateLimiter(100, 60000);
var server = startServer(8080, src);
How can I do that?
write something like:
module.exports = {rateLimiter, startServer}
You need to exports those functions and import them to other files.
Here is the export
server.js
const express = require("express");
const app = express();
const rateLimit = require("express-rate-limit");
function rateLimiter(request, ms) {}
function startServer(port, dir) {}
module.exports = {rateLimiter, startServer}
And here is the import
index.js
const express = require("server.js");
const {rateLimiter, startServer} = require('./server.js'); // your server.js file
var rate = rateLimiter(100, 60000);
var server = startServer(8080, src);

TypeError: is not a constructor with Node and Express JS

I wrote code below and I have a TypeError: Server is not a constructor and I don't see why and how to fixe it.
Server.js code :
const express = require('express');
class Server {
constructor() {
this.app = express();
this.app.get('/', function(req, res) {
res.send('Hello World');
})
}
start() {
this.app.listen(8080, function() {
console.log('MPS application is listening on port 8080 !')
});
}
}
app.js code :
const Server = require('./Server');
const express = require('express');
const server = new Server();
server.start();
You did not export the Server class. In your 'Server.js' file, do this:
export default Server {
...
}
and leave your 'app.js' like this:
const Server = require("./Server");
The above method only works with ES6 and up, if not using ES6:
class Server {
...
}
module.exports = Server;
You need to export your class before import anywhere,
Add the following line at the end of your Server.js
module.exports = Server
ES6
export default Server {
// you implementation
}

How move custom route outside of server.js in jsonServer

In server.js, I am using json-server. I want to move
server.get('/api/1.0/searchDoc', (req, res) => {
const searchType = req.query['searchType'];
const searchValue = req.query['searchValue'];
res.status(200).jsonp({searchType, searchValue});
});
to route.js then import in server.js. How do I achieve it?
Full code
// json server
const jsonServer = require('json-server');
// create server
const server = jsonServer.create();
// data as router
const allDocData = require('../response.json');
const searchDocData = require('../searchResponse.json');
const dataObj = {
'mockResponse': allDocData,
'searchDocData': searchDocData
};
const router = jsonServer.router(dataObj);
// mid-ware
const middlewares = jsonServer.defaults();
// package.json uses port 4000
const port = 4000;
// live before router
// e.g. http://localhost:4000/api/1.0/searchDoc/?searchType='customerId'&searchValue='1234'
server.get('/api/1.0/searchDoc', (req, res) => {
const searchType = req.query['searchType'];
const searchValue = req.query['searchValue'];
res.status(200).jsonp({searchType, searchValue});
});
// use mid-ware
server.use(middlewares);
// use data
server.use(router);
// user body parser
server.use(jsonServer.bodyParser);
// use mid-ware
server.use(middlewares);
// use router
server.use(router);
// listen
server.listen(port);
Do you mean like this? www.js
const JSONServer = require('jsonserver')
function build() {
const server = JSONServer.create()
server.get('/api/1.0/searchDoc', (req, res) => {
const searchType = req.query['searchType'];
const searchValue = req.query['searchValue'];
res.status(200).jsonp({searchType, searchValue});
});
return server
}
module.exports = build
And on another file index.js for example
const build = require('./www.js')
const server = build()
// use mid-ware
server.use(middlewares);
// use data
server.use(router);
// user body parser
server.use(jsonServer.bodyParser);
// use mid-ware
server.use(middlewares);
// use router
server.use(router);
// listen
server.listen(port);
you can if you just return it.
There are a number of ways this could be achieved - another approach would be to inject the server instance into the route.js module which would enable your app's routing concern to be extracted as:
route.js
/*
Define default module function that configures apps routing for the specified
server instance
*/
module.exports = function(server) {
server.get('/api/1.0/searchDoc', (req, res) => {
const searchType = req.query['searchType'];
const searchValue = req.query['searchValue'];
res.status(200).jsonp({searchType, searchValue});
});
}
server.js
const jsonServer = require('json-server');
/*
Import default module function from route.js module. We'll assing this
function to the configureRoutes variable and call it in the server.js when
needed. This import assumes route.js exists in the same directory of this
source file
*/
const configureRoutes = require('./route.js');
const server = jsonServer.create();
const allDocData = require('../response.json');
const searchDocData = require('../searchResponse.json');
const dataObj = {
'mockResponse': allDocData,
'searchDocData': searchDocData
};
const router = jsonServer.router(dataObj);
const middlewares = jsonServer.defaults();
const port = 4000;
/*
Call configureRoutes() to configure routes on your server instance via the
new route.js module
*/
configureRoutes(server);
server.use(middlewares);
server.use(router);
server.use(jsonServer.bodyParser);
server.use(middlewares);
server.use(router);
server.listen(port);

Socket.io - listen events in separate files in node.js

For example my idea is:
File1.js
io.sockets.on('connection', function (socket) {
socket.on('file1Event', function () {
//logic
});
});
File2.js
io.sockets.on('connection', function (socket) {
socket.on('file2Event', function () {
//logic
});
});
This code is for a node server, will I have problems with this code?
Nope, just use the same "io" object.
File1.js
exports = module.exports = function(io){
io.sockets.on('connection', function (socket) {
socket.on('file1Event', function () {
console.log('file1Event triggered');
});
});
}
File2.js
exports = module.exports = function(io){
io.sockets.on('connection', function (socket) {
socket.on('file2Event', function () {
console.log('file2Event triggered');
});
});
}
app.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, file1 = require('./File1')(io)
, file2 = require('./File2')(io)
app.listen(3000);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
index.html
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.emit('file1Event'); // 'file1Event triggered' will be shown
socket.emit('file2Event'); // 'file2Event triggered' will be shown
</script>
Be careful not to generate a new connection event for each file. You should use the same on('connection') event, otherwise after 10 files imported, you will get this error from node: MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connection listeners added. Use emitter.setMaxListeners() to increase limit.
The better way is to do like this in your main file:
io.on('connection', function (socket) {
require('pathToSocketRoutesFile1')(socket);
require('pathToSocketRoutesFile2')(socket);
require('pathToSocketRoutesFileN')(socket);
return io;
};
and in each separate file:
module.exports = function(socket) {
socket.on('eventName1', function() {
//...
});
socket.on('eventName2', function() {
//...
});
};
Another option is to create a rootSocket which handles the initial connection and then passes the socket to other handlers.
const rootSocket = (io) => {
io.sockets.on('connection', (socket) => {
authorization(socket);
chat(socket);
});
};
exports.default = rootSocket;
You Can use IO module in any route just create global middleware.
socketiomw.js
module.exports = (io)=>{
return (req,res,next)=>{
req.io = io;
next();
}
}
middlewares.js
module.exports.global = {
socketIo:require('./socketiomw'),
// add other global middleware
};
index.js
const express = require('express');
const app = express();
const port = 3000;
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
//global middleware initialization
app.use(require('./middlewares').global.socketIo(io));
app.get('/notify',(req,res)=>{
req.io.emit("hello");
req.io.to("someRoom").emit("some event");
req.io.to("room1").to("room2").to("room3").emit("some event");
req.io.of("/").adapter.on("create-room", (room) => {
console.log(`room ${room} was created`);
});
req.io.of("/").adapter.on("join-room", (room, id) => {
console.log(`socket ${id} has joined room ${room}`);
});
req.json({ success:true })
);
server.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
I used this in global middleware so i can use this io module in any routes
rootSocket.js :
const rootSocket = (io) => {
io.on('connection', (socket) => {
console.log('New connection');
// possibility to outsource events
socket.on('myEvent', () => {
console.log('myEvent triggered');
});
});
}
module.exports = rootSocket;
index.js :
const express = require('express');
const app = express();
//app.use(express.json());
//const cors = require('cors');
//app.use(cors());
const http = require('http');
const server = http.createServer(app);
const socketIo = require('socket.io');
const io = socketIo(server);
const rootSocket = require('./rootSocket')(io);
const port = 8000;
// process.env.PORT for production
server.listen(port, () => console.log('server started on ' + port));

Categories

Resources