모든 인증과 함께 사용할 환경 특정 구성을 설정하는 Node.js


117

node.js + express.js + everyauth.js를 사용하고 있습니다. 모든 everyauth 로직을 모듈 파일로 옮겼습니다.

var login = require('./lib/everyauthLogin');

이 내부에서 키 / 비밀 조합으로 내 oAuth 구성 파일을로드합니다.

var conf = require('./conf');
.....
twitter: {
    consumerKey: 'ABC', 
    consumerSecret: '123'
}

이러한 코드는 콜백이 다른 URL에 있으므로 개발 / 스테이징 / 프로덕션과 같이 환경에 따라 다릅니다.

Qu. 모든 모듈을 필터링하도록 환경 구성에서 어떻게 설정합니까? 아니면 모듈에 직접 경로를 전달할 수 있습니까?

환경에서 설정 :

app.configure('development', function(){
  app.set('configPath', './confLocal');
});

app.configure('production', function(){
  app.set('configPath', './confProduction');
});

var conf = require(app.get('configPath'));

통과

app.configure('production', function(){
  var login = require('./lib/everyauthLogin', {configPath: './confProduction'});
});

? 말이되는 희망


process.env.NODE_ENV를 평가하고 환경에 대한 올바른 개체를 반환 할 수있는 개체가 아닌 module = 함수를 사용하여 아래 아이디어 중 일부를 사용하는 솔루션을 찾았습니다. 조금 지저분하지만 작동합니다.
앤디 t

뻔뻔한 자기 홍보를 용서하지만, 별도의 파일과 명령 줄 스위치를 통해이를 수행하는 node.js 용 모듈을 작성했습니다. node-configure
Randolpho 2013

답변:


192

내 솔루션,

다음을 사용하여 앱로드

NODE_ENV=production node app.js

그런 다음 config.js객체가 아닌 함수로 설정

module.exports = function(){
    switch(process.env.NODE_ENV){
        case 'development':
            return {dev setting};

        case 'production':
            return {prod settings};

        default:
            return {error or other settings};
    }
};

그런 다음 Jans 솔루션에 따라 파일을로드하고 필요한 경우 값을 전달할 수있는 새 인스턴스를 만듭니다.이 경우 process.env.NODE_ENV에는 전역이므로 필요하지 않습니다.

var Config = require('./conf'),
    conf = new Config();

그런 다음 이전과 똑같이 구성 개체 속성에 액세스 할 수 있습니다.

conf.twitter.consumerKey

2
여기서 new를 사용하는 이유는 무엇입니까?
bluehallu

5
나는 두 번째 @bluehallu. 가 new필요?
성 조

2
Windows에서 동등한 것은 SET NODE_ENV = development
mujaffars

3
대신 new. 나는 다음에서 config.js....Config = function(){...}; module.exports = Config()
Atu

50 개의 웹 서버가있는 경우 수동으로 스크립트를 시작하기 위해 각 서버로 이동하기가 어려울 수 있습니다.
Rajesh

60

최상위 레벨로 NODE_ENV가있는 JSON 파일을 가질 수도 있습니다. IMO는 구성 설정을 표현하는 더 좋은 방법입니다 (설정을 반환하는 스크립트를 사용하는 것과 반대).

var config = require('./env.json')[process.env.NODE_ENV || 'development'];

env.json의 예 :

{
    "development": {
        "MONGO_URI": "mongodb://localhost/test",
        "MONGO_OPTIONS": { "db": { "safe": true } }
    },
    "production": {
        "MONGO_URI": "mongodb://localhost/production",
        "MONGO_OPTIONS": { "db": { "safe": true } }
    }
}

안녕하세요, 이것이 구성 설정을 표현하는 더 좋은 방법이라고 생각하는 이유를 설명해 주시겠습니까 (설정을 반환하는 스크립트를 사용하는 것과 반대). ?
Venkat Kotra 2014 년

14
그다지 큰 차이가없는 것 같아요. 정신적으로 JSON을 볼 때 '정적 데이터'와 JS 파일을 볼 때 생각하면 그 안에 논리가 있다고 생각합니다. 또한 .json 유형을 사용하는 또 다른 이점은 다른 언어가 동일한 파일을 가져올 수 있다는 것입니다.
mattwad 2014

1
@VenkatKotra 구성은 일반적으로 정적 인 것으로 간주되므로 json, yaml, ini 등과 같이 선언적으로 가장 잘 표현됩니다. 해당 상태를 생성하는 스크립트를 사용하여 명령 적으로 완료하면 sortof 는 동적 이 발생하고 있음을 암시합니다 .
최대

9
이 메서드는 소스 제어에서 자격 증명을 노출합니다.
Pier-Luc Gendreau

스테이징 및 프로덕션을위한 차등 URL을 만들 수 있습니까?
Alex

34

매우 유용한 솔루션은 config 모듈을 사용하는 것 입니다.

모듈 설치 후 :

$ npm install config

default.json 구성 파일을 만들 수 있습니다 . (확장자 .json5를 사용하여 JSON 또는 JS 객체를 사용할 수 있습니다)

예를 들면

$ vi config/default.json

{
  "name": "My App Name",
  "configPath": "/my/default/path",
  "port": 3000
}

이 기본 구성은 환경 구성 파일 또는 로컬 개발 환경의 로컬 구성 파일에 의해 재정의 될 수 있습니다.

production.json 은 다음과 같을 수 있습니다.

{
  "configPath": "/my/production/path",
  "port": 8080
}

development.json 은 다음과 같을 수 있습니다.

{
  "configPath": "/my/development/path",
  "port": 8081
}

로컬 PC에서 모든 환경을 재정의 하는 local.json 을 가질 수도 있고 특정 로컬 구성을 local-production.json 또는 local-development.json 으로 가질 수도 있습니다 .

로드 순서 의 전체 목록입니다 .

앱 내부

앱에서는 구성과 필요한 속성 만 필요합니다.

var conf = require('config'); // it loads the right file
var login = require('./lib/everyauthLogin', {configPath: conf.get('configPath'));

앱로드

다음을 사용하여 앱을로드합니다.

NODE_ENV=production node app.js

또는 forever 또는 pm2로 올바른 환경 설정

영원히:

NODE_ENV=production forever [flags] start app.js [app_flags]

PM2 (쉘을 통해) :

export NODE_ENV=staging
pm2 start app.js

PM2 (.json을 통해) :

process.json

{
   "apps" : [{
    "name": "My App",
    "script": "worker.js",
    "env": {
      "NODE_ENV": "development",
    },
    "env_production" : {
       "NODE_ENV": "production"
    }
  }]
}

그리고

$ pm2 start process.json --env production

이 솔루션은 매우 깨끗하며 프로덕션 / 스테이징 / 개발 환경 및 로컬 설정에 대해 서로 다른 구성 파일을 쉽게 설정할 수 있습니다.


npm install config --save, 더 좋지 않습니까?
stackdave

14

간단히

이러한 종류의 설정은 간단하고 우아합니다.

env.json

{
  "development": {
      "facebook_app_id": "facebook_dummy_dev_app_id",
      "facebook_app_secret": "facebook_dummy_dev_app_secret",
  }, 
  "production": {
      "facebook_app_id": "facebook_dummy_prod_app_id",
      "facebook_app_secret": "facebook_dummy_prod_app_secret",
  }
}

common.js

var env = require('env.json');

exports.config = function() {
  var node_env = process.env.NODE_ENV || 'development';
  return env[node_env];
};

app.js

var common = require('./routes/common')
var config = common.config();

var facebook_app_id = config.facebook_app_id;
// do something with facebook_app_id

프로덕션 모드에서 실행하려면 다음을 수행하십시오. $ NODE_ENV=production node app.js


상세히

이 솔루션은 http://himanshu.gilani.info/blog/2012/09/26/bootstraping-a-node-dot-js-app-for-dev-slash-prod-environment/ 에서 확인하십시오. 자세한 세부 사항.


5

이를 수행하는 방법은 환경으로 앱을 시작할 때 인수를 전달하는 것입니다. 예를 들면 :

node app.js -c dev

그런 다음 app.js에서 dev.js구성 파일 로로드 합니다. optparse-js를 사용 하여 이러한 옵션을 구문 분석 할 수 있습니다 .

이제이 구성 파일에 의존하는 몇 가지 핵심 모듈이 있습니다. 다음과 같이 작성할 때 :

var Workspace = module.exports = function(config) {
    if (config) {
         // do something;
    }
}

(function () {
    this.methodOnWorkspace = function () {

    };
}).call(Workspace.prototype);

그리고 다음과 app.js같이 호출 할 수 있습니다 .

var Workspace = require("workspace");
this.workspace = new Workspace(config);

차라리 모든 로직을 app.js app.configure('development코드 안에 보관하고 싶지만 이 솔루션을 사용할 수 있는지 살펴볼 것입니다
andy t

이 답변에 대한 업데이트 : Architect 는이를 더 좋은 방법으로 해결하는 종속성 관리 프레임 워크입니다.
Jan Jongboom 2013 년

5

우아한 방법은 .env파일 을 사용 하여 프로덕션 설정을 로컬로 재정의하는 것입니다. 명령 줄 스위치가 필요하지 않습니다. config.json파일 에있는 모든 쉼표와 대괄호는 필요하지 않습니다 . 여기에서 내 대답보기

예 : 내 컴퓨터에서 .env파일은 다음과 같습니다.

NODE_ENV=dev
TWITTER_AUTH_TOKEN=something-needed-for-api-calls

내 로컬 .env은 모든 환경 변수를 재정의합니다. 그러나 스테이징 또는 생산 서버에 변수가 무대에 미리 설정되어있는 환경 (어쩌면 그들은 heroku.com에있어) NODE_ENV=stage또는 생산 NODE_ENV=prod.


4

배포 서버에서 환경 변수를 설정합니다 (예 : NODE_ENV = production과 같음). process.env.NODE_ENV를 통해 환경 변수에 액세스 할 수 있습니다. 글로벌 설정에 대한 다음 구성 파일을 찾으십시오.

const env = process.env.NODE_ENV || "development"

const configs = {
    base: {
        env,
        host: '0.0.0.0',
        port: 3000,
        dbPort: 3306,
        secret: "secretKey for sessions",
        dialect: 'mysql',
        issuer : 'Mysoft corp',
        subject : 'some@user.com',
    },
    development: {
        port: 3000,
        dbUser: 'root',
        dbPassword: 'root',

    },
    smoke: {
        port: 3000,
        dbUser: 'root',
    },
    integration: {
        port: 3000,
        dbUser: 'root',
    },
    production: {
        port: 3000,
        dbUser: 'root',
    }
};

const config = Object.assign(configs.base, configs[env]);

module.exports= config;

base는 모든 환경에 대한 공통 구성을 포함합니다.

그런 다음 다른 모듈에서 가져옵니다.

const config =  require('path/to/config.js')
console.log(config.port)

해피 코딩 ...


3

nodejs-config 모듈 을 사용하여 훨씬 더 우아한 방식으로이 작업을 수행하는 것은 어떻습니까 ?

이 모듈은 컴퓨터 이름을 기반으로 구성 환경을 설정할 수 있습니다. 그 후 구성을 요청할 때 환경 별 값을 얻을 수 있습니다.

예를 들어 pc1과 pc2라는 두 개의 개발 시스템과 pc3라는 프로덕션 시스템이 있다고 가정 해 보겠습니다. pc1 또는 pc2의 코드에서 구성 값을 요청할 때마다 "개발"환경 구성을 가져와야하고 pc3에서 "생산"환경 구성을 가져와야합니다. 이것은 다음과 같이 얻을 수 있습니다.

  1. config 디렉토리에 기본 구성 파일을 만들고 "app.json"이라고 말하고 필요한 구성을 추가합니다.
  2. 이제 환경 이름 (이 경우 "development"및 "production")과 일치하는 config 디렉토리 내에 폴더를 작성하십시오.
  3. 다음으로, 재정의 할 구성 파일을 만들고 환경 디렉터리에서 각 환경에 대한 옵션을 지정합니다 (기본 구성 파일에있는 모든 옵션을 지정할 필요는 없지만 재정의하려는 옵션 만 지정할 수 있습니다. 환경 구성 파일은 기본 파일 위에 "캐스케이드"됩니다.).

이제 다음 구문으로 새 구성 인스턴스를 만듭니다.

var config = require('nodejs-config')(
   __dirname,  // an absolute path to your applications 'config' directory
   {
      development: ["pc1", "pc2"],
      production: ["pc3"],

   }
);

이제 다음과 같은 환경에 대해 걱정하지 않고 모든 구성 값을 얻을 수 있습니다.

config.get('app').configurationKey;

0

이 대답은 새로운 것이 아닙니다. @andy_t가 언급 한 것과 비슷합니다. 그러나 두 가지 이유로 아래 패턴을 사용합니다.

  1. 외부 npm 종속성이없는 깔끔한 구현

  2. 기본 구성 설정을 환경 기반 설정과 병합합니다.

자바 스크립트 구현

const settings = {
    _default: {
       timeout: 100
       baseUrl: "http://some.api/",
    },
    production: {
       baseUrl: "http://some.prod.api/",
    },
}
// If you are not using ECMAScript 2018 Standard
// https://stackoverflow.com/a/171256/1251350
module.exports = { ...settings._default, ...settings[process.env.NODE_ENV] }

나는 보통 내 노드 프로젝트에서 typescript를 사용합니다. 아래는 실제 구현을 복사하여 붙여 넣은 것입니다.

Typescript 구현

const settings: { default: ISettings, production: any } = {
    _default: {
        timeout: 100,
        baseUrl: "",
    },
    production: {
        baseUrl: "",
    },
}

export interface ISettings {
    baseUrl: string
}

export const config = ({ ...settings._default, ...settings[process.env.NODE_ENV] } as ISettings)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.