Amy*_*eum 38 node.js ecmascript-6 es6-modules
我--experimental-modules在运行节点应用程序时使用该标志以使用ES6模块.
但是,当我使用此标志时,元变量__dirname不可用.是否有另一种方法可以获得__dirname与此模式兼容的相同字符串?
GOT*_*O 0 41
在Node.js 10中,有一种不需要创建多个文件的替代方案:
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
Run Code Online (Sandbox Code Playgroud)
rob*_*lep 19
有关于公开这些变量的建议import.meta,但是现在,你需要一个我在这里找到的hacky解决方法:
// expose.js
module.exports = {__dirname};
// use.mjs
import expose from './expose.js';
const {__dirname} = expose;
Run Code Online (Sandbox Code Playgroud)
Mik*_*ant 18
对于节点 10.12 +...
假设您正在从一个模块工作,这个解决方案应该可以工作,并且还为您提供 __filename 支持
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Run Code Online (Sandbox Code Playgroud)
好消息是,您离支持 CommonJS 模块的 require() 也只有两行代码了。为此,您将添加:
import { createRequireFromPath } from 'module';
const require = createRequireFromPath(__filename);
Run Code Online (Sandbox Code Playgroud)
Vac*_*tny 14
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;
Run Code Online (Sandbox Code Playgroud)
忘记join从当前文件创建路径,只需使用URL
const pathToAdjacentFooFile = new URL('./foo.txt', import.meta.url).pathname;
const pathToUpperBarFile = new URL('../bar.json', import.mera.url).pathname;
Run Code Online (Sandbox Code Playgroud)
Gui*_*nto 11
在大多数情况下,使用 Node.js 原生的东西(带有 ES 模块),而不是外部资源,在大多数情况下__filename__dirname,使用和完全没有必要。大多数(如果不是全部)用于读取(流)的本机方法都支持new URL+ import.meta.url,正如官方文档本身所建议的那样:
正如您在方法的描述中所见,该path参数显示了支持的格式,其中包括<URL>, 示例:
| 方法 | 路径参数支持 |
|---|---|
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());
Run Code Online (Sandbox Code Playgroud)
列出脚本目录中的所有文件:
import { readdirSync } from 'fs';
readdirSync(new URL('./', import.meta.url)).forEach((dirContent) => {
console.log(dirContent);
});
Run Code Online (Sandbox Code Playgroud)
注意:在示例中,我使用同步函数只是为了更容易复制和执行。
如果打算制作一个依赖第三方的“自己的日志”(或类似的东西),那么手动完成一些事情是值得的,但在语言和 Node.js 中这是没有必要的,ESMODULES完全有可能没有依赖于__filename两者之一__dirname,因为使用new URLwith 的本机资源已经解决了它。
请注意,如果您有兴趣在require战略时期使用类似的东西并且需要来自主脚本的绝对路径,您可以使用module.createRequire(filename)(仅限 Node.js v12.2.0 +)结合以import.meta.url在当前脚本级别以外的级别加载脚本,因为这已经有助于避免需要__dirname,使用import.meta.urlwith的示例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();
Run Code Online (Sandbox Code Playgroud)
来源foo-bar.js:
module.exports = () => {
console.log('hello world!');
};
Run Code Online (Sandbox Code Playgroud)
这类似于在没有“ECMAScript 模块”的情况下使用:
const fooBar = require('./foo-bar');
Run Code Online (Sandbox Code Playgroud)
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// do not use the following code which is bad for CJK characters
const __filename = new URL('', import.meta.url).pathname;
Run Code Online (Sandbox Code Playgroud)
小智 8
import.meta.dirname可以替代__dirname和
import.meta.filename可以替代__filename
const __dirname = import.meta.dirname;
const __filename = import.meta.filename;
Run Code Online (Sandbox Code Playgroud)
我制作了这个模块es-dirname,它将返回当前脚本目录名。
import dirname from 'es-dirname'
console.log(dirname())
Run Code Online (Sandbox Code Playgroud)
它适用于Windows和Linux上的CommonJs脚本和ES 模块。
如果脚本在我的项目中运行到目前为止出现错误,则在那里打开一个问题,但在其他一些情况下它可能会失败。因此不要在生产环境中使用它。这是一个临时解决方案,因为我相信 Node.js 团队将在不久的将来发布一种强大的方法来做到这一点。
由于其他答案虽然有用,但不涵盖跨平台情况(Windows POSIX)和/或除__dirnameor之外的路径解析__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')
Run Code Online (Sandbox Code Playgroud)
我刚刚发布了一个名为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)
Run Code Online (Sandbox Code Playgroud)
我用了:
import path from 'path';
const __dirname = path.resolve(path.dirname(decodeURI(new URL(import.meta.url).pathname)));
Run Code Online (Sandbox Code Playgroud)
decodeURI 很重要:测试系统路径中的已用空间和其他内容。
path.resolve() 处理相对网址。
小智 5
import path from 'path';
const __dirname = path.join(path.dirname(decodeURI(new URL(import.meta.url).pathname))).replace(/^\\([A-Z]:\\)/, "$1");
Run Code Online (Sandbox Code Playgroud)
此代码也适用于 Windows。(替换在其他平台上是安全的,因为path.join仅在 Windows 上返回反斜杠分隔符)
这有效:
import path from 'node:path';
import url from 'node:url';
const DIR_NAME = path.dirname(url.fileURLToPath(import.meta.url));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6592 次 |
| 最近记录: |