NodeJS는 글로벌 모듈 / 패키지를 필요로합니다


160

전 세계적으로 설치 한 다음 다음 foreverforever-monitor같이 사용하려고합니다 .

npm install -g forever forever-monitor

일반적인 출력과 파일을 전역 경로로 복사하는 작업도 보지만 시도 require("forever");하면 모듈을 찾을 수 없다는 오류가 발생합니다.

노드와 npm의 최신 버전을 사용하고 있으며 전역 및 로컬 설치에서 npm의 변경 사항에 대해 이미 알고 있지만 모든 프로젝트에 로컬을 설치하고 싶지 않으며 플랫폼이 아닌 플랫폼에서 작업하고 있습니다. 't 지원 link하므로 npm link설치 전역 후 나를 위해 할 수 없습니다.

내 질문은 : 전 세계적으로 설치된 패키지를 요구할 수없는 이유는 무엇입니까? 기능입니까, 버그입니까? 아니면 내가 잘못하고 있습니까?

추신 : 그냥 명확하게하기 위해 : 로컬로 설치하고 싶지 않습니다.




그것은 그래서 ~/.config/yarn/global원사
localhostdotdev

답변:


215

Node.js에서 require는 전역 모듈이 설치된 폴더를 찾지 않습니다.

NODE_PATH 환경 변수를 설정하여이 문제를 해결할 수 있습니다. 리눅스에서 이것은 :

export NODE_PATH=/usr/lib/node_modules

참고 : 이것은 전역 모듈이 실제로 설치된 위치에 따라 다릅니다.

전역 폴더에서로드를 참조하십시오 .


24
내 Ubuntu 13.10 시스템에서 모듈의 전역 경로는 여기에 표시된 것과 다릅니다. export NODE_PATH=/usr/local/lib/node_modules대신 사용해야 했습니다.
Drew Noakes

11
Windows 7/8을 사용 중이고 노드의 설치 기본값을 재정의하지 않은 경우 NODE_PATH환경 변수를 설정하면 C:\Users\{USERNAME}\AppData\Roaming\npm\node_modules작동합니다.
Wes Johnson

5
@WesJohnson Just %AppData%\npm\node_modules는 Windows 10에서 작동합니다.
theblang

6
설정 NODE_PATH하면 전역 및 로컬 모듈을 동시에 사용할 수 있습니까?
Paulo Oliveira

6
정적 경로 대신, 즉 NVM을 사용하는 경우 :NODE_PATH=$(npm root -g)
holmberd

97

전역으로 패키지를 설치 한 후에는 로컬 프로젝트를 전역 패키지와 연결해야합니다

npm install express -g
cd ~/mynodeproject/
npm link express  

여기를 참조 하십시오


2
링크를 지원하지 않는 플랫폼에서 실행 중입니다 (내 질문에 따르면) blog.nodejs.org/2011/04/06/npm-1-0-link
alexandernst

1
어떤 플랫폼을 사용하고 있습니까?
user568109

1
나는 정말로 링크 (또는 심볼릭 링크)를 엉망으로 만들고 싶지 않습니다. 패키지를 전체적으로 설치하고 필요합니다. 나는 이것을 피하기 위해 NPM이 재 설계되었다는 것을 알고 있지만, 이와 같은 것을 달성하기가 얼마나 어려울 수 있습니까?
alexandernst

13
프로젝트가 없으면 어떻게합니까? 말해봐 ~/some-stand-alone-random-nodejs-test.js. 홈 폴더를 프로젝트 디렉토리로 바꾸고 싶지 않습니다. 작은 실험마다 새 폴더를 만들고 싶지 않습니다.
AnnanFay

1
Windows 8.1에서 완벽하게 작동했습니다. 노드 명령 행 cd 에서 내 프로젝트의 로컬 node_modules 폴더로 실행 한 npm link <module>다음 전역 노드 모듈을 참조하는 프로젝트의 node_module 폴더 에 바로 가기 (링크)가 표시됩니다 .
dynamiclynk

26

네크로 맨시에 사과하지만 전 세계적으로 설치된 모듈에 대한 하드 코딩 된 경로를 지정할 수 있습니다.

var pg = require("/usr/local/lib/node_modules/pg");

이것은 완벽하지는 않지만 Unity3d가 프로젝트 디렉토리에 포함 된 모든 자바 스크립트를 "컴파일"하려고한다고 생각하면 실제로 패키지를 설치할 수 없습니다.


4
Unity3D는 JavaScript를 지원하지 않습니다. Boo 인터프리터 / 컴파일러 (Boo는 .NET 용 Python과 유사한 언어)에 대해 JS와 유사한 구문을 지원하며 "JavaScript"로 현혹됩니다 . Unity가 지원하는 언어에 대한보다 정확한 이름은 UnityScript 입니다. 동일한 언어에 가깝지 않기 때문에 웹 또는 Node.js 용으로 작성된 JS 중 어느 것도 Unity에서 작동하지 않습니다. 공식 Unity 위키의 차이점에 대한 더 많은 정보 : wiki.unity3d.com/index.php/UnityScript_versus_JavaScript
Slipp D. Thompson

19

나는 이것이 오래된 질문이라는 것을 알고 있지만 semverpreinstall스크립트에서 버전 확인을 시도 할 때이 문제가 발생 했습니다 package.json. 설치된 로컬 모듈에 의존 할 수 없다는 것을 알았으므로 semver전역 node_modules폴더 에서 요구하는 데 사용 npm했습니다 (내가 아는 것처럼).

function requireGlobal(packageName) {
  var childProcess = require('child_process');
  var path = require('path');
  var fs = require('fs');

  var globalNodeModules = childProcess.execSync('npm root -g').toString().trim();
  var packageDir = path.join(globalNodeModules, packageName);
  if (!fs.existsSync(packageDir))
    packageDir = path.join(globalNodeModules, 'npm/node_modules', packageName); //find package required by old npm

  if (!fs.existsSync(packageDir))
    throw new Error('Cannot find global module \'' + packageName + '\'');

  var packageMeta = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json')).toString());
  var main = path.join(packageDir, packageMeta.main);

  return require(main);
}

사용하기 위해 특별한 모듈을 설치할 필요가 없기 때문에이 방법이 마음에 듭니다.

프로젝트 NODE_PATH를 실행하기 전에 추가 구성 / 설정을 요구하지 않고 다른 사람의 컴퓨터 에서이 작업을 수행하기를 원했기 때문에 다른 사람들이 제안한 솔루션을 사용 하지 않았습니다 npm install.

이 코딩 방법, 단지 최상위 모듈 (사용하여 설치 찾을 보장 npm install -g ...) 또는에 필요한 모듈 npm(로 나열 dependencies: 여기 https://github.com/npm/npm/blob/master/package.json ). 최신 버전의 NPM을 사용하는 경우 node_modules폴더에 대한 구조가 더 평평하므로 전세계에 설치된 다른 패키지의 종속성을 찾을 수 있습니다.

이것이 누군가에게 유용하기를 바랍니다.


19

당으로 문서 , Node.js를 기본적으로 다음 위치에서 검색합니다 :

  1. NODE_PATH환경 변수에 지정된 경로 .

    참고 : NODE_PATH환경 변수는 콜론으로 구분 된 절대 경로 목록으로 설정됩니다.

  2. 현재 node_modules폴더. (현지)

  3. $HOME/.node_modules (글로벌)

    참고 : $HOME사용자의 홈 디렉토리입니다.

  4. $HOME/.node_libraries (글로벌)
  5. $PREFIX/lib/node (글로벌)

    참고 : $PREFIXNode.js가 구성되어 있습니다 node_prefix.

    의 현재 값을 확인하려면 node_prefix다음을 실행하십시오.

    node -p process.config.variables.node_prefix

    참고 : 접두사는 --prefix빌드 중 param에 해당하며에 상대적 process.execPath입니다. npm config get prefix명령의 값과 혼동하지 마십시오 . 출처

지정된 모듈을 찾을 수 없으면 위의 위치 중 하나에 해당 모듈이없는 것입니다.

모듈이 설치된 전역 루트 폴더의 위치는 다음과 같이 인쇄 할 수 있습니다 npm root -g(기본적으로 npmrc파일 에서 재정의되지 않는 한 경로는 런타임에 계산 됨 ).

해결책

다음 해결 방법을 시도 할 수 있습니다.

  • NODE_PATH환경 변수 에 글로벌 모듈 위치를 지정하십시오 . 예 :

    echo 'require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node

    의 값을 테스트하고 인쇄하려면 NODE_PATH다음을 실행하십시오.

    echo 'console.log(process.env.NODE_PATH); require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node 
  • 보다 영구적 인 솔루션을 얻으려면 $HOME/.node_modules다음 명령을 실행 하여 글로벌 사용자 폴더를 루트 폴더를 가리 키도록 연결하십시오 .

    ln -vs "$(npm root -g)" "$HOME"/.node_modules

    그런 다음 echo 'require("forever")' | node명령을 통해 다시 테스트하십시오 .

  • 스크립트를 호출하기 전에 현재 폴더를 확장 프로그램이 전역에 설치된 위치로 임시 변경하십시오. 예 :

    npm install -g forever
    cd "$(npm root -g)"
    echo 'require("forever")' | node
    cd -
  • npmuserconfig 파일 (: 참조 npm help 5 npmrc) 또는 userconfigparam ( --prefix)으로 글로벌 설치 대상을 구성 하십시오 .

    현재 구성을 표시하려면 다음을 실행하십시오 npm config list..

    현재 구성을 편집하려면 다음을 실행하십시오 npm config edit..

  • 호출 할 때 노드 모듈 위치 의 전체 경로를 지정하십시오 require(). 예 :

    require("/path/to/sub/module")
  • 사용자 정의 위치에 패키지를 설치하십시오 (예 :

    npm install forever -g --prefix "$HOME"/.node_modules

    그러나 설치는 아래로 진행 ~/.node_modules/lib/node_modules/되므로 위치를 추가해야합니다.

    참조 : npm 로컬 설치 패키지를 사용자 정의 위치로

  • 글로벌 패키지의 위치에서 현재 폴더에 심볼릭 링크만듭니다 . 예 :

    npm link forever

4. 현재 node_modules 폴더입니다. (로컬) 3. $보다 우선합니다 PREFIX / lib 디렉토리 / 노드 (전역)
랄리 이스트 반

로컬 node_modules 폴더는 항상 전역 폴더보다 우선합니다!
Király István

14

패키지 requireg를 사용 하여이 문제를 해결할 수 있습니다 .

var forever = require('requireg')('forever')

트릭을 할 것입니다.

또한 global-npmglobal을 사용하는 것과 관련된 다른 모듈이 npm있지만 짧은 코드 를보고 기술이 어떻게 작동하는지 확인할 수 있습니다.


흥미롭지 만 NODE_PATH 메소드는 아마도 더 정식 일 것입니다
Alexander Mills

의 아름다움은 NODE_PATH당신이 어떤 코드를 변경하지 않아도,도. (사용 사례는 많은 학생 프로젝트를 채점하고 npm install있으며 각 프로젝트 마다 실행 하고 싶지 않으며 node_modules디렉토리 를 제공하지 않기를 원합니다 ).
amenthes

아니요, requireg처음 에는 요구할 수 없기 때문에 요령이 아닙니다 . 이것이 요점입니다.
thisismydesign

6

와 같은 큰 모듈에 의존하는 CLI 유틸리티의 경우 puppeteera를 생성 npm root -g하고 전역 모듈이 필요합니다.

try {
  const root = require('child_process').execSync('npm root -g').toString().trim()
  var puppeteer = require(root + '/puppeteer')
} catch (err) {
  console.error(`Install puppeteer globally first with: npm install -g puppeteer`)
  process.exit(1)
}

3

이 줄을 .profile파일 에 넣을 수 있습니다 .

export NODE_PATH = "$ (npm config get prefix) / lib / node_modules"

이것은 만들 것이다 node글로벌 경로를 사용합니다.


1
아닙니다 node_modules. 이것은 전 세계를 얻는 일반적인 방법입니다 . 이것은 오래된 대답이지만 문서의 어딘가에서 얻은 것을 기억합니다. 어쨌든 내 컴퓨터 (2020 년)에서 전역 npm node_modules디렉토리는 usr/lib/node_modules입니다. 어쨌든, npm config get prefix글로벌 패키지가 설치 될 때마다 npm에서 전 세계적으로 사용되기 때문에 믿습니다 .
Luis Paulo

1
어느 쪽이든 (노드 .JS에서 경험이 많지 않았기 때문에 초기 답변에서 이것을 말하지 않았습니다), 프로그램에서 전역 적으로 설치된 패키지를 사용하는 것은 가장자리 사용 사례이며 프로젝트에서 생성되기 때문에 거의 수행하지 않아야합니다 프로젝트가 VCS에 커밋되고 package.json파일이나 yarn.lock/ 에없는 특정 종속성으로 인해 다른 환경에서 복제 될 때마다 문제가 발생합니다 package-lock.json.
Luis Paulo

1
오! 지금은 이해. PATH로 NODE_PATH를 착각하고 있다고 생각합니다. PATH는 쉘이 실행 파일을 찾는 곳입니다. NODE_PATH는 노드가 패키지를 찾는 곳입니다. node_modules폴더 의 현재 디렉토리를 살펴본 다음 시작하여 부모, 부모, ... node_modules가 해당 모듈을 포함 하는 폴더를 찾을 때까지 시작합니다 . 그러나 패키지를 전체적으로 설치하는 경우 패키지 node_modules는 스크립트의 현재 디렉토리 위의 폴더 안에 있지 않으므로 NODE_PATH를 노드가 패키지를 찾는 폴백으로 사용합니다.
Luis Paulo

1
ahahahah @Luis Paulo 당신은 완전히 맞아요! 죄송 해요! 혼란을 피하기 위해 내 의견 중 일부를 삭제하고 삭제하고, 감사합니다
Ryan Taylor

@Ryan Taylor 다른 사람이 동일한 의견을 가질 수 있으므로 의견과 질문이 해결되면 삭제해서는 안됩니다. 이제 의견에 독백이있는 것처럼 보입니다! ahahahah
루이스 파울로
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.