node.JS에서 내가로드 한 모듈의 경로를 어떻게 얻을 수 있습니까? (예 : 일부 node_module에서)


94

npm을 통해 설치된 모듈이 필요합니다. 해당 모듈에 종속 된 .js 파일에 액세스하고 싶습니다 (그래서 생성자 메서드를 하위 클래스로 만들 수 있습니다). 모듈의 코드를 수정할 수 없으므로 (글쎄요, 원하지 않습니다) __dirname을 추출 할 장소가 없습니다.

다음 질문을 알고 있지만 코드 제어 권한이있는 모듈의 경로를 얻는 것입니다 (따라서 __dirname이 해결책입니다). Node.js에서`this` 모듈의 경로를 어떻게 알 수 있습니까?

~~~

모듈의로드 된 모듈 정보를 얻는 것이 더 좋습니다.


require ( 'modulename')로 오류없이 모듈을로드 할 수있는 곳은 어디입니까?
— Futur 2011-04-11

더 잘 설명 할 수 있습니까? 일부 코드?
— Gabriel Llamas

답변:


130

질문을 올바르게 이해했다면 require.resolve () 를 사용해야합니다 .

내부 require () 기계를 사용하여 모듈의 위치를 ​​찾되 모듈을로드하는 대신 확인 된 파일 이름을 반환하십시오.

예: var pathToModule = require.resolve('module');


13
이 답변은 모든 노드 모듈에서 안정적으로 작동하지 않습니다. 내 대답을 참조하십시오.
— 제이슨

61

require.resolve () 는 부분적인 대답입니다. 허용되는 답변은 많은 노드 모듈에서 작동 할 수 있지만 모든 모듈에서 작동하지는 않습니다.

require.resolve("moduleName")모듈이 설치된 디렉토리를 제공하지 않습니다. main모듈의 속성에 정의 된 파일의 위치를 ​​제공합니다 package.json.

그럴 수도 있고 moduleName/index.js그럴 수도 있습니다 moduleName/lib/moduleName.js. 후자의 경우 path.dirname(require.resolve("moduleName"))원하지 않거나 기대하지 않는 디렉토리를 반환합니다.node_modules/moduleName/lib

특정 모듈에 대한 전체 경로를 가져 오는 올바른 방법은 파일 이름을 확인하는 것입니다.

let readmePath = require.resolve("moduleName/README.md");

모듈에 대한 디렉토리를 원하면 (많은 path.join()호출을 할 수도 있음)을 해결하고 ( package.json항상 프로젝트의 루트에 있어야 함 ) 다음으로 전달하십시오 path.dirname().

let packagePath = path.dirname(require.resolve("moduleName/package.json"));

1
package.json파일 을 감지하여 매우 영리한 답변 입니다. path.join('moduleName', 'package.json')Windows 호환을 위해 사용하지 않아야 합니까?
— João Pimentel Ferreira

2
@ JoãoPimentelFerreira는 require.resolve것처럼, 플랫폼 불가지론 require이 사용하는 데 필요한되지 않도록path.join
— Gopikrishna S

1
const path = require('path');사용하기 전에 추가하는 것을 잊지 마십시오 path.dirname.
— GOTO 0

이 대답이 완전히 사실 이었으면합니다! 나는 같은 require.resolve('@scope/module')것을주는 것과 같은 것을 성공적으로 해결할 수 /path/to/@scope/module/dist/index.js있지만 실행하려고 require.resolve('@scope/module/package.json')하면 MODULE_NOT_FOUND오류가 발생합니다. 저는 Node 14.4.0에 있으며 해결하려는 모듈은 .NET Framework를 포함하지 않는 필드가 "type": "module"있는 package.json에 exports있습니다 package.json. 그것과 관련이 있는지 확실하지 않습니다 ...
— trusktr

나는 문제를 발견했다 : 모듈 이을 가지고있을 때 type: module, 분명히 필드에 package.json명시 적으로 노출되어야한다 exports. Node의 새로운 ESM 기능이 require평소처럼 경로를 해결하는 것을 차단하지 않는다고 생각 했지만 분명히 그렇습니다.
— trusktr

3

참고 require.resolve로 CommonJS에 따라 모듈 식별자를 반환합니다. node.js에서 이것은 파일 이름입니다. 에서 웹팩 이 숫자입니다.

에서 웹팩 상황, 여기에 모듈 경로를 알아 내 솔루션입니다 :

const pathToModule = require.resolve('module/to/require');
console.log('pathToModule is', pathToModule); // a number, eg. 8
console.log('__webpack_modules__[pathToModule] is', __webpack_modules__[pathToModule]);

그런 다음 다음 __webpack_modules__[pathToModule]과 같은 정보를 얻었습니다.

(function(module, exports, __webpack_require__) {

    eval("module.exports = (__webpack_require__(6))(85);\n\n//////////////////\n// 
    WEBPACK FOOTER\n// delegated ./node_modules/echarts/lib/echarts.js from dll-reference vendor_da75d351571a5de37e2e\n// module id = 8\n// module chunks = 0\n\n//# sourceURL=webpack:///delegated_./node_modules/echarts/lib/echarts.js_from_dll-reference_vendor_da75d351571a5de37e2e?");

    /***/
})

더 빠른 빌드 속도를 위해 이전 dll 빌드 파일의 이전 스크립트가 필요하여 업데이트 된 모듈 파일이 예상대로 작동하지 않는 것으로 나타났습니다. 마지막으로 dll 파일을 다시 작성하고 문제를 해결했습니다.

참조 : 해결 된 파일 경로 (노드)를 가져 오는 데 사용require.resolve


2

나는 당신의 요구를 올바르게 이해하기를 바랍니다 : 일부 모듈의 진입 점 파일을 얻으려면. jugglingdb모듈의 진입 점을 얻고 싶다고 가정 해 보겠습니다 .

node
> require('module')._resolveFilename('jugglingdb')
'/usr/local/lib/node_modules/jugglingdb/index.js'

보시다시피 이것은 모듈에 대한 이러한 종류의 정보를 얻는 "공식적인"방법이 아니므로이 함수의 동작은 버전마다 다를 수 있습니다. 노드 소스에서 찾았습니다 : https://github.com/joyent/node/blob/master/lib/module.js#L280


2

@anatoliy 솔루션에 따르면 MacOS XI에서 조회 경로가

require('module')._resolveLookupPaths('myModule')

그래서 해결 된 조회 경로를 얻습니다.

[ 'myModule',
  [ '/Users/admin/.node_modules',
    '/Users/admin/.node_libraries',
    '/usr/local/lib/node' ] ]

반면

require('module')._resolveFilename('myModule')

어쨌든 내가 찾고 있던 모듈을 해결하지 못할 것입니다. 사실 미친 것은 _load모듈이 해결되지 않는다는 것입니다 .

> require('module')._load('myModule')
Error: Cannot find module 'myModule'
    at Function.Module._resolveFilename (module.js:440:15)
    at Function.Module._load (module.js:388:25)
    at repl:1:19
    at sigintHandlersWrap (vm.js:32:31)
    at sigintHandlersWrap (vm.js:96:12)
    at ContextifyScript.Script.runInContext (vm.js:31:12)
    at REPLServer.defaultEval (repl.js:308:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:489:10)

(가) 동안 require것입니다 :

> require('myModule')

하지만이 모듈이 없습니다

myProject/node_modules/
myProject/node_modules/@scope/
/usr/local/lib/node_modules/
/usr/local/lib/node_modules/@scope
/usr/local/lib/node_modules/npm/node_modules/
/usr/local/lib/node_modules/npm/node_modules/@scope
$HOME/.npm/
$HOME/.npm/@scope/

그래서이 모듈은 어디에 있습니까 ???

우선은해야했다 $ sudo /usr/libexec/locate.updatedb 내가 한 커피 후 그런 locate myModule이상locate myModule/someFile.js

et voilà, 그것은 내 프로젝트의 상위 폴더, 즉 내 프로젝트 루트 폴더 외부에 있음을 알 수 있습니다.

$pwd
/Users/admin/Projects/Node/myProject
$ ls ../../node_modules/myModule/

그래서 당신은 피할 수없고 rm -rf ../../node_modules/myModule/신선한 npm install.

npm실행해야 할 프로젝트 루트 폴더 또는 기본 모듈 검색 경로가 아닌 다른 모듈을 검색 할 때 컴퓨터를 스캔 하도록 지시 한 사람은 아무도 없다고 주장 할 수 있습니다 .


1

이것은 아마도 당신이 찾고있는 것일 수 있습니다.

require.main.filename


1

Jason의 대답은 Node.js ESM과 exports필드가 나올 때까지 최고의 대답이었습니다 .

이제 Node는 패키지 작성자가 명시 적으로 노출하기로 결정하지 않는 exports한 기본적으로 같은 파일 package.json을 확인할 수 없도록 하는 필드가 있는 패키지를 지원하므로 명시 적으로 노출하지 않는 패키지에 대해서는 Jason의 답변 트릭이 실패합니다 package.json.

resolve-package-path트릭을 수행 하는 패키지가 있습니다 .

사용 방법은 다음과 같습니다.

const resolvePkg = require('resolve-package-path')

console.log(resolvePkg('@some/package'))

다음과 같이 출력됩니다.

/path/to/@some/package/package.json

패키지의 exports필드에 포함 된 내용에 관계없이 .


저자가 의도적으로 모듈 내용의 일부를 내 보내면 이제는 저자가 공식적으로 공개 인터페이스를 정의했기 때문에 훨씬 더 흔들 리게 될 것입니다. 제 생각에는 명시 적으로 내 보내지 않은 것들을 더 공격적으로 리팩토링하는 경향이 있다고 생각합니다.
— Jason

@Jason 소스 파일에 대해서는 사실이지만 package.json 파일은 사라지지 않습니다. 가져 오기에서 숨겨야하는 이유가 보이지 않습니다.
— trusktr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.