standard way to deal with relative paths in node.js - javascript

Node.js path resolve system make me mad. I have
var a = '../data/data.db' path to a file but this path resolve differently depending from am I run this code from node.js directly or from test runner or from CI. Is there is a standard unified way how relative paths need to be managed in node.js?

You should use the __dirname property and path.resolve. __dirname gives you the path to the scripts location as opposed to the current execution location, and path.resolve cleans up the relative path.
var path = require('path');
var a = path.resolve(__dirname, '../data/data.db');

Your can use global variable such as __dirname which points to the directory the currently executing script resides.

Related

Node.js - get directory of routes.js

I have my server.js file at let's say directory: /dir1
I start the server with node server.js.
I have my file routes.js in directory /dir1/app/.
I want to get the directory of the server.js file.
I am not too sure how to do this. I can place code that tells me the location of the current script. But what is the current script?
A web app makes use of multiple files. So how do i get the dir of server.js?
EDIT: Here is a code example:
// routes.js
const spawn = require('child_process').spawn;
const fs = require('fs');
module.exports = function(app)
{
//the file upload button does a POST the the '/' route
//i left the arrow function notation for reference
app.post('/', (req, res) => {
if (req.files)
{
var pathAndFileName = '/home/user1/Desktop/app/dataLocation/'+fileName;
As you can see, pathAndFileName is hardcoded.
It works on my system, but it does not for every system.
So i would like to be to get the location of the server.js file (in /dir1), inside the app.js file, so i can the append to the directory the '/dataLocation' + fileName.
If routes.js is in:
/home/user1/Desktop/app/dir1
And, server.js is in:
/home/user1/Desktop/app
And, then the file you're trying to get to is in:
/home/user1/Desktop/app/dataLocation
Then, from routes.js, you can get the directory of server.js with this:
const serverjsDir = path.join(__dirname, ".."); // go up one level
Or, you could get the whole path your edit seems to be looking for (in a dataLocation subdirectory below where server.js is) with this:
const pathAndFileName = path.join(__dirname, '../dataLocation', fileName).
More detail
If you're using CommonJS modules (that use require()), then you can get the current script's directory with __dirname and then it's up to you to know where other resources are relative to your own directory so you can navigate up or down the directory hierarchy from __dirname. For example, if you want to get access to a file main.css in another directory at the same directory level as your script file, you could construct at path like this:
let filePath = path.join(__dirname, "../css/main.css");
But what is the current script?
The current script is the script that contains the code that is accessing __dirname.
A web app makes use of multiple files. Since the place where i want to embed the location (in its code) is located inside routes.js, i guess this is where is should target, am i correct?
It's not clear to me exactly what you mean here. If you can provide a specific example showing what code located in what directory wants to access what file located in what other directory, then we could offer you the precise code to get to that file.
If the code that wants to access this other file is in routes.js, then the location of routes.js would be in __dirname and you would build a relative path from that location as shown above.
To help you understand, __dirname is not a global variable. It's a module-specific variable that contains a different value for every single module location in your project. So, whatever code is running in whatever module will have access to it's own copy of __dirname that specifies the location of that specific code.
To get access routes.js, if it is a module, Im assuming you are using Import or Require, and you could use
require(./app/routes);
If you were to go back a directory, you use ../ as many times as needed. If this is not the answer you were looking for, either reply or someone else may answer

resolving a path in node when using .mjs files

I'm writing a quick/simple deploy script in node using the module format mjs so that I can use the module syntax.
One of the things I'm doing in the file is resolving an absolute path from a relative one based on the current modules' directory.
In the past I would have done something like:
const path = require("path")
const distPath = path.resolve(__dirname, "..", "dist")
But in module js I lose the __dirname symbol and get the error:
ReferenceError: __dirname is not defined
So I hop online to see what the mjs version of this is (woof, searching for "resolve path in mjs" or any permutation on that is rough b/c everything points to the original way of doing it :P), and from what I learned I can do this:
import { dirname, resolve } from "path"
import { fileURLToPath } from "url
const distPath = resolve(dirname(fileURLToPath(import.meta.url)), "..", "dist")
Which works, but is a handful to type.
If this is the correct way of doing it then I'll just memorize the new approach, but this feels like such a common task that there must be a better way of doing it in module js and I just haven't found it.
Any alternatives?

Is it necessary to specify directory when using appendFileSync?

I'm going through some of the nodejs documentation and starting to familiarize myself with some of the more basic functions. Specifically looking at appendFileSync function.
When trying to append a file, is it necessary to specify the directory? I don't recall this being a requirement in previous versions of Node but it seems when the directory is not specified, a new file is created in the root instead of appending the file.
I'm just trying to append a basic txt file, with this it creates a new file:
const fs = require('fs');
fs.appendFileSync('notes.txt', 'Changing the text with appendFileSync');
However, when specifying the directory, it appends the file just fine making me think this is required:
const fs = require('fs');
fs.appendFileSync('./nodejs/notes-app/notes.txt', ' Colin, changed the
text with appendFileSync', function (err) {
if (err) throw err; console.log('Notes updated');
});
Node -v 12.13.0
NPM -v 6.12.0
As with all fs operations that take a file path, if you don't specify any sort an absolute path, then the path you do specify is combined with the current working directory. In a nodejs program, the default current working directory (if you don't change it programmatically) is taken from the environment in which you started the node program.
If want to control the path directly without regard to the current working directory, then specify an absolute path.
This is what the fs module documentation says about file paths:
String form paths are interpreted as UTF-8 character sequences identifying the absolute or relative filename. Relative paths will be resolved relative to the current working directory as specified by process.cwd().
Note: For some situations, a developer wants to access the file system relative to the installation of the module that is running. That is typically done by building a path that is relative to __dirname which is the location of the current module like this.
path.join(__dirname, "somefile.txt");
Of course, you can always specific a full path name starting from root if you want.

How to get the absolute path of my NPM global package?

I'm building an NPM package that is supposed to run globally.
Inside the NPM package, there's a data folder which contains a file I need to read at runtime.
How can I get the absolute path of my NPM package, so I can read the data folder?
I'm searching for that on Google with no luck.
You can use the path module and with it either start your paths with a ./ or just omit any / at the begining of a string.
for example:
var path = require('path');
console.log(path.resolve('./');
is the same as
var path = require('path');
console.log(path.resolve('');
the resolve method is nice in that it'll resolve your relative path with an absolute path to it. Good to be safe!
To build on #explosion pills' comment, it's nice to combine __dirname and path.resolve
console.log(path.resolve(__dirname));

In Node.js how can I tell the path of `this` module?

In a Node.js module I would like to open a file--i.e, with fs.readFile()--that is contained in the same directory as my module. By which I mean it is in the same directory as the ./node_modules/<module_name>/index.js file.
It looks like all relative path operations which are performed by the fs module take place relative to the directory in which Node.js is started. As such, I think I need to know how to get the path of the current Node.js module which is executing.
Thanks.
As david van brink mentioned in the comments, the correct solution is to use __dirname. This global variable will return the path of the currently executing script (i.e. you might need to use ../ to reach the root of your module).
For example:
var path = require("path");
require(path.join(__dirname, '/models'));
Just to save someone from a headache.

Categories

Resources