본문으로 건너뛰기

명명 규칙

본 문서는 파일명, 클래스명, 선택자, 슬라이스명의 규약을 정의합니다.

두 개의 규약을 결합합니다. 파일과 클래스는 Angular 스타일 가이드를 따르고, 세그먼트 내부의 파일 분할은 FSD의 도메인 기반 명명을 따릅니다.

1. 기준판 고정

Angular 스타일 가이드는 2025년 개정판을 기준으로 합니다.

이 개정에서 파일명의 타입 접미사(.component.ts, .service.ts, .directive.ts)가 제거되었습니다. Angular CLI의 fileNameStyleGuide 옵션 값 2025에 해당하며, ng new가 생성하는 루트 컴포넌트가 app.component.ts가 아니라 app.ts인 것이 이 규약의 적용 결과입니다.

기준판을 고정하지 않으면 CLI 생성물과 문서의 규약이 어긋나 생성할 때마다 파일명을 손으로 고치게 됩니다.

2. 파일명

2.1 형식

모든 파일명은 케밥 케이스를 사용합니다. 타입 접미사를 붙이지 않습니다.

대상 파일명
컴포넌트 assessment-list.ts, assessment-list.html
서비스 session.ts
가드 auth-guard.ts
인터셉터 auth-interceptor.ts
파이프 format-grade.ts
모델·타입 risk-assessment.ts

가드와 인터셉터는 접미사를 유지합니다. 이름만으로 역할이 드러나지 않으면 라우트 정의나 프로바이더 배열에서 무엇인지 판별할 수 없기 때문입니다.

2.2 도메인 기반 분할

세그먼트 안에서 파일을 나눌 때는 다루는 도메인으로 이름 짓습니다. 기술적 역할로 짓는 것을 금지합니다.

구분 준수 지침 (Do) 금지 지침 (Don't)
모델 model/risk-assessment.ts model/types.ts
유틸 lib/format-grade.ts lib/utils.ts
요청 api/fetch-assessments.ts api/api.ts
상수 config/assessment-grade.ts config/constants.ts

types.tsutils.ts가 금지되는 이유는 무관한 도메인이 한 파일에 섞이기 때문입니다. 파일명으로 내용을 알 수 없어 열어 봐야 하고, 시간이 지나면 무엇이든 들어가는 자리가 됩니다.

세그먼트에 도메인 관심사가 하나뿐이면 파일명이 슬라이스명과 같아도 됩니다. features/auth/model/auth.ts 형태입니다.

2.3 요청 함수 파일

동사로 시작해 무엇을 하는지 드러냅니다.

동작 파일명
목록 조회 fetch-assessments.ts
단건 조회 fetch-assessment.ts
생성 create-assessment.ts
수정 update-assessment.ts
삭제 delete-assessment.ts

3. 클래스명과 심볼명

3.1 클래스

파스칼 케이스를 사용하며 타입 접미사를 붙이지 않습니다.

대상 클래스명
컴포넌트 AssessmentList
서비스 SessionStore
디렉티브 Autofocus
파이프 FormatGrade

AssessmentListComponent가 아니라 AssessmentList입니다. 접미사는 정보를 더하지 않으며, 파일 위치(ui/ 세그먼트)가 이미 역할을 드러냅니다.

서비스는 역할을 드러내는 명사로 이름 짓습니다. SessionService처럼 Service로 끝내는 대신 SessionStore, InvalidationBus처럼 무엇을 하는지 담습니다.

3.2 함수

대상 형식 예시
주입 헬퍼 inject 접두사 injectInteractionMode, injectAssessment
조회 요청 fetch 접두사 fetchAssessments
변경 요청 동사 approveAssessment, deleteAssessment
계산 동사 calculateGrade, formatDate
판정 is · has · can 접두사 isExpired, hasPermission

3.3 타입

생성된 서버 타입은 생성기가 정한 이름을 그대로 사용합니다. 손으로 고치지 않습니다. 서버 어휘가 화면 코드에 드러나는 것은 API 계약 소비에서 감수하기로 한 대가입니다.

직접 정의하는 타입은 파스칼 케이스를 사용하며 I 접두사나 Type 접미사를 붙이지 않습니다.

4. 선택자

컴포넌트 선택자는 app 접두사와 케밥 케이스를 사용합니다.

@Component({ selector: 'app-assessment-list' })

접두사는 angular.jsonprefix 설정이 원본입니다. 프로젝트별로 다른 접두사를 쓸 수 있으나, 한 프로젝트 안에서는 일관되어야 합니다.

디렉티브 선택자는 접두사를 붙인 카멜 케이스 속성 형태를 사용합니다.

@Directive({ selector: '[appAutofocus]' })

5. 슬라이스명

5.1 형식

케밥 케이스를 사용하며 계층에 따라 품사가 다릅니다.

계층 품사 예시
pages 화면을 나타내는 명사구 assessment-list, assessment-detail
features 사용자 동작을 나타내는 동사구 assessment-approve, file-upload
entities 도메인 개념을 나타내는 명사 assessment, worker

featuresentities의 품사 차이가 두 계층의 판정 기준입니다. 이름을 지을 때 동사구가 자연스러우면 features, 명사가 자연스러우면 entities입니다.

5.2 pages 슬라이스명

라우트 경로와 대응시킵니다. 라우트를 보고 슬라이스를, 슬라이스를 보고 라우트를 찾을 수 있어야 합니다.

라우트 슬라이스
/assessments assessment-list
/assessments/:id assessment-detail
/assessments/:id/edit assessment-edit
/assessments/new assessment-create

목록·상세·편집·생성은 각각 별도 슬라이스입니다. 접미사를 -list, -detail, -edit, -create로 통일해 화면 성격이 이름에서 드러나게 합니다.

5.3 금지

금지 사유
슬라이스명에 계층명 포함 (assessment-page) 경로에 이미 pages/가 있습니다
지나치게 넓은 슬라이스명 (common, misc, management) 무엇이든 들어가는 자리가 됩니다
축약어 (assmt, usr) 검색되지 않고 읽는 사람마다 다르게 해석합니다

user-management 같은 광범위한 이름은 시간이 지나면 여러 책임이 뒤섞입니다. auth, profile-edit, password-reset처럼 책임 단위로 나눕니다.

6. 상수와 열거값

상수는 대문자 스네이크 케이스를 사용합니다.

export const MAX_UPLOAD_SIZE = 10 * 1024 * 1024;

열거 대신 유니온 타입과 as const 객체를 우선합니다. TypeScript의 enum은 런타임 코드를 생성하고 isolatedModules 환경에서 제약이 있습니다.

export const ASSESSMENT_GRADE = {
  high: 'HIGH',
  medium: 'MEDIUM',
  low: 'LOW',
} as const;

export type AssessmentGrade = (typeof ASSESSMENT_GRADE)[keyof typeof ASSESSMENT_GRADE];

7. 자동 강제

규칙 강제 수단
선택자 접두사와 형식 angular-eslint 규칙
클래스 접미사 금지 angular-eslint 규칙
도메인 기반 파일명 Steiger inconsistent-naming, ambiguous-slice-names, segments-by-purpose (부분)
파일명 케밥 케이스 ESLint 파일명 규칙

Steiger의 명명 규칙은 슬라이스와 세그먼트 수준의 위반만 검출합니다. 파일 하나가 여러 도메인을 담고 있는지는 판정하지 못하므로 코드 리뷰에서 확인합니다.

© 2026 dev.goraebap