fs: how do I locate a parent folder? - javascript

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'));

Related

Adding a variable to __dirname -- Javascript

I am trying to add a variable to __dirname because I want to navigate folders depending on that but it doesn't seem to work.
Isn't this the correct way to do so?
var directory = '/some_folder/';
fs.readdir(__dirname + directory, function(err, files){
// code
}
To be more precise, I have a folder like so:
A_folder
some_folder
some_other_folder
..
And knowing __dirname is A_folder I want to access the other folders depending on what my "directory" variable is.
Use path.join() to get absolute path. Pass relative path as second argument.
var path = require('path');
var directory = path.join(__dirname, './some_folder');
fs.readdir(directory, function(err, files){
// code
}

Javascript insert backslash: __dirname + "index.html"

in the question below, someone has given me the following code:
res.end(fs.readFileSync(__dirname + "index.html"));
However this is creating a filename of folderNameindex.html, i.e. there needs to be a backslash before index.html. From googling, the solution should be two x \ within the double quotes, resulting in "\index.html". I've tried this and many other variations, single, double, treble, forward slashes, regex escaping. In every case, my CLI tells me it cannot find file folderNameindex.html.
This is probably simple. Grateful for any help.
Can i use node as webserver for html app?
EDIT:
My new code:
const http = require('http'), // to listen to http requests
path = require('path'),
fullPath = path.join(__dirname, 'index.html'),
fs = require('fs'); // to read from the filesystem
const app = http.createServer((req,res) => {
// status should be 'ok'
res.writeHead(200);
// read index.html from the filesystem,
// and return in the body of the response
res.end(fs.readFileSync(fullPath)); });
app.listen(3000); // listen on 3000
I still get the same error - my command line tells me it can't find folderNameindex.html
You should use path.join, for example;
const path = require('path')
const fullPath = path.join(__dirname, 'index.html')
Additionally, there are many other functions that will help you working with paths in a portable way, make sure to read all the docs for the path and file system module.

How to dynamically resolve nodejs required module's path based on caller script's path?

I am kind of new to Javascript programming. Currently I am trying to write a test for Javascript files in existing codebase that contains other programming languages. The structure is like below.
src/js/path1/path2/path3/path4/path5/
Rectangle.jsx
Circle.jsx
test/js/path1/path2/path3/path4/path5/
RectangleTest.jsx
CircleTest.jsx
The content of RectangleTest.jsx is below
import Rectangle from './../../../../../../../src/js/path1/path2/path3/path4/path5/Rectangle';
describe('<Rectangle>', () => {
it('Should show content', () => {
assert.ok(true);
});
});
As you can see, I need to set the path as a very long relative path ./../../../../../../../src/js/path1/path2/path3/path4/path5. It will be very exhaustive for I prefer something like below.
import Rectangle from './Rectangle';
Since the path of the test file and the tested file is pretty similar, it should be possible to calculate the path to be resolved by the import.
Is there a way to do that?
I am using mocha for the testing framework. I uploaded the sample code to Github (link), so you can see it.
You can use the __dirname global node variable which contains the absolute path to the current file. However you have to use require() instead of import ... because import does not support dynamic paths.
if your absolute path only contains one test name you can get away with:
const path = require('path');
const retanglePath = path.join(__dirname.replace('/test/', '/src/'), 'Rectangle'));
const Rectangle = require(rectanglePath).default;
Note: the .default is for ES6 exports that are converted with babel.
Hope this helps.
Edit: Here is a solution that also works with other test folder names in the absolute path (replace the path relative for your needs):
const path = require('path');
const basePath = path.join(__dirname, '../../../../');
const srcPath = __dirname.replace(basePath + 'test', basePath + 'src');
const Rectangle = require(path.join(srcPath, 'Rectangle')).default;
After researching about how nodejs resolve module, it turns out that it's possible to override the require function behavior by overriding module module.
So I write a file called bootstrap.js that contains code below
let path = require('path');
const BASE_DIR = __dirname;
const SRC_DIR = path.resolve(BASE_DIR + '/../../src/js');
var Module = require('module');
Module.prototype.require = new Proxy(Module.prototype.require, {
apply(target, thisArg, argumentsList){
let name = argumentsList[0];
let isLocal = thisArg.filename.startsWith(BASE_DIR) &&
name.startsWith('./');
if (isLocal) {
let testFileDir = path.dirname(thisArg.filename)
let testPath = testFileDir.replace(BASE_DIR, '');
let srcPath = SRC_DIR + testPath;
let relativePath = path.relative(testFileDir, srcPath);
argumentsList[0] = relativePath + '/' + name;
}
return Reflect.apply(target, thisArg, argumentsList)
}
});
The structure now is like this
src/js/path1/path2/path3/path4/path5/
Rectangle.jsx
Circle.jsx
test/js/
bootstrap.js
path1/path2/path3/path4/path5/
RectangleTest.jsx
CircleTest.jsx
To execute the test, I use the statement below
nyc mocha --recursive \
--require test/js/bootstrap.js \
--compilers js:babel-core/register \
test/js/**/*.{js,jsx}
Using the code above, I can check the caller script and called module and see if the caller script resides in the test directory. If it does then, it will see if the module called by using relative path.
The advantage is that, we still can use import statement.
import Rectangle from './Rectangle';
describe('<Rectangle>', () => {
it('Should show content', () => {
assert.ok(true);
});
});
The downside is for now the test file cannot call relative path in the test directory. Relative path will now only resolve in source path. But it's good for now. I am wondering if we can check if a module is resolvable or not.
The updated source code can be read here.

Traverse '__dirname' in Node.js Application

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.

How to locate parent path node.js OS independent manner

I want it portable across OSs
var path = require("path"),
fs = require("fs");
fs.readFile(path.join(__dirname, '../..', 'foo.bar'));
This code probably works only for Mac/Linux/Unix;
What is the universal manner to write this code?
The correct and easiest way would be:
path.join(__dirname, '..', '..', 'foo.bar');
But if you really want to write the separator manually, you would do it like this:
path.join(__dirname, '..' + path.sep + '..', 'foo.bar');
Depend it on the OS by ask node for it.
But I think there are some more differences like Volumes (C:\) which elementary different un nix systems.
e.g.
var sSlash = (process.platform.match(/^win/))?'\\':'/';
var path = require("path"),
fs = require("fs");
fs.readFile(path.join(__dirname, '..'+sSlash+'..', 'foo.bar'));

Categories