为了使用ES6模块,我在运行Node应用程序时使用了——experimental-modules标志。

然而,当我使用这个标志时,元变量__dirname不可用。是否有另一种方法来获得与此模式兼容的存储在__dirname中的相同字符串?


当前回答

正如Geoff指出的那样,下面的代码返回的不是模块的路径,而是工作目录。

import path from 'path';
const __dirname = path.resolve();

使用——experimental-modules

其他回答

Node.js 10.12有一个替代方案,不需要创建多个文件,并处理跨平台文件名中的特殊字符:

import { dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
process.cwd()

从文档:

process.cwd()方法返回 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); 

我还在NPM上发布了一个名为cross-dirname的包(从es-dirname派生而来)。该包使用Node.js (ESM和CJS), Deno和GJS进行测试。

例子:

import dirname from 'cross-dirname'

console.log(dirname())

因为其他答案虽然有用,但没有涵盖跨平台情况(Windows POSIX)和/或路径解析,而不是__dirname或__filename,在所有地方重复这种代码有点冗长:

import { dirname, join } from 'path'
import { fileURLToPath } from 'url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const somePath = join(__dirname, '../some-dir-or-some-file')

我刚刚发布了一个名为esm-path的NPM包来帮助完成这种循环任务,希望它也能对其他人有用。

它有文档记载,但在这里如何使用它:

import { getAbsolutePath } from 'esm-path'

const currentDirectoryPath = getAbsolutePath(import.meta.url)
console.log(currentDirectoryPath)

const parentDirectoryPath = getAbsolutePath(import.meta.url, '..')
console.log(parentDirectoryPath)

// Adapt the relative path to your case
const packageJsonFilePath = getAbsolutePath(import.meta.url, '../package.json')
console.log(packageJsonFilePath)

// Adapt the relative path to your case
const packageJsonFilePath = getAbsolutePath(import.meta.url, '..' , 'package.json')
console.log(packageJsonFilePath)