새로 만든 Angular 프로젝트는 정해진 구조를 따릅니다. 파일마다 하는 일을 알아 두면 빌드 설정을 바꾸거나 기능을 추가할 때, 다른 사람의 프로젝트를 읽을 때 훨씬 수월합니다.
작업 공간 한눈에 보기
my-app/
angular.json 작업 공간과 빌드 설정
package.json 의존성과 npm 스크립트
tsconfig.json 공통 TypeScript 설정
tsconfig.app.json 애플리케이션 코드용 설정
tsconfig.spec.json 테스트 파일용 설정
public/ 그대로 복사되는 정적 파일(파비콘, 이미지)
src/
index.html 하나뿐인 HTML 페이지
main.ts 애플리케이션 진입점
styles.css 전역 스타일
app/
app.ts 루트 컴포넌트
app.html 루트 컴포넌트 템플릿
app.css 루트 컴포넌트 스타일
app.spec.ts 루트 컴포넌트 테스트
app.config.ts 앱 전체에 쓰는 프로바이더
app.routes.ts 라우트 정의
이전 버전으로 만든 프로젝트에는 public 대신 src/assets 폴더가 있고, 컴포넌트 파일 이름에 .component가 붙어 있을 수 있습니다. --ssr로 만든 프로젝트에는 server.ts, src/main.server.ts, app.config.server.ts, app.routes.server.ts가 더 있습니다.
시작 과정: main.ts와 app.config.ts
main.ts는 루트 컴포넌트와 애플리케이션 설정으로 앱을 시작(부트스트랩)합니다.
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { App } from './app/app';
bootstrapApplication(App, appConfig)
.catch((err) => console.error(err));
app.config.ts에는 앱 전체에서 쓸 프로바이더를 나열합니다. 라우터, HttpClient 같은 기능을 여기서 등록합니다. 생성된 파일에 변경 감지 설정 같은 다른 프로바이더가 이미 들어 있을 수 있는데, 그대로 두고 옆에 필요한 것을 추가하면 됩니다.
import { ApplicationConfig } from '@angular/core';
import { provideRouter, withComponentInputBinding } from '@angular/router';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withComponentInputBinding()),
provideHttpClient(withFetch()),
],
};
angular.json
angular.json은 작업 공간의 프로젝트와 CLI가 실행할 수 있는 타깃(build, serve, test 등)을 정의합니다. 타깃마다 빌더, 기본 옵션, 이름 붙은 구성(configuration)이 있습니다.
{
"projects": {
"my-app": {
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"browser": "src/main.ts",
"tsConfig": "tsconfig.app.json",
"assets": [{ "glob": "**/*", "input": "public" }],
"styles": ["src/styles.css"]
},
"configurations": {
"production": { "outputHashing": "all" },
"development": { "optimization": false, "sourceMap": true }
},
"defaultConfiguration": "production"
}
}
}
}
}
위 내용은 간추린 것입니다. 이전 작업 공간에서는 빌더 이름이 @angular-devkit/build-angular:application이며 동작은 같습니다. prefix는 ng generate가 쓰는 셀렉터 접두어로, 생성된 컴포넌트는 app-hero-list 같은 셀렉터를 갖습니다.
TypeScript와 엄격 모드
새 프로젝트는 TypeScript 엄격 모드와 엄격한 템플릿 검사가 켜져 있습니다. 템플릿의 오타나 잘못된 입력 타입을 브라우저가 아니라 빌드 단계에서 잡아 주므로 그대로 켜 두는 것이 좋습니다.
{
"compilerOptions": {
"strict": true,
"noImplicitReturns": true
},
"angularCompilerOptions": {
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
환경별 값
빌드마다 다른 값을 쓰려면 ng generate environments를 실행합니다. src/environments에 파일이 만들어지고 angular.json에 fileReplacements 항목이 추가되어, 개발 빌드에서는 environment.development.ts가 대신 쓰입니다.
// src/environments/environment.ts
export const environment = {
apiUrl: 'https://api.example.com',
};
코드에서는 import { environment } from '../environments/environment';로 가져옵니다. 이 파일의 내용은 모두 브라우저 번들에 들어가므로 비밀 값은 절대 넣지 않습니다.
커지는 앱 정리하기
공식 스타일 가이드는 파일을 종류별이 아니라 기능별로 묶기를 권합니다.
src/app/
core/
auth.service.ts
heroes/
hero-list.ts
hero-list.html
hero-detail.ts
hero.service.ts
heroes.routes.ts
shared/
ui/
button.ts
그 밖에 지키면 좋은 관례는 다음과 같습니다.
- 파일 이름은 하이픈으로 단어를 잇고(kebab-case), 파일 하나에 컴포넌트·서비스·디렉티브 하나만 둡니다.
- 한 컴포넌트의 TypeScript, 템플릿, 스타일, 테스트 파일은 같은 이름으로 나란히 둡니다.
- 의존성은 생성자 매개변수보다
inject()로 받습니다. - 템플릿에서만 쓰는 멤버는
protected로, 입력과 시그널은 readonly로 선언합니다. - 최근 CLI는 생성하는 파일 이름에서
.component, .service 같은 접미사를 뺍니다. 어느 방식이든 동작하지만 한 프로젝트 안에서는 하나로 통일합니다.
정리
main.ts는 app.config.ts의 프로바이더와 함께 루트 컴포넌트를 부트스트랩합니다.angular.json은 빌드·서브·테스트 타깃을 설정하고, public/에는 정적 파일을 둡니다.- TypeScript와 템플릿의 엄격한 검사는 켜 둡니다.
- 빌드별 값은
ng generate environments로 관리하고, 코드는 기능별로 묶습니다.
댓글 0개
로그인 · 로그인하면 댓글을 남길 수 있습니다.