programing

__dirname이(가) 노드 REPL에 정의되지 않은 이유는 무엇입니까?

testmans 2023. 5. 10. 20:30
반응형

__dirname이(가) 노드 REPL에 정의되지 않은 이유는 무엇입니까?

노드 매뉴얼에서 파일의 디렉터리를 가져올 수 있음을 알 수 있습니다.__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)

Node.js 모듈을 사용하는 경우__dirname그리고.__filename존재하지 않습니다.

Node.js 설명서에서 다음을 수행합니다.

필요 없음, 내보내기, module.exports, __filename, __dirname

이러한 공통 JS 변수는 ES 모듈에서 사용할 수 없습니다.

require를 사용하여 ES 모듈로 가져올 수 있습니다.

의 등가물__filename그리고.__dirname를 통해 각 파일 내부에 생성할 수 있습니다.

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

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

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

__dirname스크립트에서만 정의됩니다.REPL에서는 사용할 수 없습니다.

대본을 써 보다a.js

console.log(__dirname);

실행:

node a.js

알게 될 것입니다__dirname인쇄의

추가된 배경 설명:__dirname는 '이 스크립트의 디렉터리'를 의미합니다.REP에는 스크립트가 없습니다.이런 이유로,__dirname진정한 의미는 없을 겁니다

여기에 있는 기존 답변을 바탕으로 REPL에서 다음을 정의할 수 있습니다.

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

또는:

__dirname = path.resolve();

안되면path세그먼트가 통과되었습니다.path.resolve()현재 작업 디렉터리의 절대 경로를 반환합니다.


또는 @Jthorpe의 대안:

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

ES6에서는 다음을 사용합니다.

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

노드를 호출할 때도 사용할 수 있습니다.--experimental-modules

-> ES6 버전에서는 다음을 사용합니다.

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

-> 다음과 같이 사용합니다.

res.sendFile(path.join(__dirname ,'views','shop.html'))

저는 또한 제 길에 합류하려고 노력했습니다.path.join(__dirname, 'access.log')하지만 같은 실수를 하고 있었습니다.

수정 방법은 다음과 같습니다.

먼저 경로 패키지를 가져오고 이름이 지정된 변수를 선언했습니다.__dirname그 당시에 the라고 불렸습니다.resolve 경로 방법

공동으로제이에스

var path = require("path");

var __dirname = path.resolve();

ES6+에서

import path  from 'path';

const __dirname = path.resolve();

해피 코딩......

@qiao가 말했듯이, 당신은 사용할 수 없습니다.__dirname노드 복제본에 있습니다.그러나 콘솔에 이 값이 필요한 경우 다음을 사용할 수 있습니다.path.resolve()또는path.dirname().비록 ~일지라도,path.dirname()그냥 "."를 줄 테니, 아마 그렇게 도움이 되지 않을 겁니다.반드시 해라require('path').

만약 당신이node __dirname not defined와 함께node --experimental-modules할 수 있습니다.

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

다른 예제에서는 다른 디렉터리가 아닌 현재/pwd 디렉터리로만 작업합니다.

다음과 같은 작업도 수행할 수 있습니다.

__dirname=fs.realpathSync('.');

물론, 잊지 마세요.fs=require('fs')

(노드 스크립트에서는 정확하게 글로벌하지 않으며 모듈 레벨에서 정의된 것뿐입니다.)

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

비록 이것이 이 문제에 대한 해결책은 아니지만 다른 사람들에게 도움이 될 수도 있기 때문에 추가하고 싶습니다.

dirname 앞에는 하나의 밑줄이 아니라의 밑줄이 있어야 합니다.__dirname것은 아니다._dirname).

노드 JS 문서

이 방법은 해결 방법이지만 CommonJS 및 ESModules에서 모두 작동합니다.할 수 Node 금까지사수있에노JS.JS에서 ES 모듈로.저는 다른 방법을 찾지 못했습니다. import.meta.urlCommonJS에서 TypeScript 파일의 컴파일이 중지되므로 사용할 수 없습니다.

__slot.ts

import { fileURLToPath } from 'url'

export function get__filename() {
  const error = new Error()
  const stack = error.stack
  const match = stack.match(/^Error\s+at[^\r\n]+\s+at *(?:[^\r\n(]+\((.+?)(?::\d+:\d+)?\)|(.+?)(?::\d+:\d+)?) *([\r\n]|$)/)
  const filename = match[1] || match[2]
  if (filename.startsWith('file://')) {
    return fileURLToPath(filename)
  }
  return filename
}

코드.ts

if (typeof __filename === 'undefined') {
  global.__filename = get__filename()
  global.__dirname = path.dirname(__filename)
}

언급URL : https://stackoverflow.com/questions/8817423/why-is-dirname-not-defined-in-node-repl

반응형