How to locate parent path node.js OS independent manner - javascript

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

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

how should I handle this nodejs code to do the rigth things?

this is my first question here. I need some help with my code structure. My api in node with express have to do the following:
receipt GET /api/file/{filename}
return the file content, its could be a big one (a few GB).
For now, I could get the files with streams, but I don't the best practice to handle error in this case.
'use strict';
const fs = require('fs');
const express = require('express');
const app = express();
const path = require('path');
const filePath = path.join(__dirname, `../file`);
console.log(filePath)
app.get('/api/:filename', (req, res) => {
let filename = req.params.filename
const streamFile = fs.createReadStream(`${filePath}/${filename}`);
streamFile.pipe(res);
} );
module.exports = app;
Should I make another dir, maybe 'modules', and there code an async function to read and pipe the files, and call the function from app.get in routes dir ?
Remember that Express is an "un-opinionated, minimalist web framework for Node.js applications", unopinionated means that it doesn't decide for you a lot of aspects of what tool you use for each specific task, and that is the main difference with another frameworks like Rails. Said that, you could use the classical and and old try and catch, in this case around your I/O operation. A module is a way to mantain separation of concerns and it's a way to organize your code so you can fastly identify what is the part of your code that is causing a malfunction. So in this case i don't consider it necessary because your router's callback is doing one thing and that is ok.
app.get('/api/:filename', (req, res) => {
let filename = req.params.filename
try{
const path = `${filePath}/${filename}`;
if (!fs.existsSync(path)) return res.status(404).send('You could send any message here...');
const streamFile = fs.createReadStream(path);
streamFile.pipe(res);
} catch {
res.status(500).send();
};
});

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.

Express Serving a Static File: Server and Client in Different Locations

I'm trying to get my express to serve up static files that are in another location:
This is the current directory I have:
|__client
| |__thumbnails.html
|
|__server
|__app.js
I tried to just use app.use(express.static(path.join(__dirname, '..', 'client')));, but it wouldn't serve the file at all. However, when I used the same path.join for a get request on '/' it will send the file.
Here it the code I have at the moment. It's working, thank God, but I want to see if there is a way for me to serve it without actually sending the file.
const express = require('express');
const path = require('path');
const similar = require('./routes/similar');
const image = require('./routes/images');
const app = express();
app.use(express.static(path.join(__dirname, '..', 'client')));
app.use('/item', similar);
app.use('/thumbnail', image);
app.get('/', (req, res) => res.status(200).sendFile(path.join(__dirname, '..', 'client', 'thumbnail.html')));
module.exports = app;
You can make the file anything you want, through configuration of the serve-static module:
https://expressjs.com/en/resources/middleware/serve-static.html
From that page:
var express = require('express')
var serveStatic = require('serve-static')
var app = express()
app.use(serveStatic('public/ftp', {'index': ['default.html', 'default.htm']}))
app.listen(3000)
now anything that you put in the 'index' array will be looked at, in the order you defined.
Otherwise, you would still be able to get to your html file if you put the actual filename in the url.
Okay I think I figured it out. So apparently you have to have the html saved as index. Express is looking for that, but since I don't have an index.html it skips my thumbnails.html.
So renaming my html to index.html fixed the issue.
UPDATE:
So reading through the documentation, you can set the what the default is by passing in an options. I passed in { index: 'thumbnails.html' } as the second argument for static and it serves my html.

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