为了使用ES6模块,我在运行Node应用程序时使用了——experimental-modules标志。
然而,当我使用这个标志时,元变量__dirname不可用。是否有另一种方法来获得与此模式兼容的存储在__dirname中的相同字符串?
为了使用ES6模块,我在运行Node应用程序时使用了——experimental-modules标志。
然而,当我使用这个标志时,元变量__dirname不可用。是否有另一种方法来获得与此模式兼容的存储在__dirname中的相同字符串?
当前回答
我创建了这个模块es-dirname,它将返回当前脚本dirname。
import dirname from 'es-dirname'
console.log(dirname())
它既适用于CommonJs脚本,也适用于Windows和Linux上的ES模块。
打开一个问题,如果有一个错误,因为脚本一直在我的项目中工作,但在其他一些情况下可能会失败。因此,不要在生产环境中使用它。这是一个临时的解决方案,我相信Node.js团队在不久的将来会发布一个健壮的方法来实现它。
其他回答
我使用:
import path from 'path';
const __dirname = path.resolve(path.dirname(decodeURI(new URL(import.meta.url).pathname)));
decodeURI很重要:在我的测试系统的路径中使用空格和其他东西。
Path.resolve()处理相对url。
编辑:
修复支持windows (/C:/…= > C: /…):
import path from 'path';
const __dirname = (() => {let x = path.dirname(decodeURI(new URL(import.meta.url).pathname)); return path.resolve( (process.platform == "win32") ? x.substr(1) : x ); })();
我使用这个选项,因为路径以file://开始,只需删除该部分。
const __filename = import.meta.url.slice(7);
const __dirname = import.meta.url.slice(7, import.meta.url.lastIndexOf("/"));
另一个选择
import {createRequire} from 'module'; // need node v12.2.0
const require = createRequire(import.meta.url);
const __dirname = require.resolve.paths('.')[0];
只需使用path.resolve()方法即可。
import { resolve } from 'path';
app.use('/public/uploads', express.static(resolve('public', 'uploads')))
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;