콘텐츠로 이동

분산되어 있는 정리 여기로 합쳐야겠다.

Import 관련 & tsconfig.json 설정

JSON
adding "esModuleInterop": true to compilerOptions of tsconfig.json  

Problem occurs when we want to import CommonJS module into ES6 module codebase.
import * as 로 가져올 수 있지만
moment 와 같이, * 를 사용하여 import 하려는 대상의 타입이 Object가 아닌 경우에는 ES6의 모듈 사양에 호환되지 않게 된다.
esModuleInterop 속성이 위의 코드 처럼 true로 설정될 경우, ES6 모듈 사양을 준수하여 CommonJS 모듈을 가져올 수 있다.

저렇게 설정하니까 import * as express 못 읽음;;;
다른 라이브러리 써야겠다 유틸로 따로 만드는게 낫나? 혹은 ms 라이브러리를 그냥 현업에서 쓴다고 함.

  • 임포트 문제
    Pasted image 20230110154856.png
    allowSyntheticDefaultImports 때문에 그럼

TypeScript
import cookieParser from 'cookie-parser';  

app.use(cookieParser());   

로 수정함

TypeScript: Documentation - tsc CLI Options 보고 참고하면 됨

JSON
{  
  "compilerOptions": {  
    "module": "commonjs",  
    "declaration": true,  
    "removeComments": true,  
    "emitDecoratorMetadata": true,  
    "experimentalDecorators": true,  
    "allowSyntheticDefaultImports": true, //  
    "target": "es2017",  
    "sourceMap": true,  
    "outDir": "./dist",  
    "baseUrl": "./",  
    "incremental": true,  
    "skipLibCheck": true,  
    "strictNullChecks": false,  
    "noImplicitAny": false,  
    "strictBindCallApply": false,  
    "forceConsistentCasingInFileNames": false,  
    "noFallthroughCasesInSwitch": false,  
    "moduleResolution": "node", //  
    "esModuleInterop": true  //  
  }  
}  

allowSyntheticDefaultImports: true if module is system, or esModuleInterop and module is not es6/es2015 or esnext, false otherwise.

moduleResolution: Classic if module is AMD, UMD, System or ES6/ES2015, Matches if module is node12 or nodenext, Node otherwise.

esModuleInterop: Emit additional JavaScript to ease support for importing CommonJS modules. This enables allowSyntheticDefaultImports for type compatibility.

js 유형 별로 import 관련 더 알고 싶으면 심화 참고하면 되는데 굳이 몰라도 됨 패스 (CJS, ESM 차이도 굳이 들여다볼 필요는 없으니 일단 패스.)

import - JavaScript | MDN 임포트 관련 개념 정리 → 웬만하면 default import 로 돌리는게 나음.
살펴보니까 nestjs 보통 named import 쓰는듯? (내 코드 기준)

CommonJS와 ESM에 모두 대응하는 라이브러리 개발하기: exports field 여기에 정리 잘 되어있음

Redis Nest Js Config 설정 오류

  • configuration
    ^2d5ab6
    공식문서에서 3버전까지만 적혀있고 4버전은 따로 이 문서 를 참고하라고 한다. 해당 인터페이스가 Promise\ 를 허용하지 않기 때문임.

시도: Upgrade redis to v4 · Issue #40 · dabroek/node-cache-manager-redis-store · GitHub 여기 해결 방법 채택해보려 한다.

  • packages/common/cache/cache.providers.ts
    TypeScript
        let cache: string | Function = 'memory';  
        defaultCacheOptions.ttl *= 1000;  
        if (typeof store === 'object' && 'create' in store) {  
          cache = store.create;  
        } else if (typeof store === 'function') {  
          cache = store;  
        }  
    

    typeof ~ in
    TypeScript: Documentation - Advanced Types

이용하면 됨

TypeScript
export interface CacheStoreFactory {  
  /**  

   * Return a configured cache store.  
   *  
   * @param args Cache manager options received from `CacheModule.register()`  
   * or `CacheModule.registerAsync()`  
   */  
  create(args: LiteralObject): CacheStore;  
}  

/**  

 * Interface defining Cache Manager configuration options.  
 *  
 * @publicApi  
 */  
export interface CacheManagerOptions {  
  /**  
   * Cache storage manager.  Default is `'memory'` (in-memory store).  See  
   * [Different stores](https://docs.nestjs.com/techniques/caching#different-stores)  
   * for more info.  
   */  
  store?: string | CacheStoreFactory | CacheStore;  
  /**  
   * Time to live - amount of time that a response is cached before it  
   * is deleted. Subsequent request will call through the route handler and refresh  
   * the cache.  Defaults to 5 seconds. In `cache-manager@^4` this value is in seconds.  
   * In `cache-manager@^5` this value is in milliseconds.  
   */  
  ttl?: number;  
  /**  
   * Maximum number of responses to store in the cache.  Defaults to 100.  
   */  
  max?: number;  
  isCacheableValue?: (value: any) => boolean;  
}  

Type ‘RedisStore’ is not comparable to type ‘CacheStore’ 라고 한다.
‘CacheModuleAsyncOptions>‘

저 라이브러리랑 nest js 내 interface 코드 끼리 비교하면서 어떻게 모듈이 받아오는지 생각하면서 하루종일 삽질했다.
다운그레이드 대신 다른 방식으로 해결하고 싶었는데…

더 찾아보니까

공식문서에서는 dependencies 가 다음과 같다.

JSON
"@nestjs/common": "9.0.1",  
"@nestjs/core": "9.0.1",  
"cache-manager": "4.1.0",  
"cache-manager-redis-store": "2.0.0",  

오류 해결 못한 기준 내 package.json 설정은 다음과 같다.

JSON
"@nestjs/common": "^9.0.0",  
"@nestjs/core": "^9.0.0",  
"cache-manager": "^5.1.4",  
"cache-manager-redis-store":"^3.0.1",  

더 뒤져보니까 내가 시도해볼 방법은 다음과 같다.

  1. 2023년 1월 4일 기준 nest@9.2.0 에서는 해결되었다고 한다.
  2. node-cache-manager-redis-yet 라이브러리, cach-manager 버전 5를 쓴다.
  3. 공식문서 기준 버전으로 해당 라이브러리를 다운그레이드 한다.
  4. 위에서 내가 시도했던 방법대로 한다. (인터페이스 맞춰서 어거지로 쓴다. 또 더 찾아보니까 ttl 설정 등 사이드 이펙트가 많은 것 같다.)

2번 방법은 아직 제대로 검증된 방법이 아니라서 3번 방식이 확실하게 결과가 보장되어있어서 3번 방식을 선택하기로 했다.
4번 방법은.. 일단 조금 더 시도해본다면 일단 돌아가긴 할 것 같긴 한데, 결국은 다운그레이드가 더 깔끔한 것 같아서 넘어가기로 했다.

ㄱ-

TypeScript
// app.module.ts import 배열 내에 주입해준다.  
CacheModule.registerAsync({  
  imports: [ConfigModule],  
  inject: [ConfigService],  
  useFactory: async (configService: ConfigService) => ({  
    store: redisStore,  
    host: configService.get<string>('REDIS_HOST'),  
    port: configService.get<number>('REDIS_PORT'),  
    isGlobal: true, // 에러 발생함 바로 아래에서 수정함.  
  }),  
}),  
  • Redis 아이피 연결이 안됨
    Bash
    Error: connect ECONNREFUSED 127.0.0.1:6379  
        at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16)  
    

라고 뜸
javascript - Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED - Stack Overflow 를 참고하여 해결했다.

brew install redisredis-server 로 레디스 서버를 켜야한다.

Bash
 redis-server  
81485:C 11 Jan 2023 11:49:33.969 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo  
81485:C 11 Jan 2023 11:49:33.969 # Redis version=7.0.7, bits=64, commit=00000000, modified=0, pid=81485, just started  
81485:C 11 Jan 2023 11:49:33.969 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf  
81485:M 11 Jan 2023 11:49:33.969 * Increased maximum number of open files to 10032 (it was originally set to 256).  
81485:M 11 Jan 2023 11:49:33.969 * monotonic clock: POSIX clock_gettime  
                _._  
           _.-``__ ''-._  
      _.-``    `.  `_.  ''-._           Redis 7.0.7 (00000000/0) 64 bit  
  .-`` .-```.  ```\/    _.,_ ''-._  
 (    '      ,       .-`  | `,    )     Running in standalone mode  
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379  
 |    `-._   `._    /     _.-'    |     PID: 81427  
  `-._    `-._  `-./  _.-'    _.-'  
 |`-._`-._    `-.__.-'    _.-'_.-'|  
 |    `-._`-._        _.-'_.-'    |           https://redis.io  
  `-._    `-._`-.__.-'_.-'    _.-'  
 |`-._`-._    `-.__.-'    _.-'_.-'|  
 |    `-._`-._        _.-'_.-'    |  
  `-._    `-._`-.__.-'_.-'    _.-'  
      `-._    `-.__.-'    _.-'  
          `-._        _.-'  
              `-.__.-'  

우왕ㅋㅋ

  • 주입 문제
    authController 에서 생성자 주입했는데
    Bash
    Nest can't resolve dependencies of the AuthController (?, AuthService, ConfigService). Please make sure that the argument CACHE_MANAGER at index [0] is available in the AuthModule context.  
    

    라는 에러 메시지를 준다.

디버깅해보니 isGlobal 옵션을 모듈에서 못읽어왔다는 것을 확인했다.

TypeScript
  CacheModule.registerAsync<RedisClientOptions>({  
      imports: [ConfigModule],  
      inject: [ConfigService],  
      useFactory: async (configService: ConfigService) => ({  
        store: redisStore,  
        host: configService.get<string>('REDIS_HOST'),  
        port: configService.get<number>('REDIS_PORT'),  
      }),  
      isGlobal: true,  
    }),  

이렇게 설정하였더니 잘 작동된다.

Redis 메서드 문제

TypeScript
[Nest] 24171  - 01/12/2023, 3:58:21 PM   ERROR [ExceptionsHandler] this.cacheManager.set is not a function  

오오 ..

How can I get redis io client from NestJS CacheManager module - Stack Overflow

Upgrade redis to v4 · Issue #40 · dabroek/node-cache-manager-redis-store · GitHub

javascript - In Nest js, I added Redis as a cache manager. And can’t find any added data in Redis after calling the set function. So, am I missing something? - Stack Overflow

아 아까 위에 문제랑 똑같은 원인임

이게 더 구글링해보니까 의존성 주입 문제라는 개념에 대해서 알게되었다.

다 시도해본 결과 nest js 가장 최신 버전 + 라이브러리 버전 변경 다 해보고 다른 자체 라이브러리 써보고 해봣는데
걍 프레임워크 자체를 버전 8로 낮추니까 돌아간다.

음.. 프레임워크, 라이브러리 다운그레이드 없이 어떻게 하나 더 찾아봄

관련 오류 기록 문서.githubUpgrade redis to v4 · Issue #40 · dabroek/node-cache-manager-redis-store · GitHub 요렇게 써봄

vsCode Dependencies Bug with nestJs

node.js - vsCode dependencies bug with nestJs - Stack Overflow
ctrl/cmd + shift + p > Typescript: Restart TS Server


마지막 업데이트 : 2025년 4월 23일
작성일 : 2023년 4월 2일