What is the rule for express.static root path? - javascript

I ran
node src/app.js
in the mean-to directory
express.static('public')
would work,why?
don't need to specify the path?
what's the rule?
and I know
__dirname+'/../public'`
works just fine.
Just want to make sure the the logic here
I look up the doc
http://expressjs.com/en/starter/static-files.html
it says
"Pass the name of the directory that contains the static assets to the express.static middleware function to start serving the files directly. "
"the path that you provide to the express.static function is relative to the directory from where you launch your node process"
Does that mean
if I run node src/app.js in mean-to folder --> use express.static('public')
if I run node app.js in src folder => use express.static('../public')
and for safety, better use __dirname to get the absolute path of the directory

Express static uses resolve function from module path
Example using path:
var p = require('path');
p.resolve('public'); // will return your absolute path for `public` directory
So rules for express static the same as for path#resolve function
You can see more example in the docs for path module
What's the difference between p.resolve and __dirname?
path#resolve
p.resolve() resolves to an absolute path
path.resolve('public');
Will return your absolute path for public' directory(e.g "C:\projects\myapp\public")
path.resolve('src'); // => "C:\projects\myapp\src")
__dirname
__dirname - name of the directory(absolute path) from which you're currently running your app
file app.js
console.log(__dirname);
Running node app.js will print your absolute path for your app, e.g "C:\projects\myapp"

You mixed 2 lines in one... And both are necessary:
//This line is to say that the statics files are in public
app.use(express.static(__dirname + "/public"));
//This another line is to say that when call the route "/" render a page
app.get("/", function (req, res) {
res.send('Hello World!');
}

Probably, the reason is in running it from directory highter one level than dir with code? Try run it from src:
cd src
node app.js

Related

Serve an entire /directory using an express server

I have an express server, and I would like to provide route handling to manage an entire directory.
root
/html
/css
/js
/app.js
/images
/index.html
/some-other.html
/server.js
Do I need to serve every file individually using
app.get('/', (req, res) => {
res.send(htmlPath + '/index.html');
});
and adjust it for each .html file I am serving, or can I assign the /path-to-file as a variable and concatenate the variable into the htmlPath.
Additionally, is the following correct syntax to define the path/directory name
var htmlPath = path.join(__dirname, "html/");
app.use(express.static("html"));
app.use(express.static(__dirname));
app.use(express.static(path.join(__dirname, "/html")));
I am relatively new and have been following various other questions and answers to get to where I am now.
according to SOLID principle and MCV structure, I suggest you to handle each part of your directory in an individual file.
root
/app
/statics
/images
/css
/views
/index.html
/some-other.html
/routes
/statics.js
/views.js
/index.js
/app.js
/server.js
so with this structure you have a routes directory which handle all the routes.
in the index.js(Routes) you send each request to the correct route file:
const staticsRouter = require('./statics');
const viewsRouter = require('./views');
module.exports = (app) => {
app.use('/statics',staticsRouterr);
app.use('/views',viewsRouter);
}
and in router files response to each request.

How to res.sendFile() a file that is in a different directory for Express.js webapp?

I have this inside controllers folder:
//controler.js
exports.serve_sitemap = (req, res) => {
res.sendFile("../../sitemap.xml");
// or
// res.send(__dirname + "./sitemap.xml")
// But neither of these work
};
This exported function is imported in a file inside the routes directory
const { serve_sitemap } = require('../controllers/indexer')
var router = require('express').Router()
router.get("/sitemap", serve_sitemap)
module.exports = router
Currently I am getting a 404 error when I try to get the sitmap at localhost:3000/sitemap
Folder Structure:
Before, I had the same thing in index.js which is the entry point.
app.get("/sitemap", (req, res) => {
res.sendFile(__dirname + "/sitemap.xml");
});
This was working perfectly, until I decided to restructure the project
How can I refer to the sitemap.xml file that is located in the root directory from a file that is in a sub-directory when using res.send()?
How can I get the absolute path to the root of the project directory, then I can append the file name to the path. This can solve the issse
I maybe missing something obvious. In that case, please help me out.
Any suggestion gratefully accepted. Thanks in advance
Why do you think that res.sendFile(__dirname + "./sitemap.xml") would work?
First of all __dirname + "./sitemap.xml" is not how paths should be concatenated you should use join instead especially if your second path starts with ./. And there is no file sitemap.xml in the directory of the controller:
__dirname + "./sitemap.xml" would result in something like /path/to/project/src/controller/./sitemap.xml
And why should "../../sitemap.xml" work. If you only have "../../sitemap.xml" it is relative to the working directory which is the one where (i guess) index.js is located. So "../../sitemap.xml" will be resolved based on /path/to/project, so /path/to/project/../../sitemap.xml.
Due to that is either res.sendFile("./sitemap.xml") (relative to index.js) or res.sendFile(path.join(__dirname, "../../sitemap.xml")) (relative to the controller).

Why Node.js only recognizes absolute paths? [duplicate]

This question already has answers here:
What is the difference between __dirname and ./ in node.js?
(2 answers)
Closed 3 years ago.
I created a file called nodes, then initialized the file with npm init and the main js file is called main.js. I also created index.html and index.css in the file, after that I want to use Node.js Render this index.html, so I wrote in main.js:
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 9000;
const mainHTML = './index.html';
const server = http.createServer((req, res) => {
fs.stat(`./${mainHTML}`, (err, stats) => {
if(stats) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
fs.createReadStream(mainHTML).pipe(res);
}
});
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
I opened the server with the node desktop/nodes command, but node.js could not find the file.
Until I changed the relative path to an absolute path, Node.js will recognize it:
const mainHTML = 'desktop/nodes/index.html';
Why is this? If I want to use a relative path, how do I do it?
When you access a file in node.js with a relative path, the file is accessed relative to the value of the current working directory for the process. Note, in the modular world of node.js, the current working directory may or may not be the same as the directory where your module was located. And, your code can change the current working directory to be whatever you want it to be.
It is common in modular node.js code to have a programming desire to access things relative to the directory where the current module's code was loaded from. This gives you the ability to use relative paths so the app/module can work anywhere, but it gives you certainty that you'll get the files you want. To do this, one typically uses the module-specific variable __dirname. This is the directory that the current module was loaded from. If it's the main script that node.js was started with then, it's the directory of that script.
So, to get a file from the same directory as the script you are current in, you would do this:
const mainHTML = 'index.html';
fs.createReadStream(path.join(__dirname, mainHTML)).pipe(res);
To access a file in a subdirectory public below where the script is, you could do this:
const mainHTML = 'public/index.html';
fs.createReadStream(path.join(__dirname, mainHTML)).pipe(res);
To access a file in a different subdirectory at the same level (common parent directory) as where the script is, you could do this:
const mainHTML = '../public/index.html';
fs.createReadStream(path.join(__dirname, mainHTML)).pipe(res);
All of these use paths that are relative to where the script itself is located and do not depend upon how the module/script was loaded or what the current working directory of the app is.
You are creating http server, which creates it's path as base, so it understands only paths taking that base path as relative path. If you want to use relative path, then you need to resolve that path.
You can use 'path' library.
const path = require('path')
// To resolve parent path
path.resolve('..', __dirname__)

Custom module express js:Cannot find module name error when modules folder in root directory

Folder structure of my express js app look like this
I am trying to load a modules folder which is located in root directory
routes/users.js
var express = require('express');
var router = express.Router();
var md=require('./modules');
/* GET users listing. */
router.get('/',function(req, res, next) {
//res.send('respond with a resource');
console.log('test');
res.status(200).json({ error: 'message' });
});
module.exports = router;
But i am getting a module not found error:
Cannot find module './modules'
Note:
If modules folder is in node_modules folder require works fine,but getting module name error if its in project root directory,
also an index.js file is present in modules folder
Module resolution in NodeJS is relative to the directory of your dependent module when your resolution starts with ..
In other words :
var module = require('../modules'); // Since your file is in `./routes/index`
// and `module` is in `./modules/index`
If you don't supply . in front of the required module, then NodeJS will look for that module in node_modules directory.
Excerpt from the documentation, which is self explanatory.
require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"
So in your case when you require('./modules'). NodeJS looks for it in the current directory ./routes, then since it can't find it, goes to look at it in node_modules.
Instead of './modules' you can try require('../modules')

Access to projectDir from karma test?

Within a karma test beforeEach) block I would like to access (read) a file from the project directory. However, I do not know how to get access to that directory, since process.cwd() returns the directory the test is running in, which is a random private dir assigned by node or gulp.
How can I find what the project dir is within a running test?
describe.only('convertClaimTypes', function () {
var claimTypes;
before(function () {
var base = process.cwd();
claimTypes = fs.readFileSync(path.join(base, 'build/resources/claimTypes.json'));
claimTypes = JSON.parse(claimTypes);
});
...
Try using __dirname in place of process.cwd() as it gives you the directory of the current file rather than the directory of the executable.
For example, if your tests are within a directory /test and /build is a directory within the root of your application, access /build from /test like so:
path.resolve(__dirname, '../build/');

Categories