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

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


当前回答

已经有人提议通过导入公开这些变量。meta,但现在,你需要一个hack的工作,我在这里发现:

// expose.js
module.exports = {__dirname};

// use.mjs
import expose from './expose.js';
const {__dirname} = expose;

其他回答

已经有人提议通过导入公开这些变量。meta,但现在,你需要一个hack的工作,我在这里发现:

// expose.js
module.exports = {__dirname};

// use.mjs
import expose from './expose.js';
const {__dirname} = expose;

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

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

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

我使用:

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 ); })();

因为其他答案虽然有用,但没有涵盖跨平台情况(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)

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

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

使用——experimental-modules