NodeJs: fs.unlink does not delete file [VS] - javascript

I am aware this isn't the first post about fs.unlink not working, but I'm very new to both Visual Studio and Node Js.
I want to delete a file in the working folder, I got an error and the file is not deleted.
Here is what I tried:
var fs = require('fs');
fs.unlink('test1.txt');
PS: I installed the necessary Node Js components in VS.

As far as the code goes, you're not invoking fs.unlink properly. For starters, it's asynchronous. You will need to provide it a callback. See example here:
https://nodejs.org/api/fs.html#fs_fs_unlink_path_callback
Secondly, you need to provide it the full file path, not just the name of the file... ie:
var fs = require('fs');
fs.unlink('C:\path\to\my\file\test1.txt', (err) => {});
You can also supply it with the variable __dirname to utilize your current working directory from wherever you invoke node against the script. Thus, that would look something like:
let fs = require('fs');
let path = require('path');
fs.unlink(path.join(__dirname, 'test1.txt', (err) => {
if (err) throw err;
console.log('test1.txt was deleted');
});
Currently, you can also invoke it synchronously using it's single parameter signature... thus you'd provide only the dir path:
fs.unlinkSync('C:\\path\\to\\my\\file\\test1.txt');
But, this is ill-advised as it will be blocking. I'd only use the "sync" variant during some application bootstrapping process, where it'd be invoked only one time or so, at startup. Try to fight the urge of it being "easier" to use and understand, and instead get yourself to understand asynchronous logic.

Related

How to read a symlink in Node.js

I want to read a symlink, and get the details of the link itself, not the contents of the linked file. How do I do that in Node, in a cross-platform way?
I can detect symlinks easily using lstat, no problem. Once I know the path of the file, and that it is a symlink though, how can I read it? fs.readFile always reads the target file, or throws an error for reading a directory for links to directories.
There is a fs.constants.O_SYMLINK constant, which in theory solves this on OSX, but it seems to be undefined on both Ubuntu & Windows 10.
If you have determined that the file is a symlink try this:
fs.readlink("./mysimlink", function (err, linkString) {
// .. do some error handling here ..
console.log(linkString)
});
Confirmed as working on Linux.
You could then use fs.realpath() to turn it into a full path. Be aware though that linkString can be just a filename or relative path as well as a fully qualified path so you may have to get fs.realpath() for the symlink, determine its directory part and prefix it to linkString before using fs.realpath() on it.
I've just faced the same issue: sometimes fs.readlink returns a relative path, sometimes it returns an absolute path.
(proper error handling not implemented to keep things simple)
const fs = require('fs');
const pathPckg = require('path');
async function getTarLinkOfSymLink(path){
return new Promise((resolve, reject)=>{
fs.readlink(path, (err, tarPath)=>{
if(err){
console.log(err.message);
return resolve('');
}
const baseSrcPath = pathPckg.dirname(path);
return resolve( pathPckg.resolve(baseSrcPath, tarPath) );
});
});
}
// usage:
const path = '/example/symbolic/link/path';
const tarPath = await getTarLinkOfSymLink(path);
The code works if the symbolic link is either a file or a directory/folder - tested on Linux

Execute a JS file (with logs, etc...) inside another NodeJS process

Here is my problem, I want to create a CLI that automatically runs a test. Without the CLI, I'm able to run everything perfectly with the node command:
node test.js
Basically, I want to do the exact same thing as the command before, so I googled for a technique that does this. I found this:
#!/usr/bin/env node
'use strict';
const options = process.argv;
const { execFile } = require('child_process');
const child = execFile('node', ['../dist/test.js'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
This method doesn't work for me because, in the test.js file, I'm using the ora package. And because this package is making real-time animations, it doesn't come in stdout.
Is there any way of executing in real time (without subprocess) my test.js using Node? I'm open to other methods, but I want to publish the CLI on NPM, so keep in mind that it has to be in JavaScript 😊.
You can find every file that I've talked here on GitHub. Normally, you wouldn't need this link, but I'm giving it to you if you need to have a closer look.
You should simply call your test() function from your CLI code, after requiring the module that defines it. Have a look at mocha and jasmine: you will see that while both tools provide a CLI, they also provide instructions for invoking the test frameworks from arbitrary JS code.
I can't think of a way without a sub-process. but this may help.
The child process exec will not work with the continuous output commands as it buffers the output the process will halt when that buffer is full.
The suitable solution is spwan :
var spwan = require('child_process').spwan
var child = spwan('node', ['../dist/test.js'])
child.stdout.on('data', function(data) {
console.log(data)
})
child.stderr.on('data', function(data) {
console.log(data)
})
Here is my solution, you can use the fs library to get the code of the file, and then, you simply use eval to execute in the same process.
const fs = require("fs");
function run(file) {
fs.readFile(file, (err, data) => {
eval(data.toString('utf8'))
})
}

Searching files in dir with Node.js

I'm currently trying to search for a few files in a specific folder on Windows using node and grunt.
I have a grunt task that has a function to read a dir with JSON files, but the problem is that when I run the task, the code to read the file doesn't do anything, everything else on that grunt task runs perfect, but that. I'm not sure if the reference for the path is correct, but I'm also using path.normalize() and it does not throws any error.
This is snippet of the code:
..// Some other code
var fs = require('fs'),
path = require("path");
grunt.registerTask('separate', function() {
var filePath = path.normalize("C:\Users\jbernhardt\Desktop\testkeeper\jenkinsReports");
fs.readdir(filePath, function(err, filenames) {
//This log doesn't show as it the function is not running
grunt.log.writeln("Testing");
if (err) {
grunt.log.writeln("Error");
return;
}
filenames.forEach(function(filename){
grunt.log.writeln("Testing");
});
});
...//Some more code below for the same task
}
Does anyone has an idea why this snippet of the code is being skipped when I run the task? I could probably be missing some basic stuffs. Thanks!
Try readdirSync and check if your function still not working. I guess your process is finished before the callback.
You can simply use the __dirname object to get the path where the current script is running:
..// Some other code
var fs = require('fs'),
path = require("path");
grunt.registerTask('separate', function() {
fs.readdir(__dirname, function(err, filenames) {
//This log doesn't show as it the function is not running
grunt.log.writeln("Testing");
if (err) {
grunt.log.writeln("Error");
return;
}
filenames.forEach(function(filename){
grunt.log.writeln("Testing");
});
});
...//Some more code below for the same task
}
You can find more info here.
you need change your path
var filePath = path.normalize("C:\\Users\\jbernhardt\\Desktop\\testkeeper\\jenkinsReports");
Also To achieve consistent results when working with Windows file paths on any operating system, use path.win32:
path.win32.basename('C:\\Users\\jbernhardt\\Desktop\\testkeeper\\jenkinsReports"');
You can read about https://nodejs.org/api/path.html#path_windows_vs_posix
The slash in path are being escaped.
"C:\\Users\\jbernhardt\\Desktop\\testkeeper\\jenkinsReports"
should solve your issue.

Check if file exist in Gulp

I need to check if a file exists in a gulp task, i know i can use some node functions from node, there are two:
fs.exists() and fs.existsSync()
The problem is that in the node documentation, is saying that these functions will be deprecated
You can use fs.access
fs.access('/etc/passwd', (err) => {
if (err) {
// file/path is not visible to the calling process
console.log(err.message);
console.log(err.code);
}
});
List of available error codes here
Using fs.access() to check for the accessibility of a file before calling fs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file is not accessible.
You could add
var f;
try {
var f = require('your-file');
} catch (error) {
// ....
}
if (f) {
console.log(f);
}
As of 2018, you can use fs.existsSync():
fs.exists() is deprecated, but fs.existsSync() is not. The callback parameter to fs.exists() accepts parameters that are inconsistent with other Node.js callbacks. fs.existsSync() does not use a callback.
See this answer for more details.
I believe fs-access package has been depreciated alternatively you may want to use:
path-exists.
file-exists.
Intracutions (path-exists):
npm install path-exists --save
const myFile = '/my_file_to_ceck.html';
const exists = pathExists.sync(myFile);
console.log(exists);
Intracutions (file-exists):
npm install file-exists --save
const fileExists = require('file-exists');
const myFile = '/my_file_to_ceck.html';
fileExists(myFile, (err, exists) => console.log(exists))
NPM Link: path exists
NPM Link: file exists
The node documentatión does not recommend using stat to check wether a file exists:
Using fs.stat() to check for the existence of a file before calling fs.open(), fs.readFile() or fs.writeFile() is not recommended.
Instead, user code should open/read/write the file directly and handle
the error raised if the file is not available.
To check if a file exists without manipulating it afterwards,
fs.access() is recommended.
If you don't need to read or write the file you should use fs.access, the simple and asynchronous way is:
try {
fs.accessSync(path)
// the file exists
}catch(e){
// the file doesn't exists
}

NodeJS vm.runInThisContext() and lack of __filename

Whenever I run vm.runInThisContext(code, filename), the code I ran reports __filename and __dirname as undefined.
This also leads to the situation that any fs.readFile and such calls will not work with relative paths. Actually to be exact, file system functions do not work at all even if I feed them a hard-coded absolute path to an existing file.
For example, this will do nothing:
var fs = require('fs');
fs.readFile('/home/test/file.txt', function(e, data) {
if (e) {throw e;}
console.log('here i am');
});
What happens is that nothing happens. If I run the code in normal NodeJS code then it outputs "here i am", but if I run that code through the vm module, then nothing happens. The callback is simply never called, because for some reason it can't locate the file and there does not seem to be any timeouts either.
How can I make Node to understand that the executed code is some "file" and also make the fs module functions to work? I tried specifying the second parameter to vm.runInThisContext(code, filename), but I see no difference. It almost looks that Node doesn't care about the second parameter.
I'm not exactly sure how I even got my code examples to work before, because right now they do not work at all.
I found out that you can use vm.runInNewContext(code, sandbox, filename) and then specify require, __filename and whatever you need in the sandbox:
// Place here some path to test it. I'm using Cygwin...
var filename = '/cygdrive/z/www/project/src/bootstrap.js';
var code = "var fs = require('fs'); fs.readFile('./path/to/some/file.js', function(e, data) {if (e) {throw e;} console.log(data.toString());});";
var vm = require('vm');
vm.runInNewContext(code, {
require: require,
console: console,
__filename: filename
}, filename);
Then if I run node bootstrap.js --debug it works fine!

Categories