最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

使用

旗下网站admin31浏览0评论

使用

使用

GOT*_*O 0 41

在Node.js 10中,有一种不需要创建多个文件的替代方案:

import { dirname } from 'path';import { fileURLToPath } from 'url';const __dirname = dirname(fileURLToPath(import.meta.url));

@DanDascalescu `__dirname` 不是进程目录路径,它是当前模块目录的路径。 (15认同) 这个解决方案相对于 [`path.dirname(process.argv[1])`](/sf/answers/3767888561/) 有什么优势? (3认同) 这对我在 Linux 下不起作用。还有其他人遇到过同样的问题吗? (3认同) 很酷,但是如何设置 WebStrom IDE 来理解这种语法? (2认同) 在 Windows 上(在其他平台上未经测试),此解决方案会导致路径中出现前导 `\` 字符,这会破坏很多东西。我可以对其进行修整以解决问题,但我不确定该解决方案是否跨平台兼容。 (2认同) 也许它不需要创建多个文件,但它确实需要在每个想要使用 __dirname 的模块中复制这三行代码。太丑了 `--experimental-modules`真的没有更好的解决方案吗? (2认同) 如果不喜欢不必要的依赖,也不关心像 Bob 这样的遗留操作系统... `import.meta.url.split('/').slice(2,-1).join('/') `。这不适用于处理 zip 文件等不受信任的内容......甚至不要尝试 (2认同)

rob*_*lep 19

有关于公开这些变量的建议import.meta,但是现在,你需要一个我在这里找到的hacky解决方法:

// expose.jsmodule.exports = {__dirname};// use.mjsimport expose from './expose.js';const {__dirname} = expose;

大括号步骤不是必需的,除此之外,真的不推荐使用这种方法,因为如果`./expose.js` 在另一个目录中,它将给出该目录的值`__dirname`,而不是当前脚本的值......请参阅我的回答 (2认同)

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

好消息是,您离支持 CommonJS 模块的 require() 也只有两行代码了。为此,您将添加:

import { createRequireFromPath } from 'module';const require = createRequireFromPath(__filename);

没有`createRequireFromPath` - 它是`createRequire`并以“import.meta.url”作为参数 (2认同)

Vac*_*tny 14

2021年最规范的方式

import { URL } from 'url'; // in Browser, the URL in native aessible on windowconst __filename = new URL('', import.meta.url).pathname;// Will contain trailing slashconst __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.mera.url).pathname;

在 Windows 中不起作用 - 导致类似“/C:/...”的结果 - 更好地使用 fileUrlToPath:nodejs./api/url.html#url_url_fileurltopath_url (25认同) 甚至不需要导入 `URL`,因为它[可作为全局使用](nodejs./api/url.html#class-url)。 (4认同)

Gui*_*nto 11

在大多数情况下,使用 Node.js 原生的东西(带有 ES 模块),而不是外部资源,在大多数情况下__filename__dirname,使用和完全没有必要。大多数(如果不是全部)用于读取(流)的本机方法都支持new URL+ import.meta.url,正如官方文档本身所建议的那样:

没有 __filename 或 __dirname没有 JSON 模块加载不 require.resolve

正如您在方法的描述中所见,该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());

列出脚本目录中的所有文件:

import { readdirSync } from 'fs';readdirSync(new URL('./', import.meta.url)).forEach((dirContent) => { console.log(dirContent);});

注意:在示例中,我使用同步函数只是为了更容易复制和执行。

如果打算制作一个依赖第三方的“自己的日志”(或类似的东西),那么手动完成一些事情是值得的,但在语言和 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();

来源foo-bar.js:

module.exports = () => { console.log('hello world!');};

这类似于在没有“ECMAScript 模块”的情况下使用:

const fooBar = require('./foo-bar');

这是这个帖子中对我来说最有价值的答案,谢谢! (2认同)

vde*_*nne 7

我制作了这个模块es-dirname,它将返回当前脚本目录名。

import dirname from 'es-dirname'console.log(dirname())

它适用于Windows和Linux上的CommonJs脚本和ES 模块。

如果脚本在我的项目中运行到目前为止出现错误,则在那里打开一个问题,但在其他一些情况下它可能会失败。因此不要在生产环境中使用它。这是一个临时解决方案,因为我相信 Node.js 团队将在不久的将来发布一种强大的方法来做到这一点。

Ban*_*cid 6

我用了:

import path from 'path';const __dirname = path.resolve(path.dirname(decodeURI(new URL(import.meta.url).pathname)));

decodeURI 很重要:测试系统路径中的已用空间和其他内容。

path.resolve() 处理相对网址。

per*_*507 6

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 charactersconst __filename = new URL('', import.meta.url).pathname;

小智 5

import path from 'path';const __dirname = path.join(path.dirname(decodeURI(new URL(import.meta.url).pathname))).replace(/^\\([A-Z]:\\)/, "$1");

此代码也适用于 Windows。(替换在其他平台上是安全的,因为path.join仅在 Windows 上返回反斜杠分隔符)

我为您的答案找到了一个简短的修复程序,可以在 Windows 上工作(确认工作):`[existing code].replace(/^\\([AZ]:\\)/, "$1");` 添加为编辑建议. (2认同)

发布评论

评论列表(0)

  1. 暂无评论