Node.js 如何获取当前脚本的路径?
CommonJS 用 __filename 取当前脚本完整路径、__dirname 取所在目录;ES Module 里没有这两个变量,需用 import.meta.url + fileURLToPath 转换。本文给出两种模块体系的写法。
CommonJS:用 __filename(当前文件完整路径)和 __dirname(所在目录)。ES Module:用 import.meta.url 转换。
CommonJS(.cjs 或明确配置为 CommonJS)
console.log('__filename:', __filename); // /path/to/your/script.js
console.log('__dirname:', __dirname); // /path/to/your
典型用途——构造相对于脚本文件的路径,避免相对路径随启动目录漂移:
const path = require('path');
const configPath = path.join(__dirname, 'config.json'); // 永远指向脚本旁边的 config.json
ES Module(.mjs 或 type:module)
__dirname/__filename 在 ESM 里不存在,手写等价物:
import { fileURLToPath } from 'url';
import path from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
console.log(__dirname);
相关但不同的变量
| 变量 | 含义 |
|---|---|
__dirname |
当前模块文件所在目录 |
process.cwd() |
进程当前工作目录,可通过 process.chdir() 改变 |
import.meta.url |
ESM 中当前模块的 file:// URL |
require('./data.json') 里的相对路径基于模块位置;fs.readFile('./data.json') 里的相对路径基于 process.cwd()——这个差异是路径 bug 的高发区,文件操作建议统一用 path.join(__dirname, ...)。
常见问题(FAQ)
Q:打包(webpack/esbuild)后 __dirname 还准吗?
打包后文件结构改变,__dirname 指向 bundle 所在位置。需要访问的资源要么内联打包,要么用绝对路径/环境变量指定。
Q:__dirname 末尾带斜杠吗?
不带。拼接路径用 path.join(__dirname, 'x'),别手写斜杠(Windows 兼容性问题)。
Q:Docker 里 __dirname 是什么?
容器内脚本的真实路径(如 /app/src/index.js),与宿主机无关。挂载卷后按容器内路径理解即可。