angular-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseThe Scope Rule (REQUIRED)
作用域规则(强制要求)
"Scope determines structure" - Where a component lives depends on its usage.
| Usage | Placement |
|---|---|
| Used by 1 feature | |
| Used by 2+ features | |
「作用域决定结构」 - 组件的存放位置取决于它的使用范围。
| 使用范围 | 存放位置 |
|---|---|
| 仅被1个功能模块使用 | |
| 被2个及以上功能模块使用 | |
Example
示例
features/
shopping-cart/
shopping-cart.ts # Main component = feature name
components/
cart-item.ts # Used ONLY by shopping-cart
cart-summary.ts # Used ONLY by shopping-cart
checkout/
checkout.ts
components/
payment-form.ts # Used ONLY by checkout
shared/
components/
button.ts # Used by shopping-cart AND checkout
modal.ts # Used by multiple featuresfeatures/
shopping-cart/
shopping-cart.ts # 主组件 = 功能模块名称
components/
cart-item.ts # 仅被shopping-cart使用
cart-summary.ts # 仅被shopping-cart使用
checkout/
checkout.ts
components/
payment-form.ts # 仅被checkout使用
shared/
components/
button.ts # 被shopping-cart和checkout同时使用
modal.ts # 被多个功能模块使用Project Structure
项目结构
src/app/
features/
[feature-name]/
[feature-name].ts # Main component (same name as folder)
components/ # Feature-specific components
services/ # Feature-specific services
models/ # Feature-specific types
shared/ # ONLY for 2+ feature usage
components/
services/
pipes/
core/ # App-wide singletons
services/
interceptors/
guards/
app.ts
app.config.ts
routes.ts
main.tssrc/app/
features/
[feature-name]/
[feature-name].ts # 主组件(与文件夹同名)
components/ # 功能模块专属组件
services/ # 功能模块专属服务
models/ # 功能模块专属类型定义
shared/ # 仅用于被2个及以上功能模块使用的资源
components/
services/
pipes/
core/ # 应用全局单例资源
services/
interceptors/
guards/
app.ts
app.config.ts
routes.ts
main.tsFile Naming (REQUIRED)
文件命名规则(强制要求)
No , , suffixes. The folder tells you what it is.
.component.service.model✅ user-profile.ts
❌ user-profile.component.ts
✅ cart.ts
❌ cart.service.ts
✅ user.ts
❌ user.model.ts不要添加、、后缀。文件夹层级已经能说明文件类型。
.component.service.model✅ user-profile.ts
❌ user-profile.component.ts
✅ cart.ts
❌ cart.service.ts
✅ user.ts
❌ user.model.tsStyle Guide
风格指南
What We Follow (from official docs)
我们遵循的规则(来自官方文档)
- over constructor injection
inject() - and
classbindings overstyle/ngClassngStyle - for template-only members
protected - for inputs, outputs, queries
readonly - Name handlers for action () not event (
saveUser)handleClick - Keep lifecycle hooks simple - delegate to well-named methods
- One concept per file
typescript
@Component({...})
export class UserProfileComponent {
// 1. Injected dependencies
private readonly userService = inject(UserService);
// 2. Inputs/Outputs
readonly userId = input.required<string>();
readonly userSaved = output<User>();
// 3. Internal state
private readonly _loading = signal(false);
readonly loading = this._loading.asReadonly();
// 4. Computed
protected readonly displayName = computed(() => ...);
// 5. Methods
save(): void { ... }
}- 使用而非构造函数注入
inject() - 使用和
class绑定而非style/ngClassngStyle - 模板仅用成员使用修饰符
protected - 输入、输出、查询属性使用修饰符
readonly - 事件处理方法以动作命名(如)而非事件(如
saveUser)handleClick - 保持生命周期钩子逻辑简洁 - 委托给命名清晰的方法
- 每个文件仅对应一个概念
typescript
@Component({...})
export class UserProfileComponent {
// 1. 注入的依赖
private readonly userService = inject(UserService);
// 2. 输入/输出属性
readonly userId = input.required<string>();
readonly userSaved = output<User>();
// 3. 内部状态
private readonly _loading = signal(false);
readonly loading = this._loading.asReadonly();
// 4. 计算属性
protected readonly displayName = computed(() => ...);
// 5. 方法
save(): void { ... }
}What We Override
我们修改的规则
| Official Says | We Do | Why |
|---|---|---|
| | Redundant - folder tells context |
| | Same |
| 官方要求 | 我们的做法 | 原因 |
|---|---|---|
| | 冗余 - 文件夹已说明上下文 |
| | 同理 |
Commands
命令
bash
undefinedbash
undefinedNew project
新建项目
ng new my-app --style=scss --ssr=false
ng new my-app --style=scss --ssr=false
Component in feature
在功能模块中创建组件
ng g c features/products/components/product-card --flat
ng g c features/products/components/product-card --flat
Service in feature
在功能模块中创建服务
ng g s features/products/services/product --flat
ng g s features/products/services/product --flat
Guard in core
在core中创建守卫
ng g g core/guards/auth --functional
---ng g g core/guards/auth --functional
---