节点__dirname未定义

top*_*kip 108 node.js

从节点手册中我看到我可以获取文件的目录__dirname,但是从REPL看来这似乎是未定义的.这是我的误解还是错误在哪里?

$ node
> console.log(__dirname)
ReferenceError: __dirname is not defined
    at repl:1:14
    at REPLServer.eval (repl.js:80:21)
    at Interface.<anonymous> (repl.js:182:12)
    at Interface.emit (events.js:67:17)
    at Interface._onLine (readline.js:162:10)
    at Interface._line (readline.js:426:8)
    at Interface._ttyWrite (readline.js:603:14)
    at ReadStream.<anonymous> (readline.js:82:12)
    at ReadStream.emit (events.js:88:20)
    at ReadStream._emitKey (tty.js:320:10)
Run Code Online (Sandbox Code Playgroud)

qia*_*iao 164

__dirname仅在脚本中定义.它在REPL中不可用.

尝试制作一个剧本 a.js

console.log(__dirname);
Run Code Online (Sandbox Code Playgroud)

并运行它:

node a.js
Run Code Online (Sandbox Code Playgroud)

你会看到__dirname印刷的.

添加了背景说明:__dirname表示"此脚本的目录".在REPL中,您没有脚本.因此,__dirname没有任何实际意义.

  • 此外,您不能在RequireJS模块中使用某些全局变量.如果在服务器端使用RequireJS,请参阅http://stackoverflow.com/questions/9027429/how-to-use-nodejs-global-module-objects-in-requirejs-modules. (4认同)
  • 不将其添加到REPL的加载脚本中是令人讨厌的.我想不出有什么理由不会在那里...... (3认同)
  • 是的,这真的应该添加到答案 Eye 中,因为这就是我的原因。 (2认同)

AMS*_*777 89

如果您正在使用Node.js modules__dirname并且__filename不存在。

Node.js 文档

不需要,exports,module.exports,__filename,__dirname

这些 CommonJS 变量在 ES 模块中不可用。

require可以使用module.createRequire().

可以通过以下方式在每个文件中创建__filename和 的等效项:__dirnameimport.meta.url

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

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Run Code Online (Sandbox Code Playgroud)

https://nodejs.org/docs/latest-v15.x/api/esm.html#esm_no_filename_or_dirname

  • 从技术上讲,这是这里唯一正确的答案。所有其他解决方案都使用当前工作目录。这与 __dirname 功能不同,__dirname 功能实际上是保存当前运行脚本的文件夹。 (20认同)
  • 这是这个问题的完美答案。谢谢你,对我帮助很大!@RaviLuthra 100%正确。 (4认同)
  • 同意这是唯一正确的答案,“如果”问题与 ES6 模块类型的架构有关。导入语句需要引用最终传递到 __dirname 的路径,该功能实际上是保存当前运行脚本的文件夹。– (3认同)

c24*_*24w 74

基于现有答案,您可以在REPL中定义:

__dirname = path.resolve(path.dirname(''));
Run Code Online (Sandbox Code Playgroud)

要么:

__dirname = path.resolve();
Run Code Online (Sandbox Code Playgroud)

如果没有path传递段,path.resolve()将返回当前工作目录的绝对路径.


或@ Jthorpe的替代品:

__dirname = process.cwd();
__dirname = fs.realpathSync('.');
__dirname = process.env.PWD
Run Code Online (Sandbox Code Playgroud)

  • 或`__dirname = process.cwd()` 或`__dirname=fs.realpathSync('.')` 或`__dirname = process.env.PWD` (2认同)

jer*_*ink 7

正如@qiao所说,你不能__dirname在节点repl中使用.但是,如果您需要在控制台中使用此值,则可以使用path.resolve()path.dirname().虽然,path.dirname()只会给你一个"." 所以,可能没那么有用.一定要require('path').


Des*_*eba 7

我也试图加入我的路径,path.join(__dirname, 'access.log')但它抛出了同样的错误。

这是我修复它的方法:

我首先导入了路径包并声明了一个名为 的变量__dirname,然后调用了resolve 路径方法。

在 CommonJS 中

var path = require("path");

var __dirname = path.resolve();
Run Code Online (Sandbox Code Playgroud)

在 ES6+ 中

import path  from 'path';

const __dirname = path.resolve();
Run Code Online (Sandbox Code Playgroud)

快乐编码......


小智 6

在ES6中使用:

import path from 'path';
const __dirname = path.resolve();
Run Code Online (Sandbox Code Playgroud)

当使用调用节点时也可用 --experimental-modules

  • 这是错误的。`__dirname` 应该是当前模块目录,但您的解决方案使其成为当前工作目录。这个废话是怎么得到这么多点赞的,我无法理解。 (13认同)

小智 5

-> 在 ES6 版本使用:

import path from "path"
const __dirname = path.resolve();
Run Code Online (Sandbox Code Playgroud)

-> 像这样使用它,例如:

res.sendFile(path.join(__dirname ,'views','shop.html'))
Run Code Online (Sandbox Code Playgroud)

  • 这**不**相当于“__dirname”,而是相当于“process.cwd()”。例如,从不同的目录运行脚本时,您将得到不同的结果。使用 ESM 时,更好的方法是使用“import.meta.url”。请参阅 https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_import_meta 和 /sf/ask/3272151011/ -实验模块标志 (12认同)