Cost of importing in Javascript [duplicate] - javascript

So I'm planning to separate my functions into separate files and then import them into a single index.js which then becomes the main exporter. So I'm wondering if having something like var bcrypt = require('bcrypt') in several of my files be slower than just having it in one file.
Here's how I'm planning to group and export in index.js
const fs = require('fs');
const path = require('path')
const modules = {}
const files = fs.readdirSync(__dirname)
files.forEach(file => {
if (file === 'index.js') return
let temp = require(path.join(__dirname, file))
for (let key in temp) {
modules[key] = temp[key]
}
});
module.exports = modules
As an example of what I mean:
file1.js
var bcrypt = require("bcrypt");
module.exports.file1test = "hi"
file2.js
var bcrypt = require("bcrypt");
module.exports.file2test = "bye"

No, it does not. Whenever a module is required for the first time, the module's code runs, assigns something to its exports, and those exports are returned. Further requires of that module simply reference those exports again. The logic is similar to this:
const importModule = (() => {
const exports = {};
return (name) => {
if (!exports[name]) exports[name] = runModule(name);
return exports[name];
};
})();
So, multiple imports of the same module is no more expensive than referencing an object multiple times.

Related

How can you prevent multiple instances of imported modules using node.js?

I have three files and I am attempting to share a variable I have called sharedArray, stored in the array.js file, on my main js file and another file fileA using export. Although, it appears that main.js and fileA.js create their own instances of array.js. Is there any way to prevent this and have both main.js and fileA.js point to the same variable sharedArray?
main.js
const electron = require('electron');
const path = require('path');
const arrayJS = require(path.join(__dirname,"array.js"));
const {ipcMain} = electron;
function countArray(){
console.log(`There are ${arrayJS.sharedArray.length} values in shared array`);
}
ipcMain.on('countArrayFromMain', function(e){
countArray();
});
array.js
var sharedArray = [];
function getSharedArray(){
return sharedArray;
}
function setSharedArray(newArray){
sharedArray = newArray;
}
module.exports = {
getSharedArray,
setSharedArray
}
fileA.js
const electron = require('electron') ;
const {ipcRenderer} = electron;
const arrayJS = require(path.join(__dirname,"array.js"));
var newArray = [1,2,3];
arrayJS.setSharedArray(newArray);
console.log(`There are ${arrayJS.sharedArray.length} values in shared array`); // outputs 3
ipcRenderer.send('countArrayFromMain'); // outputs 0
Per code, main.js represents Main process of Electron and filaA.js is for Renderer process. Since those 2 are different process, there is no way to share same object reference across processes: you should use IPC to ask one process's value if you want to achieve singleton across process.

webpack function usage after bundling

I try to pack that https://www.npmjs.com/package/#jscad/dxf-deserializer library and use in browser.
Uage from node looks like
const deSerializer = require('#jscad/dxf-deserializer')
const rawData = fs.readFileSync('PATH/TO/file.dxf')
const jscadCode = deSerializer(rawData)
How should i use that now after linking bundle script?
I had tried
let objs = deserialize(fileText,'square10x10',{output: 'csg'})
and got
ReferenceError: deserialize is not defined
There is js test file works fine with node
const fs = require('fs')
const path = require('path')
const test = require('ava')
const { CSG, CAG } = require('#jscad/csg')
const { nearlyEqual } = require( '../../../test/helpers/nearlyEqual' )
const { deserialize } = require( '../index' )
const samples = path.resolve('../../node_modules/#jscad/sample-files')
//
// Test suite for DXF deserialization (import)
//
test('ASCII DXF from Bourke 3D Entities to Object Conversion', t => {
//const dxfPath = path.resolve(__dirname, '../../../../sample-files/dxf/bourke/3d-entities.dxf')
const dxfPath = path.resolve(samples, 'dxf/bourke/3d-entities.dxf')
t.deepEqual(true, fs.existsSync(dxfPath))
let dxf = fs.readFileSync(dxfPath, 'UTF8')
let objs = deserialize(dxf,'aaa',{output: 'objects'})
// expect one layer, containing 2 objects (CSG, and Line3D)
t.true(Array.isArray(objs))
t.is(objs.length,2)
})
Try Adding
node: {
fs: "empty"
}
fs module isn't defined in the browser.
Maybe that's what stopping deserialize from been created. With a try.

Node.js require multiple files in the same folder

I'm building a discord bot with node.js for my server and I have a bunch of commands for the bot. Each command is in a different file so I have a lot of const cmd = require("../commands/cmd.js");
const kick = require("../commands/kick");
const info = require("../commands/info");
const cooldown = require("../commands/cooldown");
const help = require("../commands/help");
Is there a simpler way to do this?
Inside folder commands put a file called index.js.
Each time you implement new commands in new file, require that file in index.js and then add it to the exports of it. For example index.js would be:
const kick = require('./kick');
const info = require('./info');
module.exports = {
kick: kick,
info: info
}
And then from any folder you can require multiple commands in one line like this:
const { kick, info } = require('../commands');
Export an object from one file instead?
const kick = require("../commands/kick");
const info = require("../commands/info");
const cooldown = require("../commands/cooldown");
const help = require("../commands/help");
const commands = {
kick,
info,
...
}
module.exports = commands;
And then:
const commands = require('mycommands')
commands.kick()
Create index.js file inside the command folder and then you can export an object like this.
const kick = require("../commands/kick");
const info = require("../commands/info");
const cooldown = require("../commands/cooldown");
const help = require("../commands/help");
const command = {
kick,
info,
cooldown,
help
};
module.exports = command;
You can import and use it like this:
const {kick, info} = require('./commands');

Nodejs - How to get the version of a dependency

Is there a way to get the version of an external dependency in JS code, without hardcoding it?
If you wanted to get the value of express you could do something like the following. You are looping over each folder in the node modules and adding the name and the version to an object.
const fs = require('fs');
const dirs = fs.readdirSync('node_modules');
const packages = {};
dirs.forEach(function(dir) {
const file = 'node_modules/' + dir + '/package.json';
const json = require(file);
const name = json.name;
const version = json.version;
packages[name] = name;
packages[version] = version;
});
console.log(packages['react-native']); // will log the version

how to access app outside the server.js file?

I have two files:
server.js
const app = express();
require('./server/config/crawlerBasedModels.config').basedModels()
.then((models) => {
app.locals.basedModels = models;
console.log(app.locals.basedModels);
})
.catch(err => console.log(err));
crawlerBasedModels.config:
const fs = require('fs');
const Promise = require('bluebird');
module.exports = {
basedModels: () => {
return new Promise((res, rej) => {
let basedModelsPath = require('../config/exportFolderPath');
const basedModels = JSON.parse(fs.readFileSync(basedModelsPath + '/basedModels.json'));
if(basedModels) {console.log(basedModels); return res(basedModels);}
return rej('couldnt load basedModels file!');
});
}
};
in console i see:
undefined
My question is how can I set a global var within my app that will be exposed for the entire of the app lifetime?
There are two ways to accomplish this.
<app.js>
const app = module.exports = express();
app.locals.test = 'test is valid';
<anotherfile.js>
const app = require('./app');
console.log(app.locals.test);
Now, anytime you require app, it will set the app.locals and it'll be accessible to you in another file.
Another way to do it is to have a separate blank file, called global.js.
<global.js>
empty file
<test1.js>
const global = require('./global');
global.test = 'setting var in test1.js';
<test2.js>
const global = require('./global');
console.log('global vars %j', global);
<node.js runtime>
> const a = require('./test1.js')
> const b = require('./test2.js');
global vars {"test":"setting var in test1.js"}
The only caveat here will be test1 has to be required before you can access the global variable. But, your use case demands that as well, setting something in app.locals and then using it somewhere else.

Categories