Node.js - res.sendFile - Error: ENOENT, stat - Even though path is correct - node.js

Here's my folder structure :
Root Folder
...
...
...
app.js
escape_iframe.html
...
from within app.js I'm doing :
res.sendFile('escape_iframe.html' , {root : __dirname});
and the error I'm getting is :
Error: ENOENT, stat '/app/escape_iframe.html'
which I guess is a horrible way of saying that the file can't be found in the path provided ?
Anyway, as you can tell I simply want to serve a file that is a sibling of app.js (which is the file form which the res.sendFile(... call is being made)
I also tried : res.sendFile('escape_iframe.html'); and I got : path must be absolute or specify root to res.sendFile
What am I doing wrong ?

Paths specified with a . are relative to the current working directory, not relative to the script file. So the file might be found if you run node app.js but not if you run node folder/app.js.
To make a path relative to the script, you must use the __dirname variable.
res.sendFile(__dirname + '/path/to/escape_iframe.html');

Path specified with . are relative to the path and any number of forward slashes are truncated as single slash. You might get this error when the process node filename.js is not able to locate the filename.
https://nodejs.org/api/errors.html#errors_enoent_no_such_file_or_directory
My suggestion would be ::
var path = require('path')
//process.cwd() returns the current directory of the project
res.sendFile(process.cwd(),'/path/to/escape_iframe.html');

Related

Determining the path in fs.readFile()

var fs = require('fs');
var obj = JSON.parse(fs.readFileSync('./config.json', 'utf8'));
This is the code for my app (index.js) . It uses a file named config.json using a relative path ./config.json. When I compile this into my mac using $pkg index.js, I obtain a test-macos file that is my app. Both the app and the config.json file are located in the same folder named project (this is why I can use the relative path ./config.json). However, once runnning the app I run into an error:
/Users/amelie/Documents/project/test-macos ;
exit; internal/fs/utils.js:312
throw err;
^ Error: ENOENT: no such file or directory, open './config.json'.
Therefore it seems that my app cannot find the config.json file. I could determine an absolute path but I need these two files to always be together because I need the path in the variable
var obj = JSON.parse(fs.readFileSync('./config.json', 'utf8'));
to be always the same since I share those files to other people and the absolute path would therefore change. Is there a way to do this ?

Why does require() not require an absolute path but an express.static() does?

I am trying to run my index.js script from outside the project directory. My project structure is as follows:
app
- config
- config.js
- public
- index.html
- src
- index.js
Now when I run my src/index.js from outside my app folder, require() is able to resolve the relative paths
const config = require(`../config/config`);
On the other hand express.static is not able to resolve such relative paths.
e.g. app.use(express.static("../public"));
Why do I need to use path.join and get the absolute path?
require() works off __dirname which is independent of what the current directory was when your app was loaded. It's always the directory where the module is located in, so it is consistent.
express.static() when used with relative paths uses the directory that the main app was launched form, so if you use relative paths, its behavior varies depending upon how you launch the app.
From the express doc for serving static files:
However, the path that you provide to the express.static function is
relative to the directory from where you launch your node process. If
you run the express app from another directory, it’s safer to use the
absolute path of the directory that you want to serve
So, if you want the directory to be module relative, you have to manually combine your path with __dirname to make a full path, as you have discovered.

Nodejs difference between ./folderpath vs ../folderpath

I'm new in nodejs. I try to use some file in my filesystem. I would like to get them through some realtive path. Here is the structure:
-app
-resources
-tmp
-file1
-file2
-common
-common.js
-etc
So, I would like to reach the file1 and file2 in my resources/tmp folder from the common.js file in int common folder. I used two relative path methodic:
// First , wrong one
var tmpfolder = '../resources/tmp';
// Second, good one
var tmpfolder = './resources/tmp';
The file absolute path is something like this:
C:\Users\xy\Documents\work\nodejs\projects\project_wrapper_folder\project_folder\resources\tmp
If I log the first relative path I got this result:
C:\Users\xy\Documents\work\nodejs\projects\project_folder\resources\tmp
which is wrong, because it does not contains the wrapper folder.
But the second works fine.
Can somebody explain me this behaviour?
UPDATE
I see the meaning if '../', thanks your explanations!
I have tried #Lissy answer: "So baring that in mind ./ will resolve to the value of your project root..." that sounds great, but the result is not.
I have this logic in my app:
var tmpfolder = require('./otherFolder/orhetFile');
where otherFolder is the subfolder of my project_folder. So, when I used this here, I got an error called Cannot find module ...
But if I use this './' in fs module, here: /project_folder/otherFolder_2/otherFile_2 like:
var path = `./resources/tmp`;
fs.mkdirsSync(path);
It works!
these is strange for me. If './' means the current folder, than the example above sould not work (but it's works).
But if the './' means path of the project root, the example with require should work (but does not work).
Strange for me, is there some meaning of require or fs??
In Summary
./my-file means look at the root, whereas ../my-file, means come out of the current directory, and look in the parent folder.
Explanation of Relative and Absolute Paths in Node.js
The default document root is set with the NODE_PATH environment variable (however it would be terrible practice to modify that). So baring that in mind ./ will resolve to the value of your project root.
And so let tmpfolder = require('./resources/tmp'); would resolve to
C:\Users\......\project_wrapper_folder\project_folder\resources\tmp as you have seen
A relative path is denoted by not starting with ./, so for example let tmpfolder = require('my-scripts/some-script'); would look in the current directory for another folder called my-scripts.
Following on from that ../ is relative to the current directory, but goes out one (to it's parent) and looks from there. You can go out two directories by doing ../../my-dir and so on (this is not great practice though, as it can get hard to manage if you have ../../../../../../)
Better method
You can use the __dirname constant in Node to locate the directory name of the current module.
e.g.
fs.readFile(__dirname + '/../foo.bar');
Useful Links
I think you'll find this article on Better local require() paths for Node.js very useful.
Also, for a bit of further reading, here is the official Node.js documentation on paths
The .. means the previous dir. So you are getting out from project_wrapper_folder and then add to the script dir resources\tmp and that way the project_wrapper_folder is no longer in the relative path.
Lets assume you are inside a folder called app.
when you use ../resources/tmp, it will come out of the app folder and will search for tmp inside resources folder.
when you use ./resources/tmp, it will look within the app folder for resources folder and tmp inside it.
../ points to the parent directory while ./ points to current working directory.
A dot basically means "go one folder back in the path"
So:
'./' points at the folder you are in.(in your case the folder common/)
'../' points at the folder that contains the folder you are in. (in your case the folder app/)

path.dirname on Windows path is giving `.`

I in electron am doing:
path.dirname('C:\\Users\\Blagoh\\Documents\\GitHub\\Screeenshoter\\dist\\electron\\main')
That path is the actual value of my __dirname. How come it is not giving me C:\\Users\\Blagoh\\Documents\\GitHub\\Screeenshoter\\dist\\electron? I want that main part chopped off.
Assuming main is a directory inside electron. Also assuming that you have some file called index.js inside main folder where you want to have the path of electron directory.
So, you can do path.join this way:
var mainFolderParentPath = path.join(__dirname, '../');
Your original file location:
C:\\Users\\Blagoh\\Documents\\GitHub\\Screeenshoter\\dist\\electron\\main\\index.js
__dirname will return
C:\\Users\\Blagoh\\Documents\\GitHub\\Screeenshoter\\dist\\electron\\main
and then inside path.join '../', will chop off the main folder from path. So, you will be left off with:
C:\\Users\\Blagoh\\Documents\\GitHub\\Screeenshoter\\dist\\electron
Well you obviously didn't read the docs for dirname. It states that it works like the Unix command dirname which "strips non-directory suffix from file name", thus you get the C:\\Users\\Blagoh\\Documents\\GitHub\\Screeenshoter\\dist\\electron.
What you are looking for is basename.
path.basename('C:\\Users\\Blagoh\\Documents\\GitHub\\Screeenshoter\\dist\\electron\\main') will give you main.

Making the file location insensitive to where the node command is being run from?

The script src/main/js/script.js loads a file with a relative location of ../json/file.json If I run node src/main/js/script.js then I get an error saying that the ../json/file.json cannot be resolved, however if I cd into the directory src/main/js and run node script.js from there, there's not problem. How can script.js be written such that it does not matter where the script is being run from. In other words how do I specify that the file.json file is located relative to the location of the script.js file?
var location = path.join(__dirname, '../json/file.json');
require('fs').createReadStream(location)
Originally it was:
require('fs').createReadStream('../json/file.json');

Resources