What does const {app} =require('module') indicate in node js [duplicate] - node.js

This question already has answers here:
What does this symbol mean in JavaScript?
(1 answer)
Javascript object bracket notation ({ Navigation } =) on left side of assign
(5 answers)
Closed 12 months ago.
I am new to node js, while going through few bogs and tutorials I came across one thing different way to import module
For some people use:
const {app} = require('./routes/index');
Few sites follow:
const app= require('./routes/index');
So what is difference between first and second, I am really confused with this and didn't get any proper explanation about this

Short Answer
const app = require('./routes/index');
imports the default value or everything at once from that file
const { app, app2 } = require('./routes/index');
imports specific object/s from that file.
LONG ANSWER
There are two ways to import something from ./routes/index.js.
The first one is,
const app = () => {
console.log("Sample function")
}
// MOST IMPORTANT!
export default app
// Here, we are exporting app from that file as default. We use this normally, when we export only one thing from a file, and in this case, you can use,
const app = require('./routes/index')
As, only one object is getting exported, so you can use this, BUT!
Second Case:-
const app = () => {
console.log("Sample Function 1")
}
const app2 = () => {
console.log("Sample Function 2")
}
export { app, app2 }
// Here, we are exporting two different objects/functions NOT as default. As there are two different object, you need to specify which one to import
Now, to import one of these function, we can use,
const { app2 } = require('./routes/index');
// OR
const { app } = require('./routes/index');
// OR
const { app, app2 } = require('./routes/index');
If you want to import both at once, you can also use,
const app = require('./routes/index')
// The first function can be accessed/called by,
app.app()
// or
app.app2()
But, as this makes it more confusing and takes up more memory, so we don't import all at once normally.

Related

Node js - Issue with my syntax in require(module) . When to use {} and when not to use {} in require('module')

I have a query with the syntax in the require statement. Please refere the sample code below.
const nodemailer = require("nodemailer");
const {google} =require('googleapis');
const {OAuth2}=google.auth;
Some times , I see sample codes which use
const {<variable>} = require('moduleName')
Other times, I see like below
const <variable> = require('moduleName')
What is the difference between them?
Thanks in Advance.
Grateful to the Developers Community.
So, you use { } in this context when you want to do object destructuring to get a property from the exported object and create a module-level variable with that same name.
This:
const { google } = require('googleapis');
is a shortcut for this:
const __g = require('googleapis');
const google = __g.google;
So, within this context, you use the { google } only when you want the .google property from the imported module.
If you want the entire module handle such as this:
const nodemailer = require("nodemailer");
then, you don't use the { }. The only way to know which one you want for any given module is to consult the documentation for the module, the code for the module or examples of how to use the module. It depends entirely upon what the module exports and whether you want the top level export object or you want a property of that object.
It's important to realize that the { } used with require() is not special syntax associated with require(). This is normal object destructuring assignment, the same as if you did this:
// define some object
const x = { greeting: "hello" };
// use object destructuring assignment to create a new variable
// that contains the property of an existing object
const { greeting } = x;
console.log(greeting); // "hello
When you import the function with {}, it means you just import one function that available in the package. Maybe you have've seen:
const {googleApi, googleAir, googleWater} = require("googleapis")
But, when you not using {}, it means you import the whole package, just write:
const google = require("googleapis")
So, let say when you need googleApi in your code. You can call it:
google.googleApi

How to break a single node.js file into many?

Hi,
I have an app on node.js which consists of a single file app.js that looks like this:
//variables
app = require("express")();
//many more variables here
//functions
function dosomething {}
//many more functions here
but since its getting a little too long I would like to break it into several files, one for variables only (variables.js) and another one for functions only (functions.js) and load them from app.js like this like when you do it with php
//variables
include(variables.js);
//functions
include(functions.js);
is it even possible to do that? Or I have to include everything in one single file like I do now?
Thank you.
You can use Module.Export to export a separate file, and import it into another file using the require statement. Please check here for details:
https://www.geeksforgeeks.org/import-and-export-in-node-js/
Happy Learning :-)
Importing API Endpoints
You can do this by using app.use(...) and point each endpoint to a specific file like so:
const express = require("express");
const app = express();
// User Functions
app.use("/api/user", require("./routes/api/user"));
//Orders functions
app.use("/api/orders/", require("./routes/api/orders"));
/**
* Express Server Init
*/
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on ${PORT}`));
Then in /routes/api/user/user.js you would have something like:
const express = require("express");
const router = express.Router();
router.post("/create", (req, res) => {
try {
// Create user
} catch (error) {
console.log(error);
res.sendStatus(500);
}
});
module.exports = router;
Add and index.js inside /routes/api/user to point at the user file to keep things pretty when importing (otherwise you have to import it like /routes/api/user/user):
const user = require("./user");
module.exports = user;
Importing Single File
Not sure your use case but variables could be a bad naming convention since these values are more like constants than variables. Either way, you create it like this:
const variables = {
varibleOne: "valueOne",
varibleTwo: "valueTwo",
varibleThree: "valueThree",
};
module.exports = variables;
Then wherever you want to import it you can do:
const variables = require("./variables");
and access it like so variables.variableOneand so on.
Importing functions
You can also import different functions, say you need a file called helper.js where these are commonly functions needed all over you app, you could do something like this:
const twoDecimals = (number, decimal = ",") => {
let val = (Math.round(number * 100) / 100).toFixed(2);
return decimal === "." ? val : val.replace(".", decimal);
};
const getRandomInt = (max) => {
return Math.floor(Math.random() * Math.floor(max));
};
module.exports = { twoDecimals, getRandomInt };
Then wherever you needed you can import it by:
const { twoDecimals } = require("helper.js");
Now you have access to your helper functions anywhere.
You should get help from the JavaScript modular system (preferably COMMONJS).
For example, suppose we have two files:
1-module.js 2-app.js
So now let's create this files
module.js
let name = "hello world";
function printSomething(message) {
console.log(message)
}
//here export all function and variable
module.exports.name = name;
module.exports.printSomething = printSomething
ok so Well now it is enough that "require" this file in main file :
main.js
// we
const {name, printSomething} = require("./module.js");
printSomething(name);
for export all variable You need to create an object and specify your variables as a property:
let host = "localhost"
let dbname = "laravel_8"
let username = "root"
let password = "root"
function doSomething() {
console.log("hello");
}
module.exports = {host, dbname, username, password, doSomething}
so in main file :
const variables = require("./module.js")
//host
let host = variables.host
//dbname
let dbname = variables.dbname
//function doSomething
let doSomething = variables.doSomething;
doSomething()
// or directly
variables.doSomething()
In fact, in php we use the "->" symbol to access properties, and in JavaScript we use "."

Best practices in structuring Node.js & Socket.io app?

Currently I'm developing a node server which uses websockets for communication.
I'm used to applying MVC (or MC) pattern in my apps. I'd like to structure my socket.io in similiar way and my question is how to do this in the best way?
For now I have something like this:
utils/socket.ts:
type IO = null | SocketIO.Server;
let io: IO;
export function init(ioServer: IO) {
io = ioServer;
}
export function getIO(): IO {
return io;
}
app.ts:
import express from 'express';
...
import { init } from './utils/socket';
import startSockets from './controllers';
const app = express();
...
const server = app.listen(process.env.PORT || 5000);
const io = socketio.listen(server);
if (io) {
init(io);
io.on('connect', startSockets);
}
controllers/index.ts:
import { onConnect } from './connect';
import { getIO } from '../utils/socket';
export default function (socket: SocketIO.Socket) {
const io = getIO();
socket.on('connect-player', onConnect);
}
controllers/connect.ts:
import Player from '../models/Player';
export const onConnect = async function (this: SocketIO.Socket, name: string) {
const player = await Player.create({ name });
this.broadcast.emit('player-connected', `Player ${name} joined the game!`);
this.emit(
'player-connected',
`Congratulations ${name}, you successfully joined our game!`,
player,
);
this.on('disconnect', onDisconnect.bind(this, player.id));
};
const onDisconnect = async function (this: SocketIO.Socket, playerId: string) {
const player = await Player.findById(playerId);
await player?.remove();
this.broadcast.emit(
'player-connected',
`Player ${player?.name} left our game!`,
);
};
I'm not sure about using 'this' in my controller and about that singleton pattern in utils/socket.ts. Is that proper? The most important for me is to keep the app clear and extensible.
I'm using express and typescript.
Player.ts is my moongoose schema of player.
I had been struggling with socket.io + express.js a while back, specially I am as well use to apply MVC patterns.
While searching, googling and stack overflowing, these links helped me with the project back than.
https://blueanana.github.io/2017/03/18/Socket-io-Express-4/
https://github.com/onedesign/express-socketio-tutorial
https://gist.github.com/laterbreh/5d7bdf03258152c95b8d
Using socket.io in Express 4 and express-generator's /bin/www
I wont say what is the best way or not, I dont even like that expression. But I will say it is a way, which helped to keep it clear, extensible, organized and very well modularized.
Specially that each project has its own intrinsic requirements and needs.
Hope these can get to help you as well as it did it for me, get the feeling and understanding of how and what it needs to be done on the project.

How to get properties defined outside of module.export from require object

I am struggling to get const properties define outside of module.exports from the object where I am using that module. here is simple example:
ServiceX.js
const _ = require('lodash');
module.exports = {
testFirstName: function () {
console.log('Nodics');
}
}
ServiceY.js
const utils = require('utils');
module.exports = {
testLastName: function () {
console.log('framework');
}
}
now if I import both file via require and merging via _.merge(). Output file contain both of the methods, but it doesn't contain any of the const variable define outside exports.
let combined = _.merge(require('ServiceX'), require('ServiceY'));
writing this combined to the third file some this MyService
even if I print this combined object via console.log(combined), I get only both functions, not const properties.
Use case I have:
I have n-number of files in different location, I need to read files, merge all and create a new file with merged content.
Please help me,
Thanks
A problem here is that a service currently looks like:
const _ = require('lodash');
module.exports = {
testFirstName: function () {
console.log('Nodics');
}
}
And the reason for that is that if you read all files and concatenate the result then module.exports will be overwritten by the last read file.
But if it instead looked like:
const _ = require('lodash');
module.exports.testFirstname = function () {
console.log('Nodics');
}
You could pull it off by doing fs.readFileSync() on all your services and concatenate the result.
You could also do it as a build command, rather than in code:
cat service*.js > combined.js
You will most likely run into other problems, since if one service uses const _ = require('lodash') and another is doing the same you will try to redefine a const variable.
To get around this you could move have to move your requires into another scope, so they don't conflict at file level scope.

Organizing requires and moving them to document Top

I am organizing code in a app. The require statements are un-organized so I made this codemod to sort them and to add them on top of the page.
The codemod works, almost perfect. I have some doubts:
is this a ok approach, or is there a more correct way to use the API?
how can I keep the empty line between the sourceStart (all the requires) and the rest of the source code?
can a similar approach be used in ES6 imports? (ie to sort them with jscodeshift)
My Initial code:
var path = require('path');
var stylus = require('stylus');
var express = require('express');
var router = express.Router();
var async = require('async');
let restOfCode = 'foo';
My codemod:
let requires = j(file.source).find(j.CallExpression, {
"callee": {
"name": "require"
}
}).closest(j.VariableDeclarator);
let sortedNames = requires.__paths.map(node => node.node.id.name).sort(sort); // ["async", "express", "path", "stylus"]
let sortedRequires = [];
requires.forEach(r => {
let index = sortedNames.indexOf(r.node.id.name);
sortedRequires[index] = j(r).closest(j.VariableDeclaration).__paths[0]; // <- feels like a hack
});
let sourceStart = j(sortedRequires).toSource();
let sourceRest = j(file.source).find(j.CallExpression, {
"callee": {
"name": "require"
}
}).closest(j.VariableDeclaration)
.replaceWith((vD, i) => {
// return nothing, it will be replaced on top of document
})
.toSource();
return sourceStart.concat(sourceRest).join('\n'); // is there a better way than [].concat(string).join(newLine) ?
And the result I got:
var async = require('async');
var express = require('express');
var path = require('path');
var stylus = require('stylus');
var router = express.Router(); // <- I would expect a empty line before this one
let restOfCode = 'foo';
is this a ok approach, or is there a more correct way to use the API?
You shouldn't be accessing __paths directly. If you need to access all NodePaths, you can use the .paths() method. If you want to access the AST nodes, use .nodes().
E.g. the mapping would just be
let sortedNames = requires.nodes()(node => node.id.name).sort(sort);
how can I keep the empty line between the sourceStart (all the requires) and the rest of the source code?
There isn't really a good way to do this. See this related recast issue. Hopefully this will become easier one day with CSTs.
can a similar approach be used in ES6 imports? (ie to sort them with jscodeshift)
Certainly.
FWIW, here is my version (based on your first version):
export default function transformer(file, api) {
const j = api.jscodeshift;
const sort = (a, b) => a.declarations[0].id.name.localeCompare(
b.declarations[0].id.name
);
const root = j(file.source);
const requires = root
.find(j.CallExpression, {"callee": {"name": "require"}})
.closest(j.VariableDeclaration);
const sortedRequires = requires.nodes().sort(sort);
requires.remove();
return root
.find(j.Statement)
.at(0)
.insertBefore(sortedRequires)
.toSource();
};
}
https://astexplorer.net/#/i8v3GBENZ7

Resources