Handling relative paths across modules in javascript - javascript

So let's say I have a .js file which exposes a function, which I want to be able to import in many other files. The function in this file needs access to some data stored in a certain file ( take .txt for this example) and I'm using the relative address to read and write to this text file.
Now the problem comes when I import this module into other files in different directories, the relative paths won't be valid but I don't know how I can change this? I'm sure there's a simple way to do this but I can't figure it out at all.
file 1
relative path = '../../file.txt'
function foo(){
fs.readFile(relativePath)
}
module.exports = {foo}
file 2
const {foo} = require('foo')
foo();

It doesn't actually matter which other modules load this module. The path is going to be resolved relative to the current working directory, which depends on in which directory your shell is in when you invoke the code.
If you want it to resolve relative to that specific JavaScript file, then you can use __dirname:
const path = require('path');
// ...
fs.readFile(path.join(__dirname, relativePath));

you can use resolve method of path package like
const path = require('path').resolve
path.resolve('../../file.txt')

Related

Is it possible to resolve imported module path at compile time in Webpack?

I want to create build that will, based on env variable, include just specific components in the bundle.
For example when I import component like this:
import Module1 from '#/components/Module1'
I want the path to actually be converted so that imports looks like this:
import Module1 from '#/components/brands/' + process.env.APP_BRAND + 'Module1'
Now I don't want to do this for all imports, just for certain ones (eg. modules that have branded version), so maybe I'd like to prefix import path with something like !brand! which will be indicator to apply path transform.
So above logic should executed only for import paths such as:
import Module1 from '!brand!#/components/Module1'
And if process.env.APP_BRAND is falsy then I just want to stick to the original import (eg. just remove !brand! prefix from the path).
So the important aspect is that I want this to be done at build time so that Webpack can statically analyze modules and create optimized build. Is this possible to do? I suppose I need to somehow add this path transformation logic but how should I do that? Should I create a loader, plugin or is there an existing solution?
I am using Webpack 5.
Webpack provides a module resolve functionality that you can use here. Read the docs here. As an example, in your case, you can do this:
const path = require('path');
module.exports = {
resolve: {
alias: {
'#/components/Module1': path.join(
__dirname,
process.env.APP_BRAND
? '#/components/brands/' + process.env.APP_BRAND + 'Module1'
: '#/components/Module1')
}
},
};
Note that, here you would pass environment variable to your Webpack process (aka Node.js process) and make decision accordingly. Also, your resolve module must be absolute path.

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

Is there a way to load JS file without require?

Is there a way to load a javascript file without require, but with fs for example?
I know that for json files I can do:
const jsonFile = JSON.Parse(fs.readFileSync("./jsonfile.json")
Is there a way to do the same for a javascript file?
The reason I am asking is because, i have a configuration file that I kinda want to detach from my app, because when I bundle it with webpack, I cant exclude the config file.
I have tries to directly read it, but I just got some raw format in a buffer:
const jsFile = fs.readFileSync("./jsFile.js")
EDIT ANSWER: I was able to do it by utilizing readFileSync and eval:
const jsFile = eval(fs.readFileSync("./jsFile.js", "utf-8"));
Keep in mind that if you are requiring other files within that file, the paths change! They will NOT be relative to jsFile.js, but relative to the file which reads the jsFile.js
I was able to do it by utilizing readFileSync and eval:
const jsFile = eval(fs.readFileSync("./jsFile.js", "utf-8"));
Keep in mind that if you are requiring other files within that file, the paths change! They will NOT be relative to jsFile.js, but relative to the file which reads the jsFile.js

Import dynamic file with require React

Hello there I'm importing a dynamic file with require, but my file is outside of /src so I check a post that say if I comment two lines in ./node_modules/react-scripts/config/webpack-config.js
I can access to files outside of /src, the problem is that if I do this works fine:
Show PDF
but if i want to be dynamic receiving the path through props i get this error:
Error: Cannot find module '../../../../../files/asd.pdf'
Where my code is this and this.state.fullPath is the same of before.
Show PDF
I try concatenating a empty string but still not working
This is a problem that relates to the module bundler that you are using. In order for it to work, the require function has to get a path which the bundler will use to import the module at build time rather than runtime. You will need to use require using the full path and not a variable.
You can try something like:
const one = require('./path/to/one.pdf');
const two = require('./path/to/two.pdf');
const href = variable === 1 ? one : two;
Show PDF

I'd like to reuse code from another module in my Nodejs backend

I'm using the Yeoman Generator Angular Fullstack and I'd like to reuse JS code from different directories within my server directory. I'm referencing the file that has the functions I want like:
var something = require('/.path');
I get the error: "Cannot find module" in my terminal.
I tried a number of variations of the path working through all of the levels from server level down to file level where the given functions are contained. I looked at a few tutorials:
http://www.sitepoint.com/understanding-module-exports-exports-node-js/
AND
https://www.launchacademy.com/codecabulary/learn-javascript/node/modules
I clearly missed something. Each module of my nodejs has a controller with an exports.create function. All of my code for each module is contained within my exports.create function accept for other required modules. I have no problem requiring underscore or other libraries in my Node/Bower modules by the way.
To be as detailed as can be, I expected
var something = require('./directory/directory.controller.js');
var something = require('/.path');
The path you are using is likely incorrect. Probably you want to open the file called path.js contained in the same folder of the file from which you are importing it. In order to do that, you should change the import as follows :
var something = require('./path');
./path is a relative path where . stands for current directory.
/.path is an absolute path. In this case require is importing a hidden file in the root directory. I guess is not what you want.

Categories

Resources