creating multi sub directories in nodejs - node.js

I want to check if a directory not exist in my project, make two directories in my nodejs web api project. I use the following code and it works.
const myVar= req.body["specificId"];
const checkPath = path.join(__dirname , "../public/media/" + myVar);
console.log(checkPath);
if (!fs.existsSync(checkPath)) {
console.log("not exist!");
fs.mkdirSync(`${__dirname}../../public/media/`);
fs.mkdirSync(`${__dirname}../../public/media/${myVar}`);
fs.mkdirSync(`${__dirname}../../public/media/${myVar}/image`);
fs.mkdirSync(`${__dirname}../../public/media/${myVar}/video`);
}
else{
console.log("exist!");
}
but as you see I write 4 lines to do so. How may do it just by using something like the two last lines? I should mention that for the first run, just the specified 'public' folder exists and the other sub folders should be created if ${myVar} folder not existed.

Related

NodeJS/fs.readdir - Ignore certain subdirectories when scanning for a specific set of subdirectories (closed)

Say we have a working directory containing subdirectories like so:
<workDir>
|— UselessFolder
|— NotThisFolder
|— SkipThisFolder
|— UsefulFolder
|— UsefulFolder2
|— UsefulFolder3
Is there a way that I can ignore the UselessFolder, NotThisFolder & SkipThisFolder subdirectories while scanning the working directory with fs.readdir?
The goal of the function that requires this, is to find the very last instance of the UsefulFolder subdirectories and do work with them later on. The function works fine most of the time, but it breaks in some cases due to the subfolders that I want to ignore that were stated above, I know this because if I completely remove the subfolders I want my function to ignore, the function will work fine, but in my case I can't delete any of the subdirectories within the working directory, so the only option is to ignore the ones I don't care about.
The code I'm currently using in my function to read the working directory and list its subdirectories is the following:
var workDir = '/home/user/workDir';
fs.readdir(workDir, { withFileTypes: true }, (error, files) => {
if (error) {
console.log('An error occured while reading the working directory! \n\n')
console.log('Reason: ' + error);
return;
} else {
var folderList = files
.filter((item) => item.isDirectory())
.map((item) => item.name);
console.log(folderList);
};
});
I'm not aware of a way to ask readdir itself to give you a filtered list. You will need to filter them yourself, something like this:
let unwantedDirs = ['foo', 'bar'];
var folderList = files
.filter((item) =>
item.isDirectory() &&
!(unwantedDirs.includes(item.name)))

How to delete all files and subdirectories in a directory with Node.js

I am working with node.js and need to empty a folder. I read a lot of deleting files or folders. But I didn't find answers, how to delete all files AND folders in my folder Test, without deleting my folder Test` itself.
I try to find a solution with fs or extra-fs. Happy for some help!
EDIT 1: Hey #Harald, you should use the del library that #ziishaned posted above. Because it's much more clean and scalable. And use my answer to learn how it works under the hood :)
EDIT: 2 (Dec 26 2021): I didn't know that there is a fs method named fs.rm that you can use to accomplish the task with just one line of code.
fs.rm(path_to_delete, { recursive: true }, callback)
// or use the synchronous version
fs.rmSync(path_to_delete, { recursive: true })
The above code is analogous to the linux shell command: rm -r path_to_delete.
We use fs.unlink and fs.rmdir to remove files and empty directories respectively. To check if a path represents a directory we can use fs.stat().
So we've to list all the contents in your test directory and remove them one by one.
By the way, I'll be using the synchronous version of fs methods mentioned above (e.g., fs.readdirSync instead of fs.readdir) to make my code simple. But if you're writing a production application then you should use asynchronous version of all the fs methods. I leave it up to you to read the docs here Node.js v14.18.1 File System documentation.
const fs = require("fs");
const path = require("path");
const DIR_TO_CLEAR = "./trash";
emptyDir(DIR_TO_CLEAR);
function emptyDir(dirPath) {
const dirContents = fs.readdirSync(dirPath); // List dir content
for (const fileOrDirPath of dirContents) {
try {
// Get Full path
const fullPath = path.join(dirPath, fileOrDirPath);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
// It's a sub directory
if (fs.readdirSync(fullPath).length) emptyDir(fullPath);
// If the dir is not empty then remove it's contents too(recursively)
fs.rmdirSync(fullPath);
} else fs.unlinkSync(fullPath); // It's a file
} catch (ex) {
console.error(ex.message);
}
}
}
Feel free to ask me if you don't understand anything in the code above :)
You can use del package to delete files and folder within a directory recursively without deleting the parent directory:
Install the required dependency:
npm install del
Use below code to delete subdirectories or files within Test directory without deleting Test directory itself:
const del = require("del");
del.sync(['Test/**', '!Test']);

Should I hard code references to my node_modules folder?

I'm creating an npm package called ctgen and I need to reference a folder within that package. Should I hard code the reference to that folder?
e.g. src = './node_modules/ctgen/scaffold'
or is there a pre-made function that will do this for me?
For a bit more clarity on my issue. I have the following function in my package:
var createFile = function (fileName, componentName, doc) {
// Tell the user what is happening
console.log(chalk.blue('\nCreating', fileName, '...'))
// Bring in the scaffold files (note this should point to the scaffold folder in node modules/ctgen)
var scaffold = './scaffold/' + fileName
fs.readFile(scaffold, 'utf8', function (err, data) {
if (err) return console.log(chalk.red(err))
var result = data.replace(/%cname%/g, componentName)
if (doc) {
var d = new Date()
result = result.replace(/%cfname%/g, doc.componentName)
result = result.replace(/%cdesc%/g, doc.componentDesc)
result = result.replace(/%cauthor%/g, doc.userName)
result = result.replace(/%cagithub%/g, doc.userGithub)
result = result.replace(/%creationdate%/g, d.getDate() + '/' + d.getMonth() + '/' + d.getFullYear())
}
fs.writeFile('./src/components/' + componentName + '/' + fileName, result, function (err) {
if (err) return console.log(chalk.red(err))
console.log(chalk.green(fileName, 'created!'))
})
})
}
It looks in a folder called scaffold for the following files:
view.php
style.styl
component.json
It then pulls the file into a cache, performs a find and replace on some strings and then writes the output to a file in the users project.
It seems though that whenever I try to reference the 'scaffold' folder, it's trying to find it in the users project folder and not in my package folder.
I'm very hesitant to reference the scaffold folder by writing '/node_modules/ctgen/scaffold' as that seems like the wrong thing to do to me.
What you want is __dirname.
If I understand your question, you have a ressource folder contained in your module, and have trouble accessing it since the current path is the path of the app, not your module.
__dirname will contain the path of your script file, and so will point to your module file.
I presume your module is named ctgen, and the files you want to access are in ctgen/scaffold. So in your code, try to access __dirname/scaffold.
In short NO. If you want to read more about how node looks for required files pleas read this: https://nodejs.org/dist/latest-v7.x/docs/api/modules.html#modules_addenda_package_manager_tips
if you are creating an npm package, specify your dependent npm modules within your package.json and use them as intended in node (with require('your-dependent-module-name')). After you published your module and someone npm install --save your-module, it will also install your dependencies into [usrDir]/node_modules/[your-module]/node_modules, where your module will find what it needs.
That beeing said; yes, you could reference __dirname + 'node_modules/[something] but that wouldn't be smart as it makes assumptions how the user is using your module. At the same time, node+npm solves this problem for you, so there is no reason for you to want to do this)

How to create folder hierarchy of year -> month -> date if not exist in node.js

I am trying to create folder hierarchy named current year inside create another folder with name current month and then again inside that folder create another folder with name current date.
For example : Today's date is 2016-05-02, So the folder should be create if not already exist like following structure
2016->05->02
See this previously answered question
Good way to do this is to use mkdirp module.
$ npm install mkdirp
Then use it to run function that requires the directory. Callback is called after path is created (if it didn't already exists). Error is set if mkdirp failed to create directory path.
var mkdirp = require('mkdirp');
mkdirp('/tmp/some/path/foo', function(err) {
// path was created unless there was error
});
The best solution would be to use the npm module called node-fs-extra. The main advantage is that its built on top of the module fs, so you can have all the methods available in fs as well. It has a method called mkdir which creates the directory you mentioned. If you give a long directory path, it will create the parent folders automatically. The module is a super set of npm module fs, so you can use all the functions in fs also if you add this module.
one example
var fse = require('fs-extra')
var os = require('os')
function getTempPath() {
return os.tmpdir();
}
mymodule.get('/makefolder',function(req,res){
var tempfolder = getTempPath();
var myfolder = tempfolder + '/yearfolder/monthfolder/datefolder/anyotherfolder';
fse.mkdirs(myfolder, function (err) {
if (err) return res.json(err)
console.log("success!")
res.json("Hurray ! Folder created ! Now, Upvote the solution :) ");
})
});

node.js mkdir enonent when passed a string

I'm trying to build folders with a string, but I keep erroring out, everything looks good, but I'm obviously missing something, any help would be great.
var setFile = 'dijit/analysis/images/'
folders = setFile.substr(0,setFile.lastIndexOf('/'));
fs.mkdir(folders, function(err){
console.log('problem: ' + err);
});
Error: Error: ENOENT, mkdir 'dijit/analysis/images'
Thanks,
fs.mkdir can able to built only a single folder. You are trying to create a folder inside a non existing folder. This problem can be solved by fs-extra module of npm. Following code should fulfill your need.
var setFile = 'dijit/analysis/images/',
fsExtra = require('fs-extra'),
folders = setFile.substr(0, setFile.lastIndexOf('/'));
fsExtra.mkdirp(folders, function(err) {
console.log('problem: ' + err);
});
Kundu's comment answers this problem, but if you want a different solution there is plenty over at How to create full path with node's fs.mkdirSync?

Resources