분산되어 있는 정리 여기로 합쳐야겠다.
Import 관련 & tsconfig.json 설정¶
- ms 라이브러리 import 에러 해결:
TypeError: (0 , ms_1.default) is not a function · Issue #186 · vercel/ms · GitHub
esModuleInterop 속성을 이용한 Import 에러 해결
typescript - Understanding esModuleInterop in tsconfig file - Stack Overflow
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 라이브러리를 그냥 현업에서 쓴다고 함.
로 수정함
TypeScript: Documentation - tsc CLI Options 보고 참고하면 됨
{
"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
TypeScriptlet 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
이용하면 됨
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 코드 끼리 비교하면서 어떻게 모듈이 받아오는지 생각하면서 하루종일 삽질했다.
다운그레이드 대신 다른 방식으로 해결하고 싶었는데…
더 찾아보니까
- 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
- NestJS v9 incompatible with version 5 · Issue #210 · node-cache-manager/node-cache-manager · GitHub 에서 Nest Js 버전 9 자체에서 호환이 안되는 오류였다고 한다. 단순 라이브러리 단에서의 문제가 아니었다.
(node-cache-manager version 5 또한 Nest version 8 과 호환이 안된다고 한다.)
공식문서에서는 dependencies 가 다음과 같다.
"@nestjs/common": "9.0.1",
"@nestjs/core": "9.0.1",
"cache-manager": "4.1.0",
"cache-manager-redis-store": "2.0.0",
오류 해결 못한 기준 내 package.json 설정은 다음과 같다.
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"cache-manager": "^5.1.4",
"cache-manager-redis-store":"^3.0.1",
더 뒤져보니까 내가 시도해볼 방법은 다음과 같다.
- 2023년 1월 4일 기준 nest@9.2.0 에서는 해결되었다고 한다.
- node-cache-manager-redis-yet 라이브러리, cach-manager 버전 5를 쓴다.
- 공식문서 기준 버전으로 해당 라이브러리를 다운그레이드 한다.
- 위에서 내가 시도했던 방법대로 한다. (인터페이스 맞춰서 어거지로 쓴다. 또 더 찾아보니까 ttl 설정 등 사이드 이펙트가 많은 것 같다.)
2번 방법은 아직 제대로 검증된 방법이 아니라서 3번 방식이 확실하게 결과가 보장되어있어서 3번 방식을 선택하기로 했다.
4번 방법은.. 일단 조금 더 시도해본다면 일단 돌아가긴 할 것 같긴 한데, 결국은 다운그레이드가 더 깔끔한 것 같아서 넘어가기로 했다.
ㄱ-
// 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 아이피 연결이 안됨
라고 뜸
javascript - Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED - Stack Overflow 를 참고하여 해결했다.
brew install redis → redis-server 로 레디스 서버를 켜야한다.
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 에서 생성자 주입했는데
BashNest 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 옵션을 모듈에서 못읽어왔다는 것을 확인했다.
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 메서드 문제¶
[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
아 아까 위에 문제랑 똑같은 원인임
이게 더 구글링해보니까 의존성 주입 문제라는 개념에 대해서 알게되었다.
다 시도해본 결과 nest js 가장 최신 버전 + 라이브러리 버전 변경 다 해보고 다른 자체 라이브러리 써보고 해봣는데
걍 프레임워크 자체를 버전 8로 낮추니까 돌아간다.
음.. 프레임워크, 라이브러리 다운그레이드 없이 어떻게 하나 더 찾아봄
관련 오류 기록 문서.github 랑 Upgrade 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
작성일 : 2023년 4월 2일
