在大多数情况下,使用 Node.js 的原生内容(带有 ES 模块),而不是外部资源,在大多数情况下完全不需要使用 __filename 和 __dirname。大多数(如果不是全部)用于读取(流式传输)的本机方法支持 new URL + import.meta.url,正如官方文档本身所建议的那样:
正如您在方法的描述中看到的,path参数显示了支持的格式,其中包括<URL>,示例:
| Method |
path param supports |
fs.readFile(path[, options], callback) |
<string>, <Buffer>, <URL>, <integer>
|
fs.readFileSync(path[, options]) |
<string>, <Buffer>, <URL>, <integer>
|
fs.readdir(path[, options], callback) |
<string>, <Buffer>, <URL>
|
fs.readdirSync(path[, options]) |
<string>, <Buffer>, <URL>, <integer>
|
fsPromises.readdir(path[, options]) |
<string>, <Buffer>, <URL>
|
fsPromises.readFile(path[, options]) |
<string>, <Buffer>, <URL>, <FileHandle>
|
因此,new URL('<path or file>', import.meta.url) 可以解决,您无需处理字符串并创建稍后连接的变量。
示例:
了解如何在不需要__filename 或任何解决方法的情况下读取与脚本同一级别 的文件:
import { readFileSync } from 'fs';
const output = readFileSync(new URL('./foo.txt', import.meta.url));
console.log(output.toString());
列出脚本目录下的所有文件:
import { readdirSync } from 'fs';
readdirSync(new URL('./', import.meta.url)).forEach((dirContent) => {
console.log(dirContent);
});
注意:在示例中我使用同步函数只是为了更容易复制和执行。
如果打算创建一个依赖于第三方的“自己的日志”(或类似的东西),值得手动完成一些事情,但在语言和 Node.js 中,这不是必需的,@987654372 @ 完全有可能不依赖__filename 和__dirname,因为带有new URL 的原生资源已经解决了它。
请注意,如果您有兴趣在战略时刻使用 require 之类的东西并且需要主脚本的绝对路径,您可以使用 module.createRequire(filename)(仅限 Node.js v12.2.0 +)与 import.meta.url在当前脚本级别以外的级别加载脚本,因为这已经有助于避免需要__dirname,例如使用import.meta.url 和module.createRequire:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
// foo-bar.js is a CommonJS module.
const fooBar = require('./foo-bar');
fooBar();
来源foo-bar.js:
module.exports = () => {
console.log('hello world!');
};
这类似于使用没有“ECMAScript 模块”:
const fooBar = require('./foo-bar');