ノード__dirnameが定義されていません


137

ノードのマニュアルから、でファイルのディレクトリを取得できることがわかりました__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)


1
eslintを使用しているときにこの問題が発生しました。.eslintrc.jsonファイル"browser": trueで"node": trueはなく、誤って設定しました。
— ToivoSäwén

回答:


186

__dirnameスクリプトでのみ定義されます。REPLでは使用できません。

スクリプトを作ってみる a.js

console.log(__dirname);

そしてそれを実行します:

node a.js

あなたが表示されます__dirname印刷します。

背景説明を追加:__dirname「このスクリプトのディレクトリ」を意味します。REPLでは、スクリプトはありません。したがって、__dirname実際の意味はありません。


5
また、RequireJSモジュール内では一部のグローバル変数を使用できません。サーバー側でRequireJSを使用する場合は、stackoverflow.com / questions / 9027429 /…を参照してください。
— 2012年

1
ええ、それは本当に答えの目に追加する必要があります。
— トマーシュZato -復活モニカ

3
これをREPLのロードスクリプトに追加しないのは不愉快です。そこにない理由は何も考えられません...
— jcollum

REPL内でを使用してスクリプトファイルをロードしました.load script.js。__dirnameは、script.js内からはまだ使用できません
— Kevin Wheeler

賛成です!wtfが起こっているのではないかと思っていたので15分節約できました
— PirateApp

96

ここで既存の回答に基づいて、REPLでこれを定義できます。

__dirname = path.resolve(path.dirname(''));

または:

__dirname = path.resolve();

pathセグメントが渡されない場合path.resolve()は、現在の作業ディレクトリの絶対パスを返します。


または@Jthorpeの代替案:

__dirname = process.cwd();
__dirname = fs.realpathSync('.');
__dirname = process.env.PWD

使用するnesh場合は、これをロードスクリプトの一部として定義できます。気の利いた
— jcollum

1
または__dirname = process.cwd()または__dirname=fs.realpathSync('.')または__dirname = process.env.PWD
— Jthorpe

1
path.dirname最新のメジャーバージョンでは文字列以外の値を受け入れないようです6.0.0。そのため、この回答の最初の提案は機能しません。
— トリシス

30

ES6で使用:

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

ノードがで呼び出されたときにも利用可能 --experimental-modules


REPLにコアモジュールをインポートする必要はありません。それはあなたのためにそれらをその場でロードします。
— c24w

これは、現在の.jsファイルのディレクトリではなく、現在の作業ディレクトリを提供します。
— Dirbaio

@ Dirbaio、REPLにいるときの現在の.jsファイルは何ですか?
— c24w

@ c24wをチェックしたところ、CWD
— Dirbaio

@Dirbaioそれが私のポイントだったと思います。REPLを入力すると、現在のJSファイルはありません。__dirnameCWDでなければ、何になりたいですか?
— c24w

8

@qiaoが言ったよう__dirnameに、ノードrepl では使用できません。ただし、コンソールでこの値が必要な場合は、path.resolve()またはを使用できますpath.dirname()。ただし、path.dirname()"。"が表示されます。そのため、おそらくそれほど役に立ちません。必ずrequire('path')。


3

あなたもこれを行うことができるようです:

__dirname=fs.realpathSync('.');

もちろん、忘れないでください fs=require('fs')

(ノードスクリプトでは実際にはグローバルではなく、モジュールレベルで定義されているだけです)


REPLでコアモジュールを必要とする必要はありません。それはあなたのためにそれらをその場でロードします。
— c24w

2

私は、SYSTEMユーザーなど、すべての変数としてバッチファイルからスクリプトを実行していたprocess.cwd()、path.resolve()と他のすべてのメソッドは、Cに私にパスを与える:\ Windows \ System32フォルダの代わりに実際のパスで。実験中に、エラーがスローされると、スタックにノードファイルへの真のパスが含まれていることに気付きました。

これは、エラーをトリガーしてe.stackからパスを抽出することにより、真のパスを取得する非常にハックな方法です。使ってはいけません。

// this should be the name of currently executed file
const currentFilename = 'index.js';

function veryHackyGetFolder() {
  try {
    throw new Error();
  } catch(e) {
    const fullMsg = e.stack.toString();
    const beginning = fullMsg.indexOf('file:///') + 8;
    const end = fullMsg.indexOf('\/' + currentFilename);
    const dir = fullMsg.substr(beginning, end - beginning).replace(/\//g, '\\');
    return dir;
  }
}

使用法

const dir = veryHackyGetFolder();

REPLでこれを実行していない場合は、およびを使用できます。__dirname__filename
— c24w

これは、少なくとも正しい解決策を提供しようとする唯一の答えです。
— トマーシュZato -復活モニカ

@ c24w私は__dirname、__ filenameなどを試しました。私の場合、標準的な解決策はありませんでした。これは、github.com / DVLP / Unschedulerに退屈している場合に、タスクスケジューラからSYSTEMとしてプロセスを実行する私のプロジェクトです。他の方法で機能する標準的なソリューションは、上記の私のハックよりも明らかに優れています:)
— Pawel

2

私も使用して自分のパスに参加しようとしましpath.join(__dirname, 'access.log')たが、同じエラーがスローされていました。

修正方法は次のとおりです。

最初にパスパッケージをインポートし、という名前の変数を宣言してから__dirname、resolve パスメソッドを呼び出しました。

CommonJS内

var path = require("path");

var __dirname = path.resolve();

ES6以降

import path  from 'path';

const __dirname = path.resolve();

幸せなコーディング.......



1

あなたが得た場合node __dirname not definedにnode --experimental-modules、あなたが行うことができます。

const __dirname = path.dirname(import.meta.url)
                      .replace(/^file:\/\/\//, '') // can be usefull

この例では、他のディレクトリではなく、current / pwdディレクトリでのみ機能します。


1

Node.jsモジュールを使用している場合、__dirnameおよび__filename存在しません。

Node.jsのドキュメントから:

いいえ、exports、module.exports、__ filename、__ dirname

これらのCommonJS変数は、ESモジュールでは使用できません。

requireを使用してESモジュールにインポートできますmodule.createRequire()。

__filenameおよびの同等物は、__dirname各ファイルの内部で作成できますimport.meta.url。

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

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

https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname


0

.js拡張子の付いたファイルを作成し、consol.log(_dirname)を追加することもあります。エラーが発生し、急いでいるため、「dirname」の前にアンダースコアを1つ追加するのを忘れているため、参照エラーに直面しています。正しい構文はconsol.log(__ dirname);です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.