Angular 从框架搭建到开发上线的完整流程
一、环境准备与项目搭建
1. 环境要求
- Node.js (推荐 LTS 版本,当前 16.x/18.x)
- npm (随 Node.js 安装) 或 yarn
- Angular CLI (最新稳定版)
2. 安装 Angular CLI
npm install -g @angular/cli
# 或
yarn global add @angular/cli
3. 创建新项目
ng new my-angular-app --style=scss --routing
# 参数说明:
# --style=scss 使用 SCSS 作为样式预处理器
# --routing 生成路由模块
4. 项目结构概览
my-angular-app/
├── src/
│ ├── app/ # 应用主模块和组件
│ ├── assets/ # 静态资源
│ ├── environments/ # 环境配置
│ ├── index.html # 主HTML文件
│ └── main.ts # 应用入口文件
├── angular.json # Angular CLI 配置文件
├── package.json # 项目依赖和脚本
└── tsconfig.json # TypeScript 配置
二、项目配置
1. 核心配置文件
angular.json 关键配置
{
"projects": {
"my-angular-app": {
"architect": {
"build": {
"options": {
"outputPath": "dist/my-angular-app",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": [],
"stylePreprocessorOptions": {
"includePaths": ["src/styles"]
},
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
}
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
}
}
}
}
}
2. 环境配置 (environments/)
// environment.ts (开发环境)
export const environment = {
production: false,
apiUrl: 'http://localhost:3000/api',
enableDebug: true
};
// environment.prod.ts (生产环境)
export const environment = {
production: true,
apiUrl: 'https://api.yourdomain.com/api',
enableDebug: false
};
3. 代理配置 (解决跨域)
创建 proxy.conf.json
:
{
"/api": {
"target": "http://localhost:3000",
"secure": false,
"changeOrigin": true,
"pathRewrite": {
"^/api": ""
}
}
}
在 angular.json
中配置:
"serve": {
"options": {
"proxyConfig": "proxy.conf.json"
}
}
三、核心开发流程
1. 模块化开发
创建功能模块
ng generate module products --route products --module app.module
典型模块结构
products/
├── products.module.ts # 模块定义
├── products-routing.module.ts # 模块路由
├── components/ # 组件
├── services/ # 服务
├── models/ # 数据模型
└── interfaces/ # TypeScript 接口
2. 组件开发
创建组件
ng generate component products/product-list
组件示例
import { Component, OnInit } from '@angular/core';
import { ProductService } from '../services/product.service';
import { Product } from '../models/product.model';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProductListComponent implements OnInit {
products$: Observable<Product[]>;
constructor(private productService: ProductService) {}
ngOnInit() {
this.products$ = this.productService.getProducts();
}
}
3. 服务与依赖注入
创建服务
ng generate service products/services/product
服务示例
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class ProductService {
private apiUrl = `${environment.apiUrl}/products`;
constructor(private http: HttpClient) { }
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(this.apiUrl);
}
}
4. 路由配置
路由模块示例
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ProductListComponent } from './components/product-list/product-list.component';
import { ProductDetailComponent } from './components/product-detail/product-detail.component';
const routes: Routes = [
{ path: '', component: ProductListComponent },
{ path: ':id', component: ProductDetailComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ProductsRoutingModule { }
5. 状态管理 (NgRx 示例)
安装 NgRx
npm install @ngrx/store @ngrx/effects @ngrx/store-devtools
状态管理配置
// app.module.ts
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
@NgModule({
imports: [
StoreModule.forRoot({}, {}),
EffectsModule.forRoot([]),
StoreDevtoolsModule.instrument({
maxAge: 25,
logOnly: environment.production
})
]
})
export class AppModule { }
四、测试与质量保证
1. 单元测试 (Jasmine + Karma)
describe('ProductService', () => {
let service: ProductService;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [ProductService]
});
service = TestBed.inject(ProductService);
httpTestingController = TestBed.inject(HttpTestingController);
});
it('should retrieve products', () => {
const mockProducts = [{ id: 1, name: 'Test Product' }];
service.getProducts().subscribe(products => {
expect(products).toEqual(mockProducts);
});
const req = httpTestingController.expectOne(`${environment.apiUrl}/products`);
expect(req.request.method).toBe('GET');
req.flush(mockProducts);
});
});
2. E2E 测试 (Protractor/Cypress)
使用 Cypress (推荐)
npm install cypress --save-dev
测试示例
describe('Product List', () => {
it('should display products', () => {
cy.visit('/products');
cy.get('.product-item').should('have.length.greaterThan', 0);
});
});
3. 代码质量工具
ESLint 配置
ng add @angular-eslint/schematics
Prettier 配置
// .prettierrc
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2
}
Husky + lint-staged
// package.json
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.ts": [
"eslint --fix",
"prettier --write"
],
"*.{html,scss,json}": [
"prettier --write"
]
}
}
五、构建与部署
1. 构建生产版本
ng build --configuration production
2. 部署选项
静态服务器部署 (Nginx 示例配置)
server {
listen 80;
server_name yourdomain.com;
root /var/www/my-angular-app;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://api-server:3000;
}
}
Docker 部署
# 阶段1: 构建应用
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build --configuration=production
# 阶段2: 运行应用
FROM nginx:alpine
COPY --from=builder /app/dist/my-angular-app /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
3. CI/CD 配置 (GitHub Actions 示例)
name: Angular CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 16
uses: actions/setup-node@v2
with:
node-version: '16.x'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build for production
run: npm run build -- --configuration=production
- name: Deploy to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "dist/my-angular-app/*"
target: "/var/www/my-angular-app"
六、性能优化
1. 构建优化
- 启用构建优化器 (
angular.json
中buildOptimizer: true
) - 使用 AOT 编译 (默认启用)
- 启用生产模式 (
ng build --prod
)
2. 懒加载模块
const routes: Routes = [
{
path: 'products',
loadChildren: () => import('./products/products.module').then(m => m.ProductsModule)
}
];
3. 预加载策略
import { PreloadAllModules } from '@angular/router';
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
]
})
export class AppRoutingModule { }
4. 服务 Worker (PWA)
ng add @angular/pwa
5. 性能监控
import { PerformanceObserver } from 'web-vitals';
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('[Performance]', entry.name, entry.startTime, entry.duration);
}
});
observer.observe({ entryTypes: ['navigation', 'paint', 'resource'] });
七、维护与升级
1. Angular 版本升级
ng update @angular/core @angular/cli
2. 依赖管理
npm outdated
npm update
3. 更新日志
保持 CHANGELOG.md 文件记录重要变更
通过以上流程,您可以完成从零开始搭建 Angular 应用到最终上线的完整过程。根据项目实际需求,可以适当调整各个环节的配置和工具选择。