How to resolve path to a file within node_modules - node.js

Problem loading a file using relative path when my node app is initialised using a another node app
I have created an npm which relies on a file stored relative to project root. something like this
index.js
- res
- config.json
Now I read the config.json using following code
const pathToConfig = path.resolve(__dirname, '../res/config.json')
This works great locally.
But in my prod setup this app is initialised by another node app.
And __dirname resolves to root of that app so all my logic to find config.json get messed up.
Is there any way I can read the file without worrying about how node app was initialised?

Have you tried the command process.cwd()? It is almost the same as __dirname but does differ slightly.

Related

Deploy VueJS App in a sub-directory or sub-path

I’m experiencing problems deploying a Vue JS app built using the Webpack CLi to work.
If uploaded in a root directory everything renders fine, but inside a subfolder, all the links break.
I want deploy VueJS App to this url :
https://event.domain.net/webinar
I have added publicPath in vue.config.js :
var path = require(‘path’)
module.exports = {
publicPath: ‘./’
}
But only the css and js folders point to the path /webinar.
For assets, fonts and others still point to the subdomain https://event.domain.net.
CSS and JS point to path /webinar
Asset, fonts still point to subdomain https://event.domain.net/
Console
use value of publicPath as /webinar that should work.
More details are here https://cli.vuejs.org/config/#publicpath
you can configure publicPath even based on environment.
Sagar Rabadiya pointed you to the right link:
create a file called vue.config.js in the project root (where your package.json is located).
prompt the following code snippet inside:
module.exports = {
publicPath: process.env.NODE_ENV === 'production'? '/your-sub-directory/' : '/'
}
and save the file.
Open a terminal and navigate to your project, then run npm run build to generate a production build from it.
As soon as the production build has been generated, copy the contents from it and paste it in the sub-directory you created in the root folder. For example, if you use Apache, the default root directory is the htdocs folder. I've also created a virtual host on the server, maybe you also need to do this.
Open the browser and type the address where your sub-directory lives. For example: http://your-server-url:your-port/your-sub-directory/ Your should see your app now.

Why does require() not require an absolute path but an express.static() does?

I am trying to run my index.js script from outside the project directory. My project structure is as follows:
app
- config
- config.js
- public
- index.html
- src
- index.js
Now when I run my src/index.js from outside my app folder, require() is able to resolve the relative paths
const config = require(`../config/config`);
On the other hand express.static is not able to resolve such relative paths.
e.g. app.use(express.static("../public"));
Why do I need to use path.join and get the absolute path?
require() works off __dirname which is independent of what the current directory was when your app was loaded. It's always the directory where the module is located in, so it is consistent.
express.static() when used with relative paths uses the directory that the main app was launched form, so if you use relative paths, its behavior varies depending upon how you launch the app.
From the express doc for serving static files:
However, the path that you provide to the express.static function is
relative to the directory from where you launch your node process. If
you run the express app from another directory, it’s safer to use the
absolute path of the directory that you want to serve
So, if you want the directory to be module relative, you have to manually combine your path with __dirname to make a full path, as you have discovered.

How to run node app from sub-directory with .env variables of that sub-directory?

I have a Node.js App called app.js and its stored in the directory B.
To run this script correctly it needs enviroment variables. These are stored in a file called .env, which is also in directory B.
In my app.js the env-variables are loaded via require("dotenv").config();
and I can then access them with e.g. process.env.SOME_VAR
So if I am currently located in directory B, I can just use node app and my app will execute just fine.
But if I go to the parent directory A and try to run my app via
node ./B/app
it will not execute, because it seems to have no access to the enviroment variables of the .env file.
So, my question is, how can I run my script from its parent folder, if I want to keep the .env file in the same directory?
You could use dotenv to load the the content of the environment variable i.e.
const dotenv = require('dotenv');
// ...
// Then go ahead to load the .env file content into process.env
dotenv.config({ path: '/full/custom/path/to/your/env/vars' });
you can set path using {path : '../.env'}.
require('dotenv').config({path : '../.env'});
Brilliant! it worked for me, I put my .env inside /vars folder
and used this line
require('dotenv').config({path : 'vars/.env'});
Instead of this line
require("dotenv").config();

Setting Up Node.js App Directory

I'm completely new to using Node.js and even utilizing the command line, so this question may be extremely elementary, but I am unable to find a solution.
I am trying to set up an app directory using Node.js and NPM. For some reason, whenever I try to use the port:5000 I get a "Cannot GET/" error. My question is, why is my setup for my app directory not working?
I have installed connect and serve-static, and yet it will not retrieve files and listen on port 5000. I have created a server.js file in my user, kstach1. Here is the code I have within that file:
var connect = require('connect');
var serveStatic = require('serve-static');
var app = connect();
app.use(serveStatic('../angularjs'));
app.listen(5000);
So, I don't quite understand why this won't reference my folder of angularjs, where I want to store my app. I have tested it by adding a file within the folder called test.html, and entered localhost:5000/test.html, and still get the "Cannot GET/test.html" error.
I know that Node is working correctly because I can enter scripts into the command line and they give the correct output. I do this as a user (kstach1).
The only thing I can think of that I may be doing wrong, is where my files are located. I have the angularjs folder located in the root user folder on my Mac (kstach1), as well as the server.js file. Is this incorrect? If this is not the issue, is it because of where Node is installed (usr/local/bin/node)? My research to this point has led me to think that my problem could also be that I need to add the installation directory to my path. However, I don't want to mess with this unless I know that is the case.
Any help would be greatly appreciated.
I did a little research on the serve-static package and copied the code you provided.
My project folder is located at "C:\teststatic" and the folder with the static files is: "C:\angularjs", also using "text.html" that is located in the 'angularjs' folder.
When running the code you provided and going to localhost:5000 it indeed returns "Cannot GET/". This is most likely because there is no "/" file declared.
Going to localhost:5000/test.html works for me, so you could try setting a "/" like this:
app.use(serveStatic('../angularjs', {'index': ['test.html', 'index.html']}));
And see if that works for you. If not, you should double check directory names / locations.
EDIT:
From reading the comment you posted: try this instead:
app.use(serveStatic('angularjs'));
I suggest moving your angularjs folder up into your main project's directory in a public/ folder. Its a pretty standard convention to have all of your static assets in public/. You can then use the path module to automatically resolve your path, inserting this where you have '../angularjs': path.join(__dirname, 'public').
So, your code would look like this:
var connect = require('connect');
var serveStatic = require('serve-static');
var app = connect();
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public'));
app.listen(5000);
And, your directory structure would look like this:
server.js
public/
angularjs/
test.html
You should then be able to use localhost:5000/angularjs/test.html to view your test.html

why I can't sendFile() in node.js express when deployed to AWS?

I am using node.js express to serve some static file like svg and json to the client, so I used sendFile() to send the files directly.
so here is my server file structures,
/root // the root of the server
/maps // put some static files
/routes/api // put the web API
in the web API
app.get('/buildings/map',function(req,res){
var mappath = 'maps/ARM-MAP_Base.svg';
res.sendfile(mappath);
})
It works perfectly on my local server to send files to the client, so it means the server could locate the file and send it. but when the server is deployed to the AWS, this methods would encounter a error - 242:Error: ENOENT, stat node.js, looks like it can't open the file in that path
I read some solutions like combining the __dirname with mappath, it didn't work since it would bring to the path of /routes/api/maps/...
so far I have no idea why it works on my local computer but fail to work on the AWS
Relative fs paths like mappath will be resolved from the current working directory, which isn't guaranteed to be consistent. It works locally because you're executing your application with /root as your working directory.
This is why you're finding recommendations to use __dirname, which an be used to resolve paths relative to the current script.
Though, along with it, you'll want to use ../ to resolve parent directories.
var mappath = 'maps/ARM-MAP_Base.svg';
res.sendfile(__dirname + '/../../../' + mappath);
This assumes the current script is located in and __dirname would be /root/maps/routes/api as the indentation in your directory tree suggests.

Resources