Node.js require multiple files in the same folder - javascript

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');

Related

Check if child_process can run a command in NodeJS

how can I check if child_process can run a command?
'echo' is a valid command that can be run in a terminal, but 'echoes' is not one. For example, if I do this
const cp = require('child_process')
cp.exec('echo hello')
it will work.
If I do this, though
const cp = require('child_process')
cp.exec('echoes hello') //notice how it is echoes instead of echo
it will just error, but maybe the user has a program that adds 'echoes' to a terminal, and in that case, it would be able to run, but if it errors it will just exit out of the process and I won't be able to check if it works.
Is there any way to do this? Thank you so much in advance!
You have to manually loop through dirs in $PATH env & perform look up on those directory.
eg: $PATH is set to /bin:/usr/local/bin then you have to perform
fs.access('/bin/' + command, fs.constants.X_OK)
and
fs.access('/usr/local/bin/' + command, fs.constants.X_OK)
solution would look like this.
const { constants: fsconsts } = require('fs')
const fs = require('fs/promises')
const path = require('path')
const paths = process.env.PATH.split(':')
async function isExecutable(command) {
const cases = []
for (const p of paths) {
const bin = path.join(p, command)
cases.push(fs.access(bin, fsconsts.X_OK)) // X_OK is bit flag which makes sure file is executable
}
await Promise.any(cases)
return command
}
const found = (bin) => console.log('found', bin)
const notfound = (errors) => {
console.log('not found or not executable')
// console.error(errors)
}
// passes
isExecutable('echo').then(found).catch(notfound)
isExecutable('node').then(found).catch(notfound)
// fails
isExecutable('shhhhhh').then(found).catch(notfound)
isExecutable('echoes').then(found).catch(notfound)
NOTE: I think my solution works only on *nix based OSs

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.

How can I grab files from inside a parent directory and all subdirectories inside?

I want to grab all javascript files inside the parent directory and in all sub directories for my discord.js command handler. How do I achieve that?
I have a working block of code that already grabs all .js files from the parent directory, but all sub directories are left alone.
const botConfig = require('./config/nvdconfig.json');
const Discord = require('discord.js');
const fs = require('fs');
const prefix = botConfig.prefix;
// nvdColor: #45c263
const bot = new Discord.Client({
disableEveryone: true
});
bot.commands = new Discord.Collection();
const {
readdirSync,
statSync
} = require('fs');
const {
join
} = require('path');
fs.readdir('./cmds/', (err, files) => {
if (err) console.error(err);
let jsfiles = files.filter(f => f.split('.').pop() === 'js');
if (jsfiles.length <= 0) {
return console.log('No commands to load.');
return;
}
console.log(`Loading ${jsfiles.length} commands!`);
jsfiles.forEach((f, i) => {
let props = require(`./cmds/${f}`);
console.log(`${i + 1}: ${f} loaded!`);
bot.commands.set(props.help.name, props);
});
});
I expect the same result from the loading of the jsfiles through the parent directory as well as all current and future subdirectories.
My current result is all js files are being loaded in but the ones inside the subdirectories are left alone.
I would really appreciate if someone could help me with this! Thank you in advance.
So, I figured out how to get the result that I want.
I found a node package called fs-readdir-recursive that had everything I wanted.
Install the package: npm install fs-readdir-recursive --save
And initialize it. const <var name> = require('fs-readdir-recursive');
Then after you do that, create another variable. const <var name> = read('./<parent directory>/');
This variable will be the parent directory that is searched through with a for each loop.
const <var name> = require('fs-readdir-recursive');
const files = read('./cmds/');
files.forEach(file => {
let cmd = file.replace('.js', '');
let props = require(`./cmds/${cmd}`);
<your code here>
});
This will read each file in each directory of the parent.

Cost of importing in Javascript [duplicate]

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.

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

Categories