düğüm __dirname tanımlanmadı


138

Düğüm kılavuzundan bir dosyanın dizinini alabileceğimi görüyorum __dirname, ancak REPL'den bu tanımsız görünüyor. Bu benim açımdan bir yanlış anlama mı yoksa hata nerede?

$ 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 kullanırken ben yanlışlıkla batmıştı, bu sorunu var "browser": trueyerine "node": truebenim .eslintrc.json dosyasında.
Toivo Säwén

Yanıtlar:


187

__dirnameyalnızca komut dosyalarında tanımlanır. REPL'de mevcut değildir.

bir senaryo yapmayı dene a.js

console.log(__dirname);

ve çalıştırın:

node a.js

__dirnamebasılı göreceksiniz .

Arka plan açıklaması eklendi: __dirname'Bu komut dosyasının dizini' anlamına gelir. REPL'de bir komut dosyanız yok. Dolayısıyla __dirnamegerçek bir anlamı olmayacaktı.


5
Ayrıca RequireJS modüllerinde bazı Global değişkenleri kullanamazsınız. RequireJS'yi sunucu tarafında kullanıyorsanız, stackoverflow.com/questions/9027429/… adresine bakın .
Eye

1
Evet, bu cevaba gerçekten eklenmeli Eye, çünkü beni anlayan bu.
Tomáš Zato - Monica'yı eski durumuna getir

3
Bunu REPL'nin kod dosyasına eklememek iğrençtir. Orada olmaması için herhangi bir sebep düşünemiyorum ...
jcollum

Kullanarak REPL'in içindeyken bir komut dosyası yükledim .load script.js. __Dirname'nin hala script.js içinden mevcut olmaması çok kötü
Kevin Wheeler

upvoted!
wtf'nin

96

Buradaki mevcut cevaplara dayanarak, bunu REPL'inizde tanımlayabilirsiniz:

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

Veya:

__dirname = path.resolve();

Hiçbir pathsegment geçilmezse, path.resolve()geçerli çalışma dizininin mutlak yolunu döndürür.


Veya @ Jthorpe'un alternatifleri:

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

kullanırsanız, neshbunu kod dosyanızın bir parçası olarak tanımlayabilirsiniz; o şık
jcollum

1
veya __dirname = process.cwd()veya __dirname=fs.realpathSync('.')veya__dirname = process.env.PWD
Jthorpe

1
path.dirnameen yeni ana sürümde artık dize olmayan değerleri kabul etmiyor gibi görünüyor 6.0.0, bu nedenle bu yanıttaki ilk öneri işe yaramayacak.
trysis

30

ES6 kullanımında:

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

düğüm ile çağrıldığında da kullanılabilir --experimental-modules


REPL'de çekirdek modülleri içe aktarmanıza gerek yoktur; onları sizin için anında yükleyecektir.
c24w

Bu, geçerli .jsdosyanın dizinini değil, geçerli çalışma dizinini verir .
Dirbaio

@Dirbaio, REPL'deyken mevcut .jsdosya ne olur ?
c24w

@ c24w az önce kontrol edildi, görünen o ki CWD
Dirbaio

@Dirbaio Sanırım benim amacım buydu. REPL'e girdiğinizde, geçerli JS dosyası yoktur. __dirnameCWD olmasa ne olmak isterdin ?
c24w

8

@Qiao'nun dediği gibi, __dirnamedüğüm replinde kullanamazsınız . Ancak konsolda bu değere ihtiyacınız varsa, path.resolve()veya kullanabilirsiniz path.dirname(). Yine path.dirname()de sana bir "." yani, muhtemelen o kadar da yararlı değil. Emin olun require('path').


5

Ben de kullanarak yoluma katılmaya çalışıyordum path.join(__dirname, 'access.log')ama aynı hatayı atıyordu.

İşte bunu nasıl düzelttim:

Önce yol paketini içe aktardım ve adlı bir değişken tanımladım __dirname, ardından resolve yol yöntemini çağırdım .

CommonJS'de

var path = require("path");

var __dirname = path.resolve();

ES6 + 'da

import path  from 'path';

const __dirname = path.resolve();

Mutlu kodlamalar .......


3

Bunu da yapabilirsin gibi görünüyor:

__dirname=fs.realpathSync('.');

tabiki unutma fs=require('fs')

(düğüm betiklerinde tam olarak küresel değildir, sadece modül seviyesinde tanımlanmıştır)


REPL'de çekirdek modüllere ihtiyaç duymanıza gerek yoktur; onları sizin için anında yükleyecektir.
c24w

2

Ben toplu SYSTEM kullanıcısı dosya ve benzeri tüm değişkenlerden bir komut dosyası koşuyordu process.cwd(), path.resolve()ve diğer tüm yöntemler C'ye bana yolunu verecekti: gerçek yolu yerine \ Windows \ System32 klasörüne. Deneyler sırasında, bir hata atıldığında yığının düğüm dosyasına giden gerçek bir yol içerdiğini fark ettim.

İşte bir hatayı tetikleyerek ve e.stack'ten yol çıkararak doğru yolu elde etmenin çok karmaşık bir yolu. Kullanmayın.

// 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;
  }
}

kullanım

const dir = veryHackyGetFolder();

Eğer repl ile bu çalışmıyorsa ediyorsanız yapabilirsiniz kullanmak __dirnameve __filename.
c24w

En azından doğru çözümü sağlamaya çalışan tek cevap budur.
Tomáš Zato - Monica'yı eski durumuna getir

@ c24w __dirname, __filename ve diğer her şeyi denedim. Benim durumumda hiçbir standart çözüm işe yaramadı. Github.com/DVLP/Unscheduler sıkıldıysanız işte görev zamanlayıcıdan SYSTEM olarak bir işlem çalıştıran projem. Aksi takdirde işe yarayan herhangi bir standart çözüm, yukarıdaki hack'imden açıkça daha iyidir :)
Pawel

1

Bu sorunun çözümü olmasa da, başkalarına yardımcı olabileceği için eklemek isterim.

Sen sahip olmalıdır iki çizgi dirname önce değil bir alt çizgi ( __dirnamedeğil_dirname ).

NodeJS Belgeleri


__dirname (iki alt çizgi ile) REPL'de çalışmıyor
Aaron J Spetner

1

Eğer amacımız node __dirname not definedile node --experimental-modules, bunu yapabilirsiniz:

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

Başka bir örnekte olduğu için, yalnızca geçerli / pwd diziniyle çalışın, başka bir dizinle değil.


1

Eğer kullanıyorsanız node.js modüllerini , __dirnameve__filename yoktur.

Gönderen node.js belgelerinde :

Gereksinim yok, ihracat, module.exports, __filename, __dirname

Bu CommonJS değişkenleri ES modüllerinde mevcut değildir.

requirekullanılarak bir ES modülüne aktarılabilir module.createRequire().

Eşdeğerler __filenameve __dirnameher dosyanın içinde şu yollarla oluşturulabilir 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

bazen .js uzantılı bir dosya oluşturup consol.log (_dirname) ekliyoruz; ancak hatalarla karşılaşıyoruz, acelemiz var, bu yüzden "dirname" den önce bir alt çizgi daha eklemeyi unutuyoruz, bu yüzden referans hatasıyla karşılaşıyoruz. doğru sözdizimi consol.log (__ dirname);

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.