process.cwd()
실행중인 node.js 프로세스의 루트 디렉토리를 결정하는 것보다 더 좋은 방법이 있습니까? Rails.root
Node.js 와 같은 것과 비슷합니다 . 가능한 한 예측 가능하고 신뢰할 수있는 것을 찾고 있습니다.
답변
이것에 접근하는 몇 가지 방법이 있으며, 각각 고유 한 장단점이 있습니다.
require.main.filename
에서 http://nodejs.org/api/modules.html :
파일이 Node에서 직접 실행될 때이로
require.main
설정됩니다module
. 즉, 테스트를 통해 파일이 직접 실행되었는지 확인할 수 있습니다.require.main === module
때문에
module
제공filename
속성 (정상적으로 당량__filename
), 현재 어플리케이션의 엔트리 포인트를 선택하여 얻을 수있다require.main.filename
.
따라서 앱의 기본 디렉토리를 원하면 다음을 수행 할 수 있습니다.
var path = require('path');
var appDir = path.dirname(require.main.filename);
찬반 양론
대부분의 경우 잘 작동하지만 pm2 와 같은 실행기로 앱을 실행하거나 mocha 테스트를 실행 하면이 방법이 실패합니다.
global.X
Node에는 전역 네임 스페이스 global
객체가 있습니다.이 객체에 첨부하는 모든 것은 앱의 모든 곳에서 사용할 수 있습니다. 따라서 index.js
(또는 app.js
기본 앱 파일 이름에 관계없이) 전역 변수를 정의하면됩니다.
// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);
// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');
찬반 양론
일관되게 작동하지만 전역 변수에 의존해야하므로 구성 요소 등을 쉽게 재사용 할 수 없습니다.
process.cwd ()
현재 작업 디렉토리를 반환합니다. 이 프로세스가 시작되었다 어떤 디렉토리에 전적으로 의존하는 것에 따라, 전혀하지 신뢰성 에서 :
$ cd /home/demo/
$ mkdir subdir
$ echo "console.log(process.cwd());" > subdir/demo.js
$ node subdir/demo.js
/home/demo
$ cd subdir
$ node demo.js
/home/demo/subdir
앱 루트 경로
이 문제를 해결하기 위해 app-root-path 라는 노드 모듈을 만들었습니다 . 사용법은 간단합니다.
var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');
응용 프로그램 루트 경로 모듈은 앱에서 실행중인 경우 (예를 들어, 계정으로 전 세계적으로 설치된 모듈을 복용, 응용 프로그램의 루트 경로를 결정하기 위해 여러 가지 기술을 사용 /var/www/
하지만 모듈이 설치되어~/.nvm/v0.x.x/lib/node/
). 100 % 작동하지는 않지만 가장 일반적인 시나리오에서는 작동합니다.
찬반 양론
대부분의 환경에서 구성없이 작동합니다. 또한 편리한 추가 편리한 방법을 제공합니다 (프로젝트 페이지 참조). 가장 큰 단점은 다음과 같은 경우 작동하지 않는다는 것입니다.
- pm2와 같은 실행기를 사용하고 있습니다.
- AND , 모듈이 앱의
node_modules
디렉토리에 설치되지 않은 경우 (예 : 전역으로 설치 한 경우)
APP_ROOT_PATH
환경 변수 를 설정 하거나 .setPath()
모듈 을 호출 하여이 문제를 해결할 수 있지만이 경우 global
메소드를 사용하는 것이 좋습니다 .
NODE_PATH 환경 변수
현재 앱의 루트 경로 를 결정 하는 방법을 찾고 있다면 위의 솔루션 중 하나가 가장 적합 할 것입니다. 반면에 앱 모듈을 안정적으로로드하는 문제를 해결하려는 경우 NODE_PATH
환경 변수를 조사하는 것이 좋습니다 .
노드 모듈 시스템 은 다양한 위치에서 모듈을 찾습니다. 이 위치 중 하나는 어디든지 process.env.NODE_PATH
포인트 입니다. 이 환경 변수를 설정하면 require
다른 변경없이 표준 모듈 로더가있는 모듈 을 사용할 수 있습니다 .
예를 들어, 설정하면 NODE_PATH
할 수 /var/www/lib
는 다음과 같은 상황이 잘 작동합니다 :
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
이를 수행하는 가장 좋은 방법은 다음을 사용하는 것입니다 npm
.
"scripts": {
"start": "NODE_PATH=. node app.js"
}
이제 앱을 시작할 npm start
수 있으며 황금색입니다. 이것을 강제 노드 경로 모듈 과 결합하여 NODE_PATH
설정 하지 않고 실수로 앱을로드하지 못하게 합니다. 환경 변수 시행에 대한 더 많은 제어는 checkenv를 참조하십시오 .
하나의 문제 : 노드 앱 외부 에 설정 NODE_PATH
해야합니다 . 모듈 로더는 앱이 실행되기 전에 검색 할 디렉토리 목록을 캐시하기 때문에 이와 같은 작업을 수행 할 수 없습니다 .process.env.NODE_PATH = path.resolve(__dirname)
[add 4/6/16] 이 문제를 해결하려는 또 다른 유망한 모듈은 물결 모양 입니다.
답변
__dirname
글로벌이 아닙니다. 현재 모듈에 로컬이므로 각 파일마다 고유 한 로컬 값이 있습니다.
실행중인 프로세스의 루트 디렉토리를 원한다면을 사용하고 싶을 것입니다 process.cwd()
.
예측 가능성과 신뢰성을 원한다면 특정 환경 변수가 설정되어 있어야합니다. 귀하의 앱은 MY_APP_HOME
(또는 무엇이든) 찾아보고 거기에 있으면 응용 프로그램이 해당 디렉토리에 있으면 모든 것이 잘됩니다. 정의되지 않았거나 디렉토리에 응용 프로그램이 포함되어 있지 않으면 변수를 만들라는 오류 메시지와 함께 종료됩니다. 설치 프로세스의 일부로 설정할 수 있습니다.
노드에서 환경 변수를 다음과 같이 읽을 수 있습니다 process.env.MY_ENV_VARIABLE
.
답변
1- 프로젝트 루트에 파일을 만듭니다. settings.js
2-이 파일 안에이 코드를 추가하십시오
module.exports = {
POST_MAX_SIZE : 40 , //MB
UPLOAD_MAX_FILE_SIZE: 40, //MB
PROJECT_DIR : __dirname
};
3- 내부 node_modules는 “설정”이라는 새 모듈 이름을 만들고 모듈 index.js 안에 다음 코드를 작성합니다.
module.exports = require("../../settings");
4-프로젝트 디렉토리를 원할 때마다
var settings = require("settings");
settings.PROJECT_DIR;
이 방법 으로이 파일과 관련된 모든 프로젝트 디렉토리를 갖게됩니다.)
답변
글로벌 루트를 얻는 가장 쉬운 방법 ( NPM을 사용하여 node.js 앱 ‘npm start’등을 가정 할 때 )
var appRoot = process.env.PWD;
위의 내용을 교차 확인하려면
process.env.PWD
node.js 응용 프로그램의 설정 으로 교차 확인을 원한다고 가정 해보십시오. 의 런타임 유효성 검사를 위해 런타임 테스트를 원한다면 process.env.PWD
이 코드를 사용하여 교차 검사 할 수 있습니다 (필자는 잘 작동하는 것 같습니다). package.json 파일의 npm_package_name을 사용하여 appRoot의 마지막 폴더 이름을 교차 검사 할 수 있습니다. 예를 들면 다음과 같습니다.
var path = require('path');
var globalRoot = __dirname; //(you may have to do some substring processing if the first script you run is not in the project root, since __dirname refers to the directory that the file is in for which __dirname is called in.)
//compare the last directory in the globalRoot path to the name of the project in your package.json file
var folders = globalRoot.split(path.sep);
var packageName = folders[folders.length-1];
var pwd = process.env.PWD;
var npmPackageName = process.env.npm_package_name;
if(packageName !== npmPackageName){
throw new Error('Failed check for runtime string equality between globalRoot-bottommost directory and npm_package_name.');
}
if(globalRoot !== pwd){
throw new Error('Failed check for runtime string equality between globalRoot and process.env.PWD.');
}
: 당신은이 NPM 모듈을 사용할 수 있습니다 require('app-root-path')
이러한 목적을 위해 아주 잘 작동
답변
Mocha와 같은 일부 테스트 프레임 워크에서와 같이 하위 폴더에서 응용 프로그램을 호출 하더라도이 기능이 지속적으로 작동한다는 것을 알았습니다.
process.mainModule.paths[0].split('node_modules')[0].slice(0, -1);
작동하는 이유 :
런타임시 노드는로드 된 모든 파일의 전체 경로에 대한 레지스트리를 작성합니다. 모듈이 먼저로드되므로이 레지스트리의 맨 위에로드됩니다. 레지스트리의 첫 번째 요소를 선택하고 ‘node_modules’디렉토리 앞의 경로를 리턴하여 애플리케이션의 루트를 판별 할 수 있습니다.
그것은 단지 한 줄의 코드이지만, 편의상 (나를 위해) NPM 모듈에 블랙 박스로 넣었습니다.
https://www.npmjs.com/package/node-root.pddivine
즐겨!
답변
이러한 모든 “루트 디렉토리”는 대부분 실제 파일 경로에 대한 가상 경로를 해결해야하므로 살펴보아야 path.resolve
할까요?
var path= require('path');
var filePath = path.resolve('our/virtual/path.ext');
답변
이 줄을 루트로 모듈에 추가하는 것처럼 간단합니다. 일반적으로 app.js입니다.
global.__basedir = __dirname;
그러면 _basedir은 모든 모듈에 액세스 할 수 있습니다.