Traverse '__dirname' in Node.js Application - javascript

I'm trying to get the parent of the current __dirname in my node application.
Here is my current line of code:
mu.root = __dirname + '/theme';
Yet, I want to reach out of the current directory and into another one of it's sibilings.
Here is my directory structure:
lib
this_file.js
theme
theme_file.file
How would I go about doing this without having to parse the result of __dirname?

You could use ../ to traverse to the parent of the current directory and path.join to resolve the path:
var path = require('path');
...
path.join(__dirname, "../whiceverdirectoryname");

Use path.dirname(__dirname)
Here's the doc.

Related

node.js can't find module from relative path

I have two simple files in node.js and want to export two classes from one file and import them in the other. I'm using:
module.exports = {TrigInter, Hilbert};
Now, if I call require, it only works with the absolute file path:
const lib = require("/Users/username/documents/atom/project_folder/lib.js");
and not with the relative file path:
const lib = require("./lib.js");
eventhough the two files are both located in the "project_folder". I'm pretty sure, I tried the exact same thing before and it worked with the relative path. I don't see what I'm doing wrong. What am I missing?
Absolute path is not best practice to use, instead you can use path join method like
const path = require('path');
let your_file_path = path.resolve(__dirname, '/lib.js');
https://www.digitalocean.com/community/tutorials/nodejs-how-to-use__dirname

Why Node.js only recognizes absolute paths? [duplicate]

This question already has answers here:
What is the difference between __dirname and ./ in node.js?
(2 answers)
Closed 3 years ago.
I created a file called nodes, then initialized the file with npm init and the main js file is called main.js. I also created index.html and index.css in the file, after that I want to use Node.js Render this index.html, so I wrote in main.js:
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 9000;
const mainHTML = './index.html';
const server = http.createServer((req, res) => {
fs.stat(`./${mainHTML}`, (err, stats) => {
if(stats) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
fs.createReadStream(mainHTML).pipe(res);
}
});
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
I opened the server with the node desktop/nodes command, but node.js could not find the file.
Until I changed the relative path to an absolute path, Node.js will recognize it:
const mainHTML = 'desktop/nodes/index.html';
Why is this? If I want to use a relative path, how do I do it?
When you access a file in node.js with a relative path, the file is accessed relative to the value of the current working directory for the process. Note, in the modular world of node.js, the current working directory may or may not be the same as the directory where your module was located. And, your code can change the current working directory to be whatever you want it to be.
It is common in modular node.js code to have a programming desire to access things relative to the directory where the current module's code was loaded from. This gives you the ability to use relative paths so the app/module can work anywhere, but it gives you certainty that you'll get the files you want. To do this, one typically uses the module-specific variable __dirname. This is the directory that the current module was loaded from. If it's the main script that node.js was started with then, it's the directory of that script.
So, to get a file from the same directory as the script you are current in, you would do this:
const mainHTML = 'index.html';
fs.createReadStream(path.join(__dirname, mainHTML)).pipe(res);
To access a file in a subdirectory public below where the script is, you could do this:
const mainHTML = 'public/index.html';
fs.createReadStream(path.join(__dirname, mainHTML)).pipe(res);
To access a file in a different subdirectory at the same level (common parent directory) as where the script is, you could do this:
const mainHTML = '../public/index.html';
fs.createReadStream(path.join(__dirname, mainHTML)).pipe(res);
All of these use paths that are relative to where the script itself is located and do not depend upon how the module/script was loaded or what the current working directory of the app is.
You are creating http server, which creates it's path as base, so it understands only paths taking that base path as relative path. If you want to use relative path, then you need to resolve that path.
You can use 'path' library.
const path = require('path')
// To resolve parent path
path.resolve('..', __dirname__)

What is the rule for express.static root path?

I ran
node src/app.js
in the mean-to directory
express.static('public')
would work,why?
don't need to specify the path?
what's the rule?
and I know
__dirname+'/../public'`
works just fine.
Just want to make sure the the logic here
I look up the doc
http://expressjs.com/en/starter/static-files.html
it says
"Pass the name of the directory that contains the static assets to the express.static middleware function to start serving the files directly. "
"the path that you provide to the express.static function is relative to the directory from where you launch your node process"
Does that mean
if I run node src/app.js in mean-to folder --> use express.static('public')
if I run node app.js in src folder => use express.static('../public')
and for safety, better use __dirname to get the absolute path of the directory
Express static uses resolve function from module path
Example using path:
var p = require('path');
p.resolve('public'); // will return your absolute path for `public` directory
So rules for express static the same as for path#resolve function
You can see more example in the docs for path module
What's the difference between p.resolve and __dirname?
path#resolve
p.resolve() resolves to an absolute path
path.resolve('public');
Will return your absolute path for public' directory(e.g "C:\projects\myapp\public")
path.resolve('src'); // => "C:\projects\myapp\src")
__dirname
__dirname - name of the directory(absolute path) from which you're currently running your app
file app.js
console.log(__dirname);
Running node app.js will print your absolute path for your app, e.g "C:\projects\myapp"
You mixed 2 lines in one... And both are necessary:
//This line is to say that the statics files are in public
app.use(express.static(__dirname + "/public"));
//This another line is to say that when call the route "/" render a page
app.get("/", function (req, res) {
res.send('Hello World!');
}
Probably, the reason is in running it from directory highter one level than dir with code? Try run it from src:
cd src
node app.js

How to go back 1 folder level with __dirname?

I am using gulp-karma and facing a simple problem but cannot seems to find what i am doing wrong .
gulp.task('test', function (done) {
karma.start({
configFile: __dirname + '..\\test\\' +'\karma.conf.js',
singleRun: true
}, done);
});
Here is the code i am using and i cannot seems to go 1 level back in the folder directory . When i do the above it just append the ..\ to the folder direcotry without going 1 level back (which is the usual use of ..\). Following is the folder structure .
parent|
test|karma.conf.js
webapirole|gulpfile.js
and my folder is inside the webapirole folder . i want to go back 1 folder back and go inisde the test folder which contains the karma.conf.js file. can anyone make me understand what i am doing wrong here ?
error i am getting
[18:06:32] Starting 'tdd'...
ERROR [config]: File C:\Users\Documents\WebApiRole..\test\karma.conf.js does not exist
TL;DR
Use path.join(__dirname, '..', 'test', 'karma.conf.js'). Prevent use of slashes.
Long Answer
As a lot of answers have pointed out, using path module is probably the best way.
However, most of the solutions here have gone back to using slashes like:
path.join(__dirname+'../test/karma.conf.js')
However, by doing this, you're beating the purpose of using path. One uses path to do operations irrespective of the underlying OS (Linux, Windows etc). Just to give a bit of insight, you can do the path operations directly as string operations (like __dirname + '../test/karma.conf.js'. You do not do this because Linux uses forward slashes ( / ), Windows uses backward slashes ( \ ). This makes your application prone to errors when you port it across operating systems.
Thus, the better way would be:
path.join(__dirname, '..', 'test', 'karma.conf.js')
And of course, coming back - prevent use of slashes in your path.join, instead spread out your params.
I am using (path) NPM for the above usage......
simply require path npm in js file.Then use
let reqPath = path.join(__dirname, '../../../');//It goes three folders or directories back from given __dirname.
__dirname is just a string. you can use ../ to traverse up the folder structure and path.join to resolve the path
path = require('path')
configFile: path.join(__dirname, '../test/karma.conf.js'),
You can use Path like this
const path = require('path');
path.join(__dirname, "../");
if you are sending the path as a string,
configFile: path.join(__dirname+'../test/karma.conf.js'),
this doesn't work.
Instead you have to use a comma, (the plus sign concatenates the two strings)
configFile: path.join(__dirname, '../test/karma.conf.js'),
from Root directory
(path.join(__dirname , 'views' ,'main.html')) -> will return Root:/views/main.html
from any sub-folder of Root
(path.join(__dirname , '../views/main.html')) -> same as above
Like Pranav Totla said, hardcode the path with forward slashes ( "/" ) or backward slashes ( "\" ) makes the application prone to errors when it came across different operating systems.
Use the built in "path" module to prevent errors.
// Import "path"
const path = require('path');
// To go down on the three from index.html:
path.join(__dirname, 'css', 'style.css')
// To go up on the three from style.css:
path.join(__dirname, '..', 'img', 'cat.jpg')
// Three
root/
| |_css/
| |_img/
|
|_index.html
we can use path module to go back one level from the current directory
Example:
path.join(__dirname, '..', 'test', 'conf.js')
__dirname -- present directory
.. -- one level
test -- folder name
config.js -- file (test folder inside)
Try putting a \\ before the ..\\.
Without it, the path your generating has a folder called WebApi... as part of it. You can see this in the path being output from the error message.
Like this:
gulp.task('test', function (done) {
karma.start({ configFile: __dirname + '\\..\\test\\' +'\karma.conf.js', singleRun: true }, done);
});
You may also want to look into using the path library from npm. It makes combining paths a lot easier by handling adding and removing extra path separator characters as needed.
Here is all you need to know about relative file paths:
Starting with / returns to the root directory and starts there
Starting with ../ moves one directory backward and starts there
Starting with ../../ moves two directories backward and starts there (and so on...)
To move forward, just start with the first sub directory and keep moving forward.
this will move you 2 directory back irrespective of any operating system:
import { join, sep } from 'path';
join(__dirname, sep, "..", sep, "..");

fs: how do I locate a parent folder?

How do I write this to go back up the parent 2 levels to find a file?
fs.readFile(__dirname + 'foo.bar');
Try this:
fs.readFile(__dirname + '/../../foo.bar');
Note the forward slash at the beginning of the relative path.
Use path.join http://nodejs.org/docs/v0.4.10/api/path.html#path.join
var path = require("path"),
fs = require("fs");
fs.readFile(path.join(__dirname, '..', '..', 'foo.bar'));
path.join() will handle leading/trailing slashes for you and just do the right thing and you don't have to try to remember when trailing slashes exist and when they dont.
I know it is a bit picky, but all the answers so far are not quite right.
The point of path.join() is to eliminate the need for the caller to know which directory separator to use (making code platform agnostic).
Technically the correct answer would be something like:
var path = require("path");
fs.readFile(path.join(__dirname, '..', '..', 'foo.bar'));
I would have added this as a comment to Alex Wayne's answer but not enough rep yet!
EDIT: as per user1767586's observation
The easiest way would be to use path.resolve:
path.resolve(__dirname, '..', '..');
Looks like you'll need the path module. (path.normalize in particular)
var path = require("path"),
fs = require("fs");
fs.readFile(path.normalize(__dirname + "/../../foo.bar"));
If another module calls yours and you'd still like to know the location of the main file being run you can use a modification of #Jason's code:
var path = require('path'),
__parentDir = path.dirname(process.mainModule.filename);
fs.readFile(__parentDir + '/foo.bar');
That way you'll get the location of the script actually being run.
If you not positive on where the parent is, this will get you the path;
var path = require('path'),
__parentDir = path.dirname(module.parent.filename);
fs.readFile(__parentDir + '/foo.bar');
You can use
path.join(__dirname, '../..');
this will also work:
fs.readFile(`${__dirname}/../../foo.bar`);
i'm running electron app and i can get the parent folder by path.resolve()
parent 1 level:path.resolve(__dirname, '..') + '/'
parent 2 levels:path.resolve(__dirname, '..', '..') + '/'
This works fine
path.join(__dirname + '/../client/index.html')
const path = require('path')
const fs = require('fs')
fs.readFile(path.join(__dirname + '/../client/index.html'))
You can locate the file under parent folder in different ways,
const path = require('path');
const fs = require('fs');
// reads foo.bar file which is located in immediate parent folder.
fs.readFile(path.join(__dirname, '..', 'foo.bar');
// Method 1: reads foo.bar file which is located in 2 level back of the current folder.
path.join(__dirname, '..','..');
// Method 2: reads foo.bar file which is located in 2 level back of the current folder.
fs.readFile(path.normalize(__dirname + "/../../foo.bar"));
// Method 3: reads foo.bar file which is located in 2 level back of the current folder.
fs.readFile(__dirname + '/../../foo.bar');
// Method 4: reads foo.bar file which is located in 2 level back of the current folder.
fs.readFile(path.resolve(__dirname, '..', '..','foo.bar'));

Categories