为了使用ES6模块,我在运行Node应用程序时使用了——experimental-modules标志。
然而,当我使用这个标志时,元变量__dirname不可用。是否有另一种方法来获得与此模式兼容的存储在__dirname中的相同字符串?
为了使用ES6模块,我在运行Node应用程序时使用了——experimental-modules标志。
然而,当我使用这个标志时,元变量__dirname不可用。是否有另一种方法来获得与此模式兼容的存储在__dirname中的相同字符串?
当前回答
2021年最标准化的方式
import { URL } from 'url'; // in Browser, the URL in native accessible on window
const __filename = new URL('', import.meta.url).pathname;
// Will contain trailing slash
const __dirname = new URL('.', import.meta.url).pathname;
忘记使用join从当前文件创建路径,只使用URL
const pathToAdjacentFooFile = new URL('./foo.txt', import.meta.url).pathname;
const pathToUpperBarFile = new URL('../bar.json', import.meta.url).pathname;
其他回答
我创建了这个模块es-dirname,它将返回当前脚本dirname。
import dirname from 'es-dirname'
console.log(dirname())
它既适用于CommonJs脚本,也适用于Windows和Linux上的ES模块。
打开一个问题,如果有一个错误,因为脚本一直在我的项目中工作,但在其他一些情况下可能会失败。因此,不要在生产环境中使用它。这是一个临时的解决方案,我相信Node.js团队在不久的将来会发布一个健壮的方法来实现它。
节点10.12 +…
假设你正在从一个模块中工作,这个解决方案应该可以工作,并且还提供了__filename支持
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
好的事情是,你也只需要两行代码就可以支持CommonJS模块的require()。为此,你可以补充:
import { createRequireFromPath } from 'module';
const require = createRequireFromPath(__filename);
已经有人提议通过导入公开这些变量。meta,但现在,你需要一个hack的工作,我在这里发现:
// expose.js
module.exports = {__dirname};
// use.mjs
import expose from './expose.js';
const {__dirname} = expose;
process.cwd()
从文档:
process.cwd()方法返回 node . js的过程。
不管你是否同意使用global,我发现这是记忆和重构现有代码的最简单方法。
在代码执行的早期放置:
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
global.___filename = (path) => {
return fileURLToPath(path);
};
global.___dirname = (path) => {
return dirname(global.___filename(path));
};
然后在任何需要dirname或filename的文件中:
___filename(import.meta.url)
___dirname(import.meta.url)
当然,如果有宏,我就不需要传递import。meta了。Url,也许有改进。