Skip to Content
문서기여 가이드

기여 가이드

ASAPJS에 기여해주셔서 감사합니다. 이 문서는 개발 환경 설정부터 PR 제출까지의 전체 워크플로를 안내합니다.


레포지토리 구조

ASAPJS는 Lerna + Yarn Workspaces 기반 모노레포입니다.

asapjs/ packages/ core/ @asapjs/core — Application, 설정, 로거 router/ @asapjs/router — HTTP 라우팅, 데코레이터, Swagger, JWT sequelize/ @asapjs/sequelize — ORM, TypeIs, DTO, Repository socket/ @asapjs/socket — Socket.IO 통합 example/ 참조 구현 (User/Post CRUD) docs/ Nextra 기반 문서 사이트 package.json 루트 (workspaces, 스크립트) lerna.json Lerna 설정

각 패키지는 독립적인 package.json, tsconfig.json, src/, dist/를 가지며 npm에 별도로 발행됩니다.


개발 환경 설정

사전 요구사항

  • Node.js 16 이상
  • Yarn 1.x (Classic)
  • Git

초기 설정

# 레포지토리 클론 git clone https://github.com/asapjs/asapjs.git cd asapjs # 의존성 설치 (모든 패키지 + example) yarn install # 전체 패키지 빌드 yarn build:packages

개발 서버 실행

# example 앱 개발 서버 (파일 변경 감지 + 자동 재시작) cd example && yarn dev # 디버그 모드 (Node inspector, 포트 9229) cd example && yarn dev:debug

패키지 빌드

패키지 간 의존성 때문에 빌드 순서가 중요합니다:

1단계: @asapjs/core (의존성 없음) 2단계: @asapjs/router (core에 의존) @asapjs/sequelize (core에 의존) @asapjs/socket (core에 의존) ← 병렬 빌드 가능 3단계: example (모든 패키지에 의존)
# 전체 패키지 빌드 (Lerna가 순서 자동 해결) yarn build:packages # 단일 패키지 빌드 cd packages/core && yarn build cd packages/router && yarn build cd packages/sequelize && yarn build cd packages/socket && yarn build

중요: 패키지 소스를 수정한 후에는 반드시 해당 패키지를 다시 빌드해야 example 앱에 반영됩니다.


테스트

# 루트에서 example 테스트 실행 yarn example:test # example 디렉토리에서 직접 실행 cd example yarn test # 유닛 테스트 yarn test:e2e # E2E 테스트 yarn test:all # 유닛 + E2E yarn test:watch # 파일 변경 시 자동 재실행

테스트는 인메모리 SQLite를 사용하므로 외부 DB 서버가 필요 없습니다. 테스트 작성 방법은 Testing 가이드를 참고하세요.


코딩 컨벤션

TypeScript 설정

모든 패키지는 다음 TypeScript 옵션을 사용합니다:

{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true, "strict": false, "strictPropertyInitialization": false } }

experimentalDecoratorsemitDecoratorMetadata는 ASAPJS의 데코레이터 시스템에 필수입니다.

파일 명명 규칙

ASAPJS의 자동 탐색(auto-discovery) 시스템은 파일 이름 패턴에 의존합니다:

패턴용도예시
*Table.tsSequelize 모델 (Entity)UsersTable.ts, PostsTable.ts
*Dto.tsDTO 클래스CreateUserDto.ts, UserInfoDto.ts
*Socket.tsSocket.IO 핸들러ChatSocket.ts
route.ts라우트 정의 (진입점과 같은 디렉토리)src/route.ts

주의: 이 파일 이름 규칙은 initSequelizeModule()initSocketModule()의 자동 탐색에 사용됩니다. 규칙을 따르지 않으면 모듈이 등록되지 않습니다.

디렉토리 구조 (도메인별)

src/ {domain}/ controller/ {Domain}Controller.ts # RouterController 확장 application/ {Domain}Application.ts # 비즈니스 로직 domain/ entity/ {Domain}sTable.ts # @Table 데코레이터 모델 dto/ Create{Domain}Dto.ts # 요청 DTO {Domain}InfoDto.ts # 응답 DTO

데코레이터 패턴

Entity 정의@Table + TypeIs.* 데코레이터:

// src/user/domain/entity/UsersTable.ts import { Model } from 'sequelize-typescript'; import { Table, TypeIs } from '@asapjs/sequelize'; @Table({ tableName: 'users', timestamps: true }) export default class UsersTable extends Model { @TypeIs.INT({ primaryKey: true, autoIncrement: true, comment: '사용자 ID' }) id: number; @TypeIs.STRING({ unique: true, comment: '이메일' }) email: string; }

DTO 정의ExtendableDto + TypeIs.*:

// src/user/dto/UserInfoDto.ts import { ExtendableDto, TypeIs } from '@asapjs/sequelize'; import UsersTable from '../domain/entity/UsersTable'; export default class UserInfoDto extends ExtendableDto { @TypeIs.INT({ comment: '사용자 ID' }) id: number; @TypeIs.STRING({ comment: '이메일' }) email: string; }

Controller 정의RouterController + @Get/@Post/@Put/@Delete:

// src/user/controller/UserController.ts import { RouterController, Get, Post, ExecuteArgs } from '@asapjs/router'; export default class UserController extends RouterController { public tag = 'User'; public basePath = '/users'; constructor() { super(); this.registerRoutes(); } @Get('/', { title: '사용자 목록', response: UserInfoDto }) async list({ paging }: ExecuteArgs) { ... } }

로거 사용

구조화된 메타데이터와 함께 로거를 사용합니다:

import { logger } from '@asapjs/core'; // info logger.info('User registered', { operation: 'UserApplication.register', executeId: '...', context: { userId: 1 }, }); // error (에러 객체를 두 번째 인자로 전달) logger.error('Registration failed', error, { operation: 'UserApplication.register', executeId: '...', });

PR 가이드라인

브랜치 전략

  • main — 안정된 릴리스 브랜치
  • feat/{feature-name} — 새 기능 개발
  • fix/{issue} — 버그 수정
  • docs/{topic} — 문서 변경

PR 작성 시 체크리스트

  • 영향받는 패키지만 수정했는가?
  • yarn build:packages가 성공하는가?
  • yarn example:test가 통과하는가?
  • 새 기능에 대한 테스트를 추가했는가?
  • 파일 명명 규칙(*Table.ts, *Dto.ts)을 따랐는가?

커밋 메시지 형식

<type>(<scope>): <description> feat(router): add multipart/form-data support fix(sequelize): handle null values in TypeIs.PASSWORD docs(core): update logger usage examples refactor(core): rename transactionId to executeId
type용도
feat새 기능
fix버그 수정
docs문서 변경
refactor리팩토링 (기능 변경 없음)
test테스트 추가/수정
chore빌드/도구 설정 변경

관련 문서

Last updated on