nó __dirname não definido


137

No manual do nó, vejo que consigo o diretório de um arquivo __dirname, mas no REPL isso parece indefinido. Isso é um mal-entendido do meu lado ou onde está o erro?

$ 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
Eu obtive esse problema ao usar o eslint, que havia definido por engano em "browser": truevez de "node": trueno meu arquivo .eslintrc.json.
Toivo Säwén 25/03

Respostas:


186

__dirnameé definido apenas em scripts. Não está disponível no REPL.

tente fazer um script a.js

console.log(__dirname);

e execute:

node a.js

você verá __dirnameimpresso.

Adicionada explicação em segundo plano: __dirnamesignifica 'O diretório deste script'. No REPL, você não tem um script. Portanto, __dirnamenão teria nenhum significado real.


5
Além disso, você não pode usar algumas das variáveis ​​globais nos módulos RequireJS. Se você usar o RequireJS no lado do servidor, consulte stackoverflow.com/questions/9027429/… .
do olho

1
Sim, isso realmente deve ser adicionado à resposta Eye, porque é isso que me pegou.
Tomáš Zato - Restabelece Monica

3
Não adicionar isso ao script de carregamento do REPL é desagradável. Eu não consigo pensar em qualquer razão que não seria lá ...
jcollum

Carreguei um arquivo de script enquanto estava dentro do REPL usando .load script.js. É muito ruim __dirname ainda não está disponível a partir de dentro script.js
Kevin Wheeler

votado! me salvou 15 minutos como eu estava me perguntando wtf está acontecendo
PirateApp

96

Com base nas respostas existentes aqui, você pode definir isso no seu REPL:

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

Ou:

__dirname = path.resolve();

Se nenhum pathsegmento for passado, path.resolve()retornará o caminho absoluto do diretório de trabalho atual.


Ou as alternativas de @ Jthorpe:

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

se você usar, neshpoderá definir isso como parte do seu script de carregamento; é bacana
jcollum 18/11/2015

1
ou __dirname = process.cwd()ou __dirname=fs.realpathSync('.')ou__dirname = process.env.PWD
Jthorpe 06/04

1
path.dirnameparece não aceitar mais valores que não sejam de seqüência de caracteres na versão principal mais recente 6.0.0, portanto a primeira sugestão nesta resposta não funcionará.
trysis

30

No ES6, use:

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

também disponível quando o nó é chamado com --experimental-modules


Você não precisa importar módulos principais no REPL; irá carregá-los rapidamente para você.
C24w 31/10/19

Isso fornece o diretório de trabalho atual, não o diretório do .jsarquivo atual .
Dirbaio

@Dirbaio, qual seria o arquivo atual.js quando você está no REPL?
c24w

@ c24w acabou de verificar, parece dar ao CWD
Dirbaio 03/02

@Dirbaio Acho que esse foi o meu ponto. Quando você digita o REPL, não há arquivo JS atual. O que você gostaria __dirnamede ser, se não o CWD?
c24w

8

Como @qiao disse, você não pode usar __dirnameo nó repl. No entanto, se você precisar desse valor no console, poderá usar path.resolve()ou path.dirname(). Embora, path.dirname()apenas lhe dê um "." então, provavelmente não é tão útil. Certifique-se de require('path').


3

Parece que você também pode fazer isso:

__dirname=fs.realpathSync('.');

claro, não esqueça fs=require('fs')

(não é exatamente global nos scripts dos nós, é apenas definido no nível do módulo)


Você não precisa exigir módulos principais no REPL; irá carregá-los rapidamente para você.
C24w 31/10/19

2

Eu estava executando um script a partir do arquivo em lotes como usuário do sistema e todas as variáveis ​​como process.cwd(), path.resolve()e todos os outros métodos me dariam o caminho para a pasta C: \ Windows \ System32 em vez do caminho real. Durante as experiências, notei que, quando um erro é gerado, a pilha contém um caminho verdadeiro para o arquivo do nó.

Aqui está uma maneira muito hacky de obter o caminho verdadeiro, disparando um erro e extraindo o caminho do e.stack. Não use.

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

Uso

const dir = veryHackyGetFolder();

Se você não estiver executando isso através do REPL, poderá usar __dirnamee __filename.
C24w

Esta é a única resposta que pelo menos tenta fornecer a solução correta.
Tomáš Zato - Restabelecer Monica

@ c24w Eu tentei __dirname, __filename e tudo mais. Nenhuma solução padrão funcionou no meu caso. Aqui está meu projeto que executa um processo como SYSTEM a partir do agendador de tarefas, se você está entediado github.com/DVLP/Unscheduler. Qualquer solução padrão que funcione é obviamente melhor do que o meu hack acima :)
Pawel

2

Eu também estava tentando entrar no meu caminho usando, path.join(__dirname, 'access.log')mas estava lançando o mesmo erro.

Aqui está como eu o consertei:

Primeiro importei o pacote de caminho e declarei uma variável chamada __dirname, depois chamei o método de resolve caminho .

Em CommonJS

var path = require("path");

var __dirname = path.resolve();

No ES6 +

import path  from 'path';

const __dirname = path.resolve();

Happy coding .......


1

Embora não seja a solução para esse problema, gostaria de adicioná-lo, pois pode ajudar outras pessoas.

Você deve ter dois sublinhados antes do dirname, não um sublinhado ( __dirnamenão _dirname).

Docs do NodeJS


__dirname (com dois sublinhados) não funciona no REPL
Aaron J Spetner

1

Se você tem node __dirname not definedcom node --experimental-modules, você pode fazer:

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

Como neste exemplo, trabalhe apenas com o diretório atual / pwd e não com outro diretório.


1

Se você estiver usando módulos Node.js , __dirnamee __filenamenão existem.

A partir da documentação Node.js :

Não é necessário, exportações, module.exports, __filename, __dirname

Essas variáveis ​​CommonJS não estão disponíveis nos módulos ES.

requirepode ser importado para um módulo ES usando module.createRequire().

Equivalentes __filenamee __dirnamepodem ser criados dentro de cada arquivo via 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

às vezes criamos um arquivo com extensão .js e adicionamos consol.log (_dirname); mas enfrentamos erros, estamos com pressa, então esquecemos de adicionar mais um sublinhado antes do "dirname" para enfrentar o erro de referência. a sintaxe correta é consol.log (__ dirname);

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.