programing

typescript에서 node-config를 사용하는 방법은 무엇입니까?

nicescript 2023. 6. 11. 21:56
반응형

typescript에서 node-config를 사용하는 방법은 무엇입니까?

설치 후node-config그리고.@types/config:

yarn add config
yarn add --dev @types/config

lorenwest/node-config에 설명된 대로 구성을 추가합니다.

// default.ts
export default {
  server: {
    port: 4000,
  },
  logLevel: 'error',
};

앱에서 사용하려고 할 때:

import config from 'config';

console.log(config.server);

오류가 발생했습니다.

src/app.ts(19,53): error TS2339: Property 'server' does not exist on type 'IConfig'.

저는 자바스크립트로 변수를 정의하고 타입스크립트로 접근하는 약간 다른 접근 방식을 취하고 있습니다.

다음 폴더 구조 사용:

├── config
│   ├── custom-environment-variables.js
│   ├── default.js
│   ├── development.js
│   └── production.js
└── server
    ├── config.ts
    └── main.ts

" 루에서구정니다합의"에서 구성을 합니다.config/폴더를 누릅니다.예:

// config/default.js
module.exports = {
  cache: false,
  port: undefined  // Setting to undefined ensures the environment config must define it
};

// config/development.js
module.exports = {
  port: '3000'
}

// config/production.js
module.exports = {
  cache: true
}

// config/custom-environment-variables.js
module.exports = {
  port: 'PORT'
}

하여 더 자동 완성 및하고, "TypeScriptland"에서 합니다.node-config맵에 :

// server/config.ts
import nodeConfig from 'config';

interface Config {
  /** Whether assets should be cached or not. */
  cache: boolean;

  /** The port that the express server should bind to. */
  port: string;
}

const config: Config = {
  cache: nodeConfig.get<boolean>('cache'),
  port: nodeConfig.get<string>('port')
};

export default config;

마지막으로 이제 TypeScript 코드 내의 구성 변수를 가져와서 사용할 수 있습니다.

// server/main.ts
import express from 'express';
import config from './config';

const { port } = config;

const app = express();

app.listen(port);

이 방법에는 다음과 같은 이점이 있습니다.

  • 는 양한기능사수있다습니용할다에서 이용할 수 있는 할 수 .node-config
  • TS 코드 내의 어디에서나 가져와 사용할 수 있는 강력한 유형의 문서화된 구성 맵이 있습니다.

config.get유틸리티를 사용하여 다음과 같은 구성 값을 가져올 수 있습니다.

import config from 'config';

const port: number = config.get('server.port');

"config에서 config를 가져오다" 대신 "import * as config from 'config';"를 사용합니다.

    import * as config from 'config';

    const port = config.get('server.port');
    console.log('port', port);
    // port 4000

config/development.json

    {
      "server": {
          "port": 4000
      }
    }

NODE_ENV= 개발 설정

 export NODE_ENV=development

참고: 기본값을 사용하는 경우 이 NODE_ENV 세트가 필요하지 않습니다.

이전부터, 저는 여전히 어려움을 겪고 있었습니다.config 수 .server에서 나온 열쇠.default.ts.

아래는 제가 npm 구성 모듈을 사용하는 방법입니다.업데이트됨export default {export =:

// default.ts
export = {
  server: {
    port: 4000,
  },
  logLevel: 'error',
};

앱 내 사용량 [동일]:

import config from 'config';

console.log(config.get('server'));

할 수 은 을 제거하는 것입니다.@types/config구성 파일을 포함하도록 형식 정의를 수정합니다.

config.d.ts

    declare module 'config' {
    
      // Importing my config files
      import dev from '#config/development.json'
      import test from '#config/test.json'
      import prod from '#config/production.json'
    
      // Creating a union of my config
      type Config = typeof dev | typeof test | typeof prod
    
      var c: c.IConfig;
    
      namespace c {
    
        // see https://github.com/lorenwest/node-config/wiki/Using-Config-Utilities
        interface IUtil {
            // Extend an object (and any object it contains) with one or more objects (and objects contained in them).
            extendDeep(mergeInto: any, mergeFrom: any, depth?: number): any;
    
            // Return a deep copy of the specified object.
            cloneDeep(copyFrom: any, depth?: number): any;
    
            // Return true if two objects have equal contents.
            equalsDeep(object1: any, object2: any, dept?: number): boolean;
    
            // Returns an object containing all elements that differ between two objects.
            diffDeep(object1: any, object2: any, depth?: number): any;
    
            // Make a javascript object property immutable (assuring it cannot be changed from the current value).
            makeImmutable(object: any, propertyName?: string, propertyValue?: string): any;
    
            // Make an object property hidden so it doesn't appear when enumerating elements of the object.
            makeHidden(object: any, propertyName: string, propertyValue?: string): any;
    
            // Get the current value of a config environment variable
            getEnv(varName: string): string;
    
            // Return the config for the project based on directory param if not directory then return default one (config).
            loadFileConfigs(configDir?: string): any;
    
            // Return the sources for the configurations
            getConfigSources(): IConfigSource[];
            
            // Returns a new deep copy of the current config object, or any part of the config if provided.
            toObject(config?: any): any;
    
            /**
             * This allows module developers to attach their configurations onto
             * the 6 years agoInitial 0.4 checkin default configuration object so
             * they can be configured by the consumers of the module.
             */
            setModuleDefaults(moduleName:string, defaults:any): any;
        }
    
        interface IConfig {
            // Changed the get method definition.
            get<K extends keyof Config>(setting: K): Config[K];
            has(setting: string): boolean;
            util: IUtil;
        }
    
        interface IConfigSource {
            name: string;
            original?: string;
            parsed: any;
        }
      }
    
      export = c;
    
    }

그러면 다음과 같은 작업을 수행할 수 있습니다.

여기에 이미지 설명 입력

대안 1

node-config-ts 사용

대안 2

는 node-config-ts를 사용할 합니다.npm i그러나 프로젝트에서 직접 가져오기 때문에 어떤 구성 파일에서 읽는지에 대해 좀 더 명확하게 설명하려면 대안 2가 좋습니다.이는 구성 파일이 변경될 경우 nx와 같은 도구가 프로젝트를 다시 컴파일할 수 있음을 의미합니다.

src/Config.ts

import config from 'config';
import DefaultConfig from '../config/default';
import CustomEnvironmentVariables from '../config/custom-environment-variables.json';
// If you have more configuration files (eg. production.ts), you might want to add them here.

export const Config = config.util.toObject() as typeof DefaultConfig & typeof CustomEnvironmentVariables;

src/app.ts

import {Config} from './Config';

// Has the correct type of "string"
console.log(Config.server);

tsconfig.json

{
  // ...
  "compilerOptions": {
    // ...
    // add these if you want to import .json configs
    "esModuleInterop": true,
    "resolveJsonModule": true,
  },
}

모노레포를 사용하고 있으며 가져오기를 시도하는 경우default.ts하위 프로젝트에서 오류가 발생할 수 있습니다.

error TS6059: File 'config/default.ts' is not under 'rootDir' 'my-project'. 'rootDir' is expected to contain all source files`. 

...그러면 이 답변을 구현해야 할 수도 있습니다.

제 생각에 형식 안전의 가장 큰 단점은 컴파일 타임 안전과 런타임 안전 사이의 일반적인 혼동으로 인해 잘못된 보안 감각을 만들 수 있다는 것입니다.특히 노드 구성의 경우 구성이 여러 파일 및 환경 변수를 병합한 결과입니다.따라서 런타임에 실제로 유형을 매핑하는지 확인하지 않고 구성에 유형을 적용하는 솔루션은 문제를 일으킬 수 있습니다.이를 해결하기 위해 타이피아나 조드와 같은 유형 보호 솔루션을 살펴볼 수 있습니다.

개인적으로 저는 프로젝트에 이미 있는 도구JTD + Ajv를 사용합니다.누군가 관심이 있다면 여기 레시피가 있습니다.

config
├── config.jtd.json
├── custom-environment-variables.js
├── default.json
└── development.json
src
├── config.ts
types
└── index.ts

파일config/config.jtd.json손으로 작성하면 다음과 같습니다(옵션 속성은 node-config에 의해 추가된 일부 사항을 무시하는 데 사용되며, 인터페이스를 node-config에서 제공하는 IConfig와 병합하는 것이 동일한 작업을 수행하는 더 나은 방법일 수 있습니다).

{
  "properties": {
    "port": { "type": "uint32"}
  },
  "optionalProperties": { "util": {}, "get": {}, "has": {} }
}

파일types/index.ts포함Config인터페이스, jtd-codegen을 사용하여 생성되었습니다.

jtd-codegen config/config.jtd.json --typescript-out types

그리고나서src/config.ts검증 및 유형 캐스팅을 수행합니다.

import fs from 'fs'
import config from 'config'
import Ajv from 'ajv/dist/jtd'
import { type Config } from '../types'

const validate = new Ajv().compile(JSON.parse(fs.readFileSync('config/config.jtd.json', 'utf8')))
if (!validate(config)) throw new Error('invalid config', { cause: validate.errors })

config.util.makeImmutable(config)
const typedConfig = config as unknown as Config

export default typedConfig

이제 가져올 때src/config.ts컴파일 시간 유형 안전성과 런타임 유효성을 모두 갖추고 있습니다.구성 개체도 변경할 수 없으므로 안전하게 유지됩니다.config.get 메소드는 포함되지 않지만 안전성이 확보된 지금은 필요하지 않다고 생각합니다.제거할 수도 있습니다.

node-config에서는 구성 유형을 검색하지 않습니다. IConfig구성 라이브러리 인터페이스에 대한 설명입니다.

다음과 같은 형식 인수와 함께 "get" 방법을 사용하여 예상되는 형식 스크립트를 구분할 수 있습니다.

const server = config.get<string>("server");

참고:config.get는 구성 값이 누락된 경우 오류를 발생시킵니다.이것은 벌레를 잡는데 도움을 주기 위한 의도적인 것입니다.

런타임 안전을 선호하는 경우 "has" 메서드를 사용하여 구성 값이 있는지 확인합니다.

config.has("server")

config.has("api.url")내포된 매개 변수의 경우

그러나 구성 값이 문자열 대신 개체 또는 숫자와 같은 다른 유형인 경우 다른 런타임 문제가 발생할 수 있습니다.

다음과 같은 패턴으로 검증:

const maybeServer = config.has("server") ? config.get("server") : null;

const server = typeof maybeServer === "string" ? maybeServer : "default";

이러한 방식으로 검증한 후에는 유형 스크립트가 변수의 유형을 알 수 있습니다.

그것이 "간단한" 대답입니다.

보다 포괄적인 엔터프라이즈 레벨 솔루션을 사용하려면 Zod와 같은 스키마 검증자를 사용하십시오.

사용할 수 있습니다.any반환 활자

const serverConfig: any = config.get('server');

언급URL : https://stackoverflow.com/questions/50813591/how-to-use-node-config-in-typescript

반응형