Node.js를 사용하여 현재 스크립트의 경로를 얻으려면 어떻게해야합니까?


979

Node.js에서 스크립트 경로를 어떻게 알 수 있습니까?

이 있다는 것을 알고 process.cwd있지만 스크립트 자체가 아닌 스크립트가 호출 된 디렉토리 만 나타냅니다. 예를 들어 /home/kyle/내가 다음 명령을 실행 한다고 가정 해보십시오.

node /home/kyle/some/dir/file.js

내가 전화하면 process.cwd(), 내가 얻을 /home/kyle/하지 /home/kyle/some/dir/. 그 디렉토리를 얻는 방법이 있습니까?


6
nodejs.org/docs/latest/api/globals.html 허용 된 답변의 문서 링크.
allenhwkim

답변:


1393

설명서를 다시 살펴본 후 발견했습니다. 내가 찾고있는 것은 __filename__dirname모듈 수준 변수였습니다.

  • __filename현재 모듈의 파일 이름입니다. 현재 모듈 파일의 해결 된 절대 경로입니다. (예 : /home/kyle/some/dir/file.js)
  • __dirname현재 모듈의 디렉토리 이름입니다. (예 : /home/kyle/some/dir)

3
전체 경로가 아닌 디렉토리 이름 만 원하는 경우 다음과 같이 할 수 있습니다. function getCurrentDirectoryName () {var fullPath = __dirname; var path = fullPath.split ( '/'); var cwd = path [경로 길이 -1]; cwd를 반환; }
Anthony Martin

58
@AnthonyMartin __dirname.split ( "/"). pop ()
19 시간

6
@apx 솔루션을 시도하는 사람들에게는 (이와 같이) Windows 에서이 솔루션이 작동하지 않습니다.
Laoujin

36
또는 간단히__dirname.split(path.sep).pop()
Burgi

47
또는require('path').basename(__dirname);
Vyacheslav Cotruta

251

그래서 기본적으로 당신은 이것을 할 수 있습니다 :

fs.readFile(path.resolve(__dirname, 'settings.json'), 'UTF-8', callback);

'/'또는 '\'와 연결하는 대신 resolve ()를 사용하십시오. 그렇지 않으면 플랫폼 간 문제가 발생합니다.

참고 : __dirname은 모듈 또는 포함 된 스크립트의 로컬 경로입니다. 메인 스크립트의 경로를 알아야하는 플러그인을 작성하는 경우 다음과 같습니다.

require.main.filename

또는 폴더 이름을 얻으려면 다음을 수행하십시오.

require('path').dirname(require.main.filename)

16
목표가 json 파일을 구문 분석하고 상호 작용하는 것이라면 종종을 통해 더 쉽게 수행 할 수 있습니다 var settings = require('./settings.json'). 물론 그것은 동기식 fs IO이므로 런타임에는하지 말고 시작시에는 괜찮으며 일단로드되면 캐시됩니다.
isaacs

2
@ 마크 감사합니다! 잠시 동안 나는 __dirname이 각 모듈에 대해 로컬이라는 사실을 둘러 보았습니다. 내 라이브러리에 중첩 구조가 있으며 여러 곳에서 내 앱의 루트를 알아야합니다. 다행 지금은이 작업을 수행하는 방법을 알고 : D
티스 Koerselman

노드 V8 : path.dirname (process.mainModule.filename)
wayofthefuture

창을 실제 플랫폼으로 생각하지 않는다면 해결을 건너 뛸 수 있습니까? BSD, Macos, Linux, tizen, symbian, Solaris, android, flutter, webos는 모두 사용 / 맞습니까?
Ray Foss


118

이 명령은 현재 디렉토리를 반환합니다.

var currentPath = process.cwd();

예를 들어, 경로를 사용하여 파일을 읽으려면 다음을 수행하십시오.

var fs = require('fs');
fs.readFile(process.cwd() + "\\text.txt", function(err, data)
{
    if(err)
        console.log(err)
    else
        console.log(data.toString());
});

비동기식동기식을 이해하지 못한 사용자는 이 링크를 참조하십시오 ... stackoverflow.com/a/748235/5287072
DarckBlezzer

16
이것이 바로 OP가 원하지 않는 것입니다 ... 요청은 실행 스크립트 경로에 대한 것입니다!
caesarsol

3
현재 디렉토리는 매우 다릅니다. 와 같은 것을 실행하면 cd /foo; node bar/test.js현재 디렉토리는 /foo있지만 스크립트는에 있습니다 /foo/bar/test.js.
rjmunro

좋은 대답이 아닙니다. 논리 beacauese가 엉망입니다. 이것은 예상보다 훨씬 짧은 경로 일 수 있습니다.
kris_IV

왜 이렇게 하시겠습니까? 파일이 현재 디렉토리 text.txt와 관련 이 있고 읽을 수 있고 작동한다면 절대 경로를 구성 할 필요가 없습니다
Michael Mrozek

103

__dirname을 사용하십시오 !!

__dirname

현재 모듈의 디렉토리 이름. 이것은의 path.dirname ()과 동일합니다 __filename.

예 : / Users / mjr에서 example.js 노드 실행

console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr

https://nodejs.org/api/modules.html#modules_dirname

ESModules의 경우 다음을 사용하려고합니다. import.meta.url


1
이것은 심볼릭 링크에서도 살아남습니다. 따라서 저장소를 만들고 파일을 찾아야하는 경우 (예 : path.join (__ dirname, "../example.json"); 바이너리가 node_modules / .bin에 링크되어 있어도 여전히 작동합니다
Jason

2
이 답변은 몇 년 전에 제공되었을뿐만 아니라 더 이상 ES 모듈 에서도 작동하지 않습니다 .
Dan Dascalescu

48

기본 스크립트와 관련하여 다음과 같이 간단합니다.

process.argv[1]

로부터 Node.js를 문서 :

process.argv

명령 행 인수를 포함하는 배열입니다. 첫 번째 요소는 'node'이고 두 번째 요소는 JavaScript 파일의 경로 입니다. 다음 요소는 추가 명령 줄 인수입니다.

모듈 파일의 경로를 알아야하는 경우 __filename 을 사용 하십시오 .


3
downvoter가 이것이 권장되지 않는 이유를 설명해 주시겠습니까?
Tamlyn

1
@Tamlyn 어쩌면 실행중인 모듈 파일 process.argv[1]__filename가리키는 동안 주 스크립트에만 적용 되기 때문일 수 있습니다. 차이점을 강조하기 위해 답변을 업데이트합니다. 여전히을 사용하는 데 아무런 문제가 없습니다 process.argv[1]. 요구 사항에 따라 다릅니다.
Lukasz Wiktor

10
pm2 process.argv [1]과 같은 노드 프로세스 관리자로 기본 스크립트를 시작한 경우 프로세스 관리자의 실행 파일을 가리 킵니다. /usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js
user3002996

34

10 개 지원 Node.js를 ECMAScript를 모듈 , __dirname그리고 __filename더 이상 사용할 수 있습니다 .

그런 다음 현재 ES 모듈경로 를 얻으려면 다음을 사용해야합니다.

import { fileURLToPath } from 'url';

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

현재 모듈을 포함하는 디렉토리의 경우 :

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

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

ES 모듈을 작성 중인지 여부를 어떻게 알 수 있습니까? 실행중인 노드 버전 또는 가져 오기 / 내보내기 키워드를 사용중인 경우에만 문제가됩니까?
Ed Brannin 19

2
ES 모듈은 --experimental-modules플래그 와 함께 만 사용할 수 있습니다 .
Nickensoul

1
--experimental-modules는 노드 버전이 <13.2 인 경우에만 필요합니다. .js가 아닌 .mjs로 이름을 지정하십시오.
Brent


24

모든 Node.js 프로그램은 환경에 일부 전역 변수가 있으며 이는 프로세스에 대한 일부 정보를 나타냅니다 __dirname.


이 답변은 몇 년 전에 제공되었을뿐 아니라 __dirname 더 이상 ES 모듈과 함께 작동하지 않습니다 .
Dan Dascalescu

그것은 NodeJs (10)에 대해,하지만이 답변이 2016 년에 출판되었다
Hazarapet Tunanyan

알아. 기술 변경에 따라 답변을 업데이트 할 수 있습니다.
Dan Dascalescu 19

13

나는 이것이 꽤 오래되었다는 것을 알고 있으며, 내가 응답 한 원래 질문은 중복으로 표시되어 지시되었지만 재스민 기자가 일하게하고 다운 그레이드해야한다는 생각이 마음에 들지 않는 문제가 발생했습니다. 작동하도록 주문하십시오. jasmine-reporters가 savePath를 올바르게 해결하지 못하고 실제로 gulp를 실행 한 루트 디렉토리 대신 jasmine-reporters 디렉토리에 보고서 폴더 출력을 넣는 것을 알았습니다. 이 작업을 올바르게 수행하기 위해 process.env.INIT_CWD 를 사용하여 gulp 를 실행 한 디렉토리 인 초기 현재 작업 디렉토리를 얻었습니다. 이것이 누군가를 돕기를 바랍니다.

var reporters = require('jasmine-reporters');
var junitReporter = new reporters.JUnitXmlReporter({
  savePath: process.env.INIT_CWD + '/report/e2e/',
  consolidateAll: true,
  captureStdout: true
 });

8

process.env.PWD를 사용하여 현재 앱 폴더 경로를 가져올 수 있습니다.


2
OP는 요청 된 "스크립트 경로"를 요청합니다. Process Working Directory와 같은 PWD는 그렇지 않습니다. 또한 "현재 앱"문구가 잘못되었습니다.
dmcontador

7

pkg앱을 패키지화 하는 데 사용 하는 경우 다음 표현식이 유용합니다.

appDirectory = require('path').dirname(process.pkg ? process.execPath : (require.main ? require.main.filename : process.argv[0]));
  • process.pkg에 의해 앱이 패키지되었는지 여부를 알려줍니다 pkg.

  • process.execPath/usr/bin/node스크립트 ( node test.js) 또는 패키지 된 앱 을 직접 호출하기위한 실행 파일의 전체 경로를 보유합니다 .

  • require.main.filename 기본 스크립트의 전체 경로를 보유하지만 노드가 대화식 모드에서 실행될 때는 비어 있습니다.

  • __dirname현재 스크립트 의 전체 경로를 유지 하므로 사용하지 않습니다 (OP가 요구하는 것일 수도 있지만 appDirectory = process.pkg ? require('path').dirname(process.execPath) : (__dirname || require('path').dirname(process.argv[0]));대화 형 모드 __dirname에서 비어 있음을 알리는 것이 좋습니다 .

  • 대화식 모드의 process.argv[0]경우 노드 실행 파일의 경로 process.cwd()를 얻거나 현재 디렉토리를 가져 오려면 사용하십시오.


3

모듈 의 basename방법을 사용하십시오 path.

var path = require('path');
var filename = path.basename(__filename);
console.log(filename);

위의 예에서 가져온 문서는 다음과 같습니다 .

Dan이 지적했듯이 Node는 "--experimental-modules"플래그를 사용하여 ECMAScript 모듈 을 작업하고 있습니다. 노드 (12 개) 스틸 지원 __dirname__filename 상기와.


--experimental-modules플래그를 사용하는 경우 다른 방법이 있습니다.

대안은 현재 ES 모듈경로 를 얻는 것입니다 .

const __filename = new URL(import.meta.url).pathname;

현재 모듈을 포함하는 디렉토리의 경우 :

import path from 'path';

const __dirname = path.dirname(new URL(import.meta.url).pathname);

-2

쉘 스크립트에서 $ 0와 같은 것을 원하면 다음을 시도하십시오.

var path = require('path');

var command = getCurrentScriptPath();

console.log(`Usage: ${command} <foo> <bar>`);

function getCurrentScriptPath () {
    // Relative path from current working directory to the location of this script
    var pathToScript = path.relative(process.cwd(), __filename);

    // Check if current working dir is the same as the script
    if (process.cwd() === __dirname) {
        // E.g. "./foobar.js"
        return '.' + path.sep + pathToScript;
    } else {
        // E.g. "foo/bar/baz.js"
        return pathToScript;
    }
}

__dirname__filename없습니다 더 이상 ES 모듈을 사용할 .
Dan Dascalescu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.