IT

*내 것이 아닌*요구를 통해 로드한 모듈의 경로를 얻으려면 어떻게 해야 합니까(예: 일부 node_module에서)

itgroup 2023. 9. 5. 20:08
반응형

*내 것이 아닌*요구를 통해 로드한 모듈의 경로를 얻으려면 어떻게 해야 합니까(예: 일부 node_module에서)

나는 npm을 통해 설치된 모듈이 필요합니다.해당 모듈에 종속된 .js 파일에 액세스하여 생성자 메서드를 하위 분류할 수 있습니다.모듈의 코드를 수정할 수 없으므로 __dirname을 추출할 장소가 없습니다.

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

~~~

모듈의 로드된 모듈 정보를 가져오는 것이 더욱 좋습니다.

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

내부 require() 시스템을 사용하여 모듈의 위치를 조회하지만 모듈을 로드하는 대신 확인된 파일 이름만 반환합니다.

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

require.message는 부분적인 답변입니다.허용된 답변은 많은 노드 모듈에서 사용할 수 있지만 모든 노드 모듈에서 사용할 수는 없습니다.

require.resolve("moduleName"), 합니다.main모의속에 package.json.

그럴 수도 있고 그럴 수도 있습니다.후자의 경우에는,path.dirname(require.resolve("moduleName"))원하지 않거나 예상하지 못한 디렉토리를 반환합니다.

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

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

만약 당신이 단지 모듈의 디렉토리를 원한다면 (아마도 당신은 많은 것을 만들 것입니다.path.join()호출), 그런 다음 문제를 해결합니다.package.json. - 항프젝트루있하어며합에니다야전어되달야상트의에로▁to합다▁which니▁pass▁always▁must 전달됩니다.path.dirname():

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

은 Node.과 Jason의 Node.js ESM이 되기 이었습니다.exports필드가 나왔습니다.

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

그 요령을 보여주는 패키지가 있습니다.

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

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

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

그것은 다음과 같은 것을 출력할 것입니다.

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

exports필드에 포함됩니다.

참고로,require.resolveCommonJS에 따라 모듈 식별자를 반환합니다.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 파일을 다시 만들고 문제를 해결했습니다.

참조: 확인된 파일 경로(노드)가져오는사용

다음은 플랫폼에 구애받지 않는 방법으로 모듈 디렉터리를 반환하는 솔루션입니다., "" "" "" "" "" "" "" "" "" ""로 ESM 으로 찾습니다."type": "module"은 를통설모를 통해 됩니다.npm link..

참고: 특정 모듈이 다른 위치에 대한 심볼 링크인 경우(예:npm link) 를fs.realpath대상 디렉터리의 위치를 가져오려면:

const moduleDir = getModuleDir('some-npm-module');
const theRealPath = fs.realpathSync(moduleDir);

ESM

import fs from 'fs';
import path from 'path';
import { createRequire } from 'module';

/**
 * Get's the file path to a module folder.
 * @param {string} moduleEntry 
 * @param {string} fromFile 
 */
const getModuleDir = (moduleEntry) => {
    const packageName = moduleEntry.includes('/') 
        ? moduleEntry.startsWith('@') 
            ? moduleEntry.split('/').slice(0, 2).join('/') 
            : moduleEntry.split('/')[0]
        : moduleEntry;
    const require = createRequire(import.meta.url);
    const lookupPaths = require.resolve.paths(moduleEntry).map((p) => path.join(p, packageName));
    return lookupPaths.find((p) => fs.existsSync(p)); 
};

커먼JS

const fs = require('fs');
const path = require('path');
const { createRequire } = require('module');

/**
 * Get's the file path to a module's folder.
 * @param {string} moduleEntry 
 * @param {string} fromFile 
 */
const getModuleDir = (moduleEntry, relativeToFile = __filename) => {
    const packageName = moduleEntry.includes('/') 
        ? moduleEntry.startsWith('@') 
            ? moduleEntry.split('/').slice(0, 2).join('/') 
            : moduleEntry.split('/')[0]
        : moduleEntry;
    const require = createRequire(relativeToFile);
    const lookupPaths = require.resolve.paths(moduleEntry).map((p) => path.join(p, packageName));
    return lookupPaths.find((p) => fs.existsSync(p)); 
}; 

어떤 모듈의 진입점 파일을 가져오는 것과 같은 당신의 요구를 올바르게 이해하기를 바랍니다.예를 들어, 다음의 진입점을 얻고 싶다고 가정해 보겠습니다.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 에서 찾았습니다.

@anatory 솔루션에 따르면 MacOS X에서 검색 경로는 다음과 같습니다.

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

etvoila, 즉 프로젝트 루트 폴더 외부에 있는 것으로 나타났습니다.

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

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

아무도 지시하지 않았다고 주장할 수 있습니다.npm실행되어야 하는 프로젝트 루트 폴더 또는 기본 모듈 검색 경로가 아닌 다른 곳에서 내 컴퓨터를 검색합니다.

이것이 당신이 찾고 있는 것일 수도 있습니다. 확인해 보십시오.

required.main.main.message

이 코드는 저에게 적합합니다.

먼저 모듈 기본 파일 경로를 가져옵니다.

const mainDir = require.resolve(moduleName);

다음 출력:D:\app\node_modules\tincolor2\cjs\tincolor.js

그런 다음 패키지 dir를 가져옵니다.

const realDir = mainDir.substring(0,mainDir.indexOf(moduleName)+moduleName.length);

출력: D:\app\node_modules\tincolor2

언급URL : https://stackoverflow.com/questions/10111163/how-can-i-get-the-path-of-a-module-i-have-loaded-via-require-that-is-not-mine

반응형