Get the number of files in a directory within Gulp.js? - javascript

So far I have tried using the glob-fs package like so:
let cssFileCount;
glob.readdir('public/css/*.css', function (err, files) {
if (err) return console.error(err);
console.log(files);
cssFileCount = (files.length);
});
This works perfectly fine with the path to my JS files public/js/*.js however when I use my public/css/*.css it returns an empty array although the directory has css files in it. When I use the js path it returns an array with a list of files. I then use .length to check the number of files.
Is there any other way I can check the number of files within a directory using Globbing?

An alternative is to simply use the node's standard file system api with a basic filter as such:
const fs = require('fs');
const path = require('path')
fs.readdr('public/css', function(err, files) {
if (err) return console.error(err);
const cssFiles = files.filter(file => path.extname(file).toLowerCase() === '.css'));
console.log(cssFiles);
cssFileCount = (cssFiles.length);
});
You cannot use glob on this approach, but from your problem statement it's not truly needed, as your file filter is quite basic (i.e. extension).

Related

fs writes file in wrong location

Im trying to use writefile, but for some reason it does it outside of ./events folder..
im trying to use fs like,
fs.writeFile("./level.json", JSON.stringify(storage), (err) => {
console.log(err)
})
xp.js is trying to write the level.json in the same folder.
This happens because ./ references the current working directory, so wherever you ran the script from. If you'd like the path to reference the same folder where the currently running js file is, use __dirname instead like so:
fs.writeFile(`${__dirname}/level.json`, JSON.stringify(storage), (err) => {
console.log(err)
})
Source: https://www.geeksforgeeks.org/difference-between-__dirname-and-in-node-js/#:~:text=The%20__dirname%20in%20a,It%20works%20similar%20to%20process.
To be more consistent across different architectures I suggest you to use path module.
So in your case:
fs.writeFile(require('path').resolve('events', 'level.json'), JSON.stringify(storage), (err) => {
console.log(err)
});

Dockerode - custom folder for container

Since yesterday, I have been trying to make a separate folder for each container in the "folder" folder in node.js api using the docker Library called "dockerode". Unfortunately, I did not find any good solution that would work. I looked at the Pterodactyl Daemon (old) source code where they had it, but unfortunately it didn't work for me either. Do you know of any good solutions that could work well?
If you need any more info, I will write it for you here.
Have a nice rest of the day, Domi
Do you just want to create a temporary folder? If so you can just use the fs module:
const fs = require('fs');
exports.createTmpDir = (dir) => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
};
exports.generateRandomString = (length = 15) => {
return Math.random().toString(36).substring(2, length);
};
you can use it like this:
// assume you call it from the root project directory
const root = ${process.cwd()}`;
// create a temp folder path. use this if you want to clean up later.
const tempDir = `${root}/tmp/${generateRandomString()}`;
createTmpDir(tempDir);
You can also use fs to copy or move your dockerfile in to that folder
Not sure if this answers your question or not?

How to execute .js files within a folder based on their name ("number".js)

I've got a folder in my node.js project that contains multiple files, which I'd like to execute via a script. The names of the files are numbers just like '001.js', '002.js' and the script is meant to execute them in that order (from small to big) one after the other (asynchronous).
Unfortunately I can't really figure out a way to get this done the easy way.
Currently I'm importing all files into the script and execute them one after the other but I know that this isn't sustainable and kinda ridiculous...
Is there an easier way to achieve this result via a lean script?
This answer can help https://stackoverflow.com/a/2727191/829300
You can use 'fs' to read all files in a folder then require all.
Once you have got the array of file you can sort it
const fs = require('fs');
const testFolder = './folder/';
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
var x = require(testFolder + file)
console.log(x)
});
});

How to access a group of files, regardless of folder name with fs/require

So I have a group of files organized like this:
./main/folder1/files.js
./main/differentfolder/files.js
./main/test/files.js
./main/test/files.js
The files are NOT named files.js, it's my way of saying that there's a lot of files in that folder.
How do I access all the files shown above without doing something like this:
const commandFiles = fs.readdirSync(`./main/folder1/files.js`)
const commandFiles2 = fs.readdirSync(`./main/differentfolder/files.js`)
const commandFiles3 = fs.readdirSync(`./main/test/files.js`)
//and so on
Just grab all the Javascript files inside "main" regardless of the folder name, both using "fs" and "require". I'd expect it to be the same. There is nothing but folders in ./main.
EDIT: I just want it so fs can check /main//files instead of what's inside of main
I easily solved this problem by using the require-all package which was something installed with the other packages I'm using for my app:
const fs = require('fs');
var folders = fs.readdirSync('./main/').filter(n => n !== '.DS_Store') //filter out that disgusting macOS file
folders.forEach(async (folder) => {
var cmdfolder = Object.values(require('require-all')(__dirname + `/main/${folder}`))
cmdfolder.forEach(async (key) => {
var file = require(`./main/${folder}/${key.fileName}`)'
//register file
})
})

Node.js create folder or use existing

I already have read the documentation of Node.js and, unless if I missed something, it does not tell what the parameters contain in certain operations, in particular fs.mkdir(). As you can see in the documentation, it's not very much.
Currently, I have this code, which tries to create a folder or use an existing one instead:
fs.mkdir(path,function(e){
if(!e || (e && e.code === 'EEXIST')){
//do something with contents
} else {
//debug
console.log(e);
}
});
But I wonder is this the right way to do it? Is checking for the code EEXIST the right way to know that the folder already exists? I know I can do fs.stat() before making the directory, but that would already be two hits to the filesystem.
Secondly, is there a complete or at least a more detailed documentation of Node.js that contains details as to what error objects contain, what parameters signify etc.
Edit: Because this answer is very popular, I have updated it to reflect up-to-date practices.
Node >=10
The new { recursive: true } option of Node's fs now allows this natively. This option mimics the behaviour of UNIX's mkdir -p. It will recursively make sure every part of the path exist, and will not throw an error if any of them do.
(Note: it might still throw errors such as EPERM or EACCESS, so better still wrap it in a try {} catch (e) {} if your implementation is susceptible to it.)
Synchronous version.
fs.mkdirSync(dirpath, { recursive: true })
Async version
await fs.promises.mkdir(dirpath, { recursive: true })
Older Node versions
Using a try {} catch (err) {}, you can achieve this very gracefully without encountering a race condition.
In order to prevent dead time between checking for existence and creating the directory, we simply try to create it straight up, and disregard the error if it is EEXIST (directory already exists).
If the error is not EEXIST, however, we ought to throw an error, because we could be dealing with something like an EPERM or EACCES
function ensureDirSync (dirpath) {
try {
return fs.mkdirSync(dirpath)
} catch (err) {
if (err.code !== 'EEXIST') throw err
}
}
For mkdir -p-like recursive behaviour, e.g. ./a/b/c, you'd have to call it on every part of the dirpath, e.g. ./a, ./a/b, .a/b/c
Good way to do this is to use mkdirp module.
$ npm install mkdirp
Use it to run function that requires the directory. Callback is called after path is created or if path did already exists. Error err is set if mkdirp failed to create directory path.
var mkdirp = require('mkdirp');
mkdirp('/tmp/some/path/foo', function(err) {
// path exists unless there was an error
});
If you want a quick-and-dirty one liner, use this:
fs.existsSync("directory") || fs.mkdirSync("directory");
The node.js docs for fs.mkdir basically defer to the Linux man page for mkdir(2). That indicates that EEXIST will also be indicated if the path exists but isn't a directory which creates an awkward corner case if you go this route.
You may be better off calling fs.stat which will tell you whether the path exists and if it's a directory in a single call. For (what I'm assuming is) the normal case where the directory already exists, it's only a single filesystem hit.
These fs module methods are thin wrappers around the native C APIs so you've got to check the man pages referenced in the node.js docs for the details.
You can use this:
if(!fs.existsSync("directory")){
fs.mkdirSync("directory", 0766, function(err){
if(err){
console.log(err);
// echo the result back
response.send("ERROR! Can't make the directory! \n");
}
});
}
I propose a solution without modules (accumulate modules is never recommended for maintainability especially for small functions that can be written in a few lines...) :
LAST UPDATE :
In v10.12.0, NodeJS impletement recursive options :
// Create recursive folder
fs.mkdir('my/new/folder/create', { recursive: true }, (err) => { if (err) throw err; });
UPDATE :
// Get modules node
const fs = require('fs');
const path = require('path');
// Create
function mkdirpath(dirPath)
{
if(!fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK))
{
try
{
fs.mkdirSync(dirPath);
}
catch(e)
{
mkdirpath(path.dirname(dirPath));
mkdirpath(dirPath);
}
}
}
// Create folder path
mkdirpath('my/new/folder/create');
You can also use fs-extra, which provide a lot frequently used file operations.
Sample Code:
var fs = require('fs-extra')
fs.mkdirs('/tmp/some/long/path/that/prob/doesnt/exist', function (err) {
if (err) return console.error(err)
console.log("success!")
})
fs.mkdirsSync('/tmp/another/path')
docs here: https://github.com/jprichardson/node-fs-extra#mkdirsdir-callback
Here is the ES6 code which I use to create a directory (when it doesn't exist):
const fs = require('fs');
const path = require('path');
function createDirectory(directoryPath) {
const directory = path.normalize(directoryPath);
return new Promise((resolve, reject) => {
fs.stat(directory, (error) => {
if (error) {
if (error.code === 'ENOENT') {
fs.mkdir(directory, (error) => {
if (error) {
reject(error);
} else {
resolve(directory);
}
});
} else {
reject(error);
}
} else {
resolve(directory);
}
});
});
}
const directoryPath = `${__dirname}/test`;
createDirectory(directoryPath).then((path) => {
console.log(`Successfully created directory: '${path}'`);
}).catch((error) => {
console.log(`Problem creating directory: ${error.message}`)
});
Note:
In the beginning of the createDirectory function, I normalize the path to guarantee that the path seperator type of the operating system will be used consistently (e.g. this will turn C:\directory/test into C:\directory\test (when being on Windows)
fs.exists is deprecated, that's why I use fs.stat to check if the directory already exists
If a directory doesn't exist, the error code will be ENOENT (Error NO ENTry)
The directory itself will be created using fs.mkdir
I prefer the asynchronous function fs.mkdir over it's blocking counterpart fs.mkdirSync and because of the wrapping Promise it will be guaranteed that the path of the directory will only be returned after the directory has been successfully created
You'd better not to count the filesystem hits while you code in Javascript, in my opinion.
However, (1) stat & mkdir and (2) mkdir and check(or discard) the error code, both ways are right ways to do what you want.
create dynamic name directory for each user... use this code
***suppose email contain user mail address***
var filessystem = require('fs');
var dir = './public/uploads/'+email;
if (!filessystem.existsSync(dir)){
filessystem.mkdirSync(dir);
}else
{
console.log("Directory already exist");
}
Just as a newer alternative to Teemu Ikonen's answer, which is very simple and easily readable, is to use the ensureDir method of the fs-extra package.
It can not only be used as a blatant replacement for the built in fs module, but also has a lot of other functionalities in addition to the functionalities of the fs package.
The ensureDir method, as the name suggests, ensures that the directory exists. If the directory structure does not exist, it is created. Like mkdir -p. Not just the end folder, instead the entire path is created if not existing already.
the one provided above is the async version of it. It also has a synchronous method to perform this in the form of the ensureDirSync method.
You can do all of this with the File System module.
const
fs = require('fs'),
dirPath = `path/to/dir`
// Check if directory exists.
fs.access(dirPath, fs.constants.F_OK, (err)=>{
if (err){
// Create directory if directory does not exist.
fs.mkdir(dirPath, {recursive:true}, (err)=>{
if (err) console.log(`Error creating directory: ${err}`)
else console.log('Directory created successfully.')
})
}
// Directory now exists.
})
You really don't even need to check if the directory exists. The following code also guarantees that the directory either already exists or is created.
const
fs = require('fs'),
dirPath = `path/to/dir`
// Create directory if directory does not exist.
fs.mkdir(dirPath, {recursive:true}, (err)=>{
if (err) console.log(`Error creating directory: ${err}`)
// Directory now exists.
})
#Liberateur's answer above did not work for me (Node v8.10.0).
Little modification did the trick but I am not sure if this is a right way. Please suggest.
// Get modules node
const fs = require('fs');
const path = require('path');
// Create
function mkdirpath(dirPath)
{
try {
fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);
}
catch(err) {
try
{
fs.mkdirSync(dirPath);
}
catch(e)
{
mkdirpath(path.dirname(dirPath));
mkdirpath(dirPath);
}
}
}
// Create folder path
mkdirpath('my/new/folder/create');
const fs = require('fs');
const folderName = '/Users/joe/test';
try {
if (!fs.existsSync(folderName)) {
fs.mkdirSync(folderName);
}
} catch (err) {
console.error(err);
}
For documentation and more examples, please see here https://nodejs.dev/learn/working-with-folders-in-nodejs
Raugaral's answer but with -p functionality. Ugly, but it works:
function mkdirp(dir) {
let dirs = dir.split(/\\/).filter(asdf => !asdf.match(/^\s*$/))
let fullpath = ''
// Production directory will begin \\, test is on my local drive.
if (dirs[0].match(/C:/i)) {
fullpath = dirs[0] + '\\'
}
else {
fullpath = '\\\\' + dirs[0] + '\\'
}
// Start from root directory + 1, build out one level at a time.
dirs.slice(1).map(asdf => {
fullpath += asdf + '\\'
if (!fs.existsSync(fullpath)) {
fs.mkdirSync(fullpath)
}
})
}//mkdirp

Categories

Resources