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!
Related
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.
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
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'))
})
}
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.
As my title explains I am getting the following error:
{
"errorMessage": "Cannot find module 'index'",
"errorType": "Error",
"stackTrace": [
"Function.Module._resolveFilename (module.js:338:15)",
"Function.Module._load (module.js:280:25)",
"Module.require (module.js:364:17)",
"require (module.js:380:17)"
]
}
I have tried both solutions provided in creating-a-lambda-function-in-aws-from-zip-file and simple-node-js-example-in-aws-lambda
My config currently looks like:
and my file structure is:
and my index.js handler function looks like :
exports.handler = function(event, context) {
What else could be causing this issue aside from what was stated in those two answers above? I have tried both solutions and I have also allocated more memory to the function just incase thats why it couldn't run.
EDIT -
For the sake of trying, I created an even simpler version of my original code and it looked like this:
var Q = require('q');
var AWS = require('aws-sdk');
var validate = require('lambduh-validate');
var Lambda = new AWS.Lambda();
var S3 = new AWS.S3();
theHandler = function (event, context) {
console.log =('nothing');
}
exports.handler = theHandler();
And yet still does not work with the same error?
Try zipping and uploading the contents of the folder lambda-create-timelapse. Not the folder itself.
If this was unclear for anyone else, here are the steps:
Step 1
Navigate to the folder of your project, and open that folder so that you are inside the folder:
Step 2
Select all of the images you want to upload into to Lambda:
Step 3
Right-click and compress the files you have selected:
This will give you a .zip file, which is the file you need to upload to Lambda:
There are a lot of ways to automate this, but this is the manual procedure.
I ran into this problem a few times myself, and this indeed has to do with zipping the folder instead of just the contents like you're supposed to.
For those working from the terminal...
While INSIDE of the directory where the .js files are sitting, run the following:
zip -r ../zipname.zip *
The * is instructing the client to zip all the contents within this folder, ../zipname.zip is telling it to name the file zipname.zip and place it right outside of this current directory.
I had the same problem sometime ago - I reformatted the code.
function lambdafunc1(event, context) {
...
...
...
}
exports.handler = lambdafunc1
The problem occurs when the handler cannot be located in the zip at first level. So anytime you see such error make sure that the file is at the first level in the exploded folder.
To fix this zip the files and not the folder that has the files.
Correct Lambda function declaration can look like this:
var func = function(event, context) {
...
};
exports.handler = func;
You may have other syntax errors that prevent the index.js file from being properly ran. Try running your code locally using another file and using the index.js as your own module.
make sure in your handler following code added
exports.handler = (event, context, callback) => {
...
}
Another reason this can occur is if you don't do an npm install in the folder before packaging and deploying.