What is ‘__dirname’?
The **dirname in a node script returns the path of the folder where the current JavaScript file resides. **filename and __dirname are used to get the filename and directory name of the currently executing file.
When I use express.js as a backend, I faced some issues with ‘__dirname’.
I should use ‘__dirname’ to serve static files in Express.
To serve static files such as images, CSS files, and JavaScript files, use the express.static
built-in middleware function in Express.
The function signature is:
express.static(root, [options]);
For example, use the following code to serve images, CSS files, and JavaScript files in a directory named public
:
app.use(express.static('public'));
Now, you can load the files that are in the public directory:
http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html
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:
const path = require('path');
app.use('/static', express.static(path.join(__dirname, 'public')));
This is a point we have to use ‘__dirname’ as a path instruction. But when I follow this instruction, there are some issues.
‘__dirname’ is not defined in ES module scope in JS
Nodemon displays the error message ‘__dirname’ is not defined in ES module scope in JS. What??
Why do I need to define this script? Because I didn’t import the path
module.
import path from 'path';
But there is one more thing. It is not enough to solve this problem.
‘**dirname’ should return the path of the folder, so we need to declare ‘**filename’ as well.
So I fixed the code like this.
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const app = express();
app.set('view engine', 'pug');
app.set('views', __dirname + '/views');
app.use('/public', express.static(__dirname + '/public'));
app.get('/', (req, res) => res.render('home'));
const handleListen = () => console.log(`Listening on http://localhost:3000`);
app.listen(3000, handleListen);
-
url.fileURLToPath(url) This function ensures the correct decodings of percent-encoded characters as well as ensuring a cross-platform valid absolute path string.
import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); new URL('file:///C:/path/').pathname; // Incorrect: /C:/path/ fileURLToPath('file:///C:/path/'); // Correct: C:\path\ (Windows) new URL('file://nas/foo.txt').pathname; // Incorrect: /foo.txt fileURLToPath('file://nas/foo.txt'); // Correct: \\nas\foo.txt (Windows) new URL('file:///你好.txt').pathname; // Incorrect: /%E4%BD%A0%E5%A5%BD.txt fileURLToPath('file:///你好.txt'); // Correct: /你好.txt (POSIX) new URL('file:///hello world').pathname; // Incorrect: /hello%20world fileURLToPath('file:///hello world'); // Correct: /hello world (POSIX)
References
https://www.geeksforgeeks.org/difference-between-__dirname-and-in-node-js/