Skip to content

๐Ÿš€ NestJS ๊ธฐ๋ณธ ๊ฐœ๋… โ€ Modules

Kang Chaeryeon edited this page Nov 11, 2024 · 1 revision

NestJS ์•ฑ์„ ์ƒ์„ฑํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœย app.controller.ts,ย app.module.ts,ย app.service.tsย ๋“ฑ์œผ๋กœ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ๊ฐ€ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๊ณ  ์ด๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ตฌ๋™๋œ๋‹ค

src
 |- main.ts                    # Nest ์•ฑ์˜ ์‹คํ–‰ํŒŒ์ผ
 |- app.module.ts              # ์‹คํ–‰ํŒŒ์ผ์—์„œ ๋“ฑ๋ก, ์‚ฌ์šฉํ•˜๋Š” root ๋ชจ๋“ˆํŒŒ์ผ
 |- app.controller.ts          # Nest ์•ฑ์˜ root ๊ธฐ๋ณธ ์ปจํŠธ๋กค๋Ÿฌ
 |- app.service.ts             # Nest ์•ฑ์˜ root ๊ธฐ๋ณธ ๋น„์ฆˆ๋‹ˆ์Šค ์„œ๋น„์Šค

์ด์ค‘ ์ค‘์š” ๊ฐœ๋…์ค‘ ํ•˜๋‚˜์ธ Module์— ๊ด€ํ•œ ์ •๋ฆฌ๋ฅผ ์œ„ํ•œ ํฌ์ŠคํŠธ์ด๋‹ค

Modules overview

๊ฐ„๋‹จ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ๋ชจ๋“ˆ์ด ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ์ด ๋˜๋Š”์ง€๋ฅผ ์‚ดํŽด๋ณด์ž

// app.module.ts
import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}

์šฐ์„  NestJS์—์„œ ๋ชจ๋“ˆ์€ @Module์ด๋ผ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ†ตํ•˜์—ฌ ์ •์˜๋œ๋‹ค

ํ•ด๋‹น ์˜ˆ์ œ์—์„œ AppModule์€ root์— ์œ„์น˜ํ•ด ์žˆ๋Š” module๋กœ์จ ์ง„์ž…์ ์˜ ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๊ฒŒ ๋œ๋‹ค. ๋˜ AppModule์ด CatsModule์„ importํ•˜์—ฌ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค

๊ทธ๋ ‡๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ import ๋˜๋Š” CatsModule์€ ์–ด๋–ค ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์„๊นŒ?

// cats.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService] 
})
export class CatsModule {}

CatsModule ์ž์ฒด์—์„œ๋Š” ๋ณ„๋„์˜ ๋‹ค๋ฅธ import๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค

๋‹ค๋งŒ CatsModule ์•ˆ์—์„œ controllers์™€ providers ์˜ต์…˜์ด ์žˆ๊ณ  ๊ฐ๊ฐ CatsController์™€ CatsService๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค

๊ฒฐ๊ตญ Module์ด๋ผ๋Š” ๊ฒƒ์€ ์‰ฝ๊ฒŒ ๋งํ•˜์ž๋ฉด ๊ตฌํ˜„ํ–ˆ๋˜ cats์˜ controller์™€ service, repository ๋“ฑ provider๋“ค์„ ํ•˜๋‚˜์˜ 'cats' ๋ชจ๋“ˆ๋กœ ๋ฌถ์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค (Provider๋“ค์„ ์‚ฌ์šฉํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ์˜ ์ง„์ž…์  ์—ญํ• ์„ ํ•˜๋Š” controller๋“ค์€ provider๋ž‘ ๋ถ„๋ฆฌ๋˜์–ด ๊ตฌ๋ถ„์ด ๋œ๋‹ค)

๊ทธ๋Ÿฌ๊ณ  ๊ทธ๋ ‡๊ฒŒ ์ •์˜ ๋œ CatsModule์„ AppModule์—์„œ importํ•˜์—ฌ ์‚ฌ์šฉ์ด ๋˜๋Š” ๊ฒƒ์ด๋‹ค

์ „์ฒด์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋ชจ๋“ˆ๋กœ ํšจ๊ณผ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค:

image

Module ๊ธฐ๋ณธ ๊ตฌ์„ฑ ์š”์†Œ์— ๊ด€ํ•œ ์ •๋ฆฌ

๊ธฐ๋ณธ์ ์œผ๋กœ @Module ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์•ˆ์—๋Š” ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋งŒ ๋“ค์–ด๊ฐ€๋Š”๋ฐ ์ด ๊ฐ์ฒด ๋‚ด attribute๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •๋ฆฌ ํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค (์ฐธ๊ณ ๋กœ attribute๋“ค์€ ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ํ•„์š”ํ•  ๊ฒฝ์šฐ ๋ฐฐ์—ด๋กœ ์ •์˜๋ฅผ ํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค)

  • providers: Nest์˜ Injector์— ์˜ํ•ด ์ธ์Šคํ„ด์Šคํ™” ๋˜์–ด ํ•ด๋‹น ๋ชจ๋“ˆ์—์„œ ๊ณต์œ  ๋  ์ˆ˜ ์žˆ๋Š” provider๋“ค
  • controllers: ๋ชจ๋“ˆ ๋‚ด์—์„œ ์ธ์Šคํ„ด์Šคํ™” ๋˜์–ด์•ผํ•  ๊ธฐ๋Šฅ์— ๋ถ€ํ•ฉํ•˜๋Š” controller list
  • import: ํ•ด๋‹น ๋ชจ๋“ˆ ๋‚ด์—์„œ ํ•„์š”ํ•œ provider๋ฅผ exportํ•˜๋Š” ๋ชจ๋“ˆ์„ ์™ธ๋ถ€์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ชฉ๋ก (์ฃผ๋กœ ๋ชจ๋“ˆ๋งŒ์„ import ํ•œ๋‹ค)
  • export: ํ•ด๋‹น ๋ชจ๋“ˆ์—์„œ ์ œ๊ณตํ•˜๊ธฐ์—, ํ•ด๋‹น ๋ชจ๋“ˆ์„ importํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” provider์˜ ์ง‘ํ•ฉ

Re-Export๋ฅผ ํ†ตํ•œ ๋ชจ๋“ˆ์˜ ํšจ์œจ์ ์ธ ๊ด€๋ฆฌ

Module์„ import ํ•˜๊ณ  ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ re-exportํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”๋ฐ, ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

@Module({
  imports: [CommnonModule],
  exports: [CommonModule],
 })
export class CoreModule {}

๊ฐ€์ ธ์˜จ ๋ชจ๋“ˆ์„ ๋ฐ”๋กœ exportํ•˜๋ฉด ์ข‹์€ ์ ์ด ๋ญ˜๊นŒ? ์ฃผ์š” ์žฅ์ ์œผ๋กœ๋Š”

  • ์ค‘๋ณต import ๋ฌธ ์ œ๊ฑฐ
  • ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋‹จ์ˆœํ™”๋ฅผ ํ†ตํ•œ ์ฝ”๋“œ ์œ ์ง€ ๋ณด์ˆ˜ ์šฉ์ด
  • ๋ชจ๋“ˆ ๊ตฌ์กฐ์˜ ์ผ๊ด€์„ฑ ์œ ์ง€

๊ฐ€ ์žˆ๋‹ค

// core.module.ts
@Module({
  imports: [
    ConfigModule,
    LoggerModule,
    DatabaseModule
  ],
  exports: [
    ConfigModule,
    LoggerModule,
    DatabaseModule
  ]
})
export class CoreModule {}

// feature.module.ts
@Module({
  imports: [CoreModule] // ํ•„์š”ํ•œ ๋ชจ๋“  ๋ชจ๋“ˆ์„ ํ•œ ๋ฒˆ์— ์ž„ํฌํŠธ
})
export class FeatureModule {}

ํ•ด๋‹น ์˜ˆ์‹œ์—์„œ CoreModule์ด ConfigModule, LoggerModule, DatabaseModule์„ ๋ชจ๋‘ ๋ฐ›์•„์™€์„œ ๋ฐ”๋กœ export๋ฅผ ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค

์ด๋ ‡๊ฒŒ ๋ ๊ฒฝ์šฐ์— FeatureModule์—์„œ๋Š” ์ƒ๊ธฐ๋œ ๋ชจ๋“ˆ๋“ค์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” CoreModuleํ•˜๋‚˜๋งŒ import ํ•˜๋ฉด ๋˜๋Š” ๊ฒƒ์ด๋‹ˆ ์ „๋ฐ˜์ ์œผ๋กœ import์— ๊ด€ํ•œ ๊ด€๋ฆฌ๊ฐ€ ์šฉ์ดํ•ด์ง„ ๊ฒƒ์„ ๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค

Single Module approach vs Multiple Module approach

Single Module Approach: ํ•˜๋‚˜์˜ root module (์ฃผ๋กœ app.module.ts)์—์„œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค

// app.module.ts
@Module({
  imports: [
    TypeOrmModule.forFeature([User, Order, Product, Payment]),
    ConfigModule.forRoot(),
  ],
  controllers: [
    UserController, 
    OrderController, 
		...
  ],
  providers: [
    UserService,
    OrderService,
    ProductService,
    ...
  ],
})
export class AppModule {}
  • ์„ค์ •์ด ๊ฐ„๋‹จํ•˜๊ณ  ๋น ๋ฅธ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค
  • ์˜์กด์„ฑ ๊ด€๋ฆฌ๊ฐ€ ๋‹จ์ˆœํ•˜๋‹ค
  • ๋‹ค๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด ๊ด€๋ฆฌ ์ฐจ์›์—์„œ ์–ด๋ ค์›Œ์งˆ ์ˆ˜๋„ ์žˆ๋‹ค
  • ๋˜ํ•œ ๊ธฐ๋Šฅ๋ณ„ ๋ถ„๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ ์งˆ ์ˆ˜๋„ ์žˆ๋‹ค
  • ๋น„๊ต์  ์ž‘์€ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜๋‹ค

Multiple Module Approach : ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๋„๋ฉ”์ธ๋ณ„๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค

์—ฌ๋Ÿฌ ๋ชจ๋“ˆ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๋„๋ฉ”์ธ๋ณ„๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค

// user.module.ts
@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UserController],
  providers: [UserService],
  exports: [UserService],
})
export class UserModule {}

// product.module.ts
@Module({
  imports: [TypeOrmModule.forFeature([Product])],
  controllers: [ProductController],
  providers: [ProductService],
})
export class ProductModule {}

// app.module.ts
@Module({
  imports: [
    ConfigModule.forRoot(),
    UserModule,
    ProductModule,
    ...
  ],
})
export class AppModule {}
  • ๋„๋ฉ”์ธ ๋ณ„๋กœ ๋ช…ํ™•ํ•œ ๊ฒฝ๊ณ„๊ฐ€ ์„ค์ •์ด ๋˜์–ด์žˆ๊ณ  ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•˜๋‹ค
  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์ด ํ–ฅ์ƒ ๋œ๋‹ค
  • ๋‹ค๋งŒ ์ดˆ๊ธฐ ์„ค์ •์ด ๋ณต์žกํ•˜๊ณ  ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง„๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค

inear

๊ธฐ์ˆ  ๊ณต์œ 

๐Ÿš€ ffmpeg๋Š” stderr๋กœ ๋””๋ฒ„๊น…์„ ํ•˜๋Š” ์ด์œ 
๐Ÿš€ HLS ํ”„๋กœํ† ์ฝœ์— ๊ด€ํ•œ ์ •๋ฆฌ ๋ฐ FFmpeg ์‚ฌ์šฉ๊ธฐ
๐Ÿš€ ๋น„ํŠธ๋Š” tsconfig.json์ด ์„ธ ๊ฐœ?
๐Ÿš€ NestJS ๊ธฐ๋ณธ ๊ฐœ๋… - Modules
๐Ÿš€ Socket.io ์ตœ(๊ฐ•)์ ํ™”
๐Ÿš€ ๋„์ปค์™€ nginx์˜ ์‚ฌ์šฉ๊ธฐ
๐Ÿš€ ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด์ž

๊ฐœ๋ฐœ ์ผ์ง€

๐Ÿš€ FSD ์‚ฌ์šฉ๊ธฐ, ๊ทผ๋ฐ ์ด์ œ ๋‚˜๋งŒ์˜ ๊ทœ์น™์„ ๊ณ๋“ค์ธ
๐Ÿš€ CICD ๊ตฌ์กฐ ์ˆ˜์ •
๐Ÿš€ ์•จ๋ฒ” ๋‹จ์œ„๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ ํ•˜๊ธฐ (with HLS)
๐Ÿš€ HLS๋กœ ์Œ์•… ์ฃผ๊ณ ๋ฐ›๊ธฐ
๐Ÿš€ vite + react + typescript ํ™˜๊ฒฝ์—์„œ path alias ์„ค์ •
๐Ÿš€ React Scan์ด ๋ญ์ฃ ?
๐Ÿš€ ๋กœ์ปฌ ํ™˜๊ฒฝ ๊ฐœ๋ฐœ ๋ชจ๋“œ ๋ฐฐํฌ
๐Ÿš€ ์•จ๋ฒ” ์ „์ฒด๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐํ•œ๋‹ค๊ณ ? (with HLS)
๐Ÿš€ ์ฝ”๋“œ์˜ ์•ˆ์ •์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž

ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

๐Ÿš€ ์ƒˆ๋กœ๊ณ ์นจ ์‹œ HLS ERROR
๐Ÿš€ input ํƒœ๊ทธ์— ํ•œ๊ธ€ ์ž…๋ ฅ ํ›„, Enter๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ•จ์ˆ˜๊ฐ€ ๋‘๋ฒˆ ํ˜ธ์ถœ๋˜๋Š” ์˜ค๋ฅ˜
๐Ÿš€ nginx proxy pass๋ฅผ ๋ฐ”๊ฟจ๋”๋‹ˆ ์ƒ๊ธด ์—๋Ÿฌ - ์Šค์›จ๊ฑฐ ์ธ์‹ ๋ฌธ์ œ
๐Ÿš€ ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ WS handshake
๐Ÿš€ ๋ Œ๋”๋ง ๋ฒ”์ธ์€ ํ•˜๋‚˜!

ํ˜‘์—… ๊ทœ์น™

๐ŸŒˆ ๊ทธ๋ผ์šด๋“œ ๋ฃฐ
๐Ÿฅ” ํŒ€์› ์†Œ๊ฐœ
๐Ÿ”Ž ์ฝ”๋“œ & ๊นƒ ์ปจ๋ฒค์…˜
๐ŸŒณ ๊นƒ branch ์ „๋žต
๐Ÿ“Œ ๋…ธ์…˜ ๋ฌธ์„œ ์ €์žฅ์†Œ

ํ”„๋กœ์ ํŠธ ๊ธฐํš

๐ŸŽจ ํ”ผ๊ทธ๋งˆ
๐Ÿง‘โ€๐Ÿ’ป ๊ธฐํš ๊ณต์œ  ๋ฐœํ‘œ ์ž๋ฃŒ
๐ŸŽค 2์ฃผ์ฐจ ๋ฐœํ‘œ ์ž๋ฃŒ
๐Ÿ˜Ž ๋ฐฑ๋กœ๊ทธ

๋ฐ์ผ๋ฆฌ ์Šคํฌ๋Ÿผ

๐Ÿ“ 1์ฃผ์ฐจ
๐Ÿ“ 2์ฃผ์ฐจ
๐Ÿ“ 3์ฃผ์ฐจ
๐Ÿ“ 4์ฃผ์ฐจ
๐Ÿ“ 5์ฃผ์ฐจ

์ฃผ๊ฐ„ ๊ณ„ํš์„œ

๐Ÿ—“๏ธ 1์ฃผ์ฐจ
๐Ÿ—“๏ธ 2์ฃผ์ฐจ
๐Ÿ—“๏ธ 3์ฃผ์ฐจ
๐Ÿ—“๏ธ 4์ฃผ์ฐจ
๐Ÿ—“๏ธ 5์ฃผ์ฐจ

๊ทธ๋ฃน ํšŒ๊ณ 

โœจ 1์ฃผ์ฐจ
โœจ 2์ฃผ์ฐจ
โœจ 3์ฃผ์ฐจ
โœจ 4์ฃผ์ฐจ


view

Clone this wiki locally