Angular学习笔记
1、环境搭建
1.1 准备全局环境
1.1.1 安装运行时环境
node.js,可到官网自行下载稳定版本。node.js只需要在开发环境中安装,无需在发布环境中安装。为什么?因为开发环境需要使用到各种各样的开发工具:如webapck、@angular/cli、sass/less等等,这些工具等运行需要node.js环境。而发布环境中,项目已经打包成原生的javascript ,html和css文件,这些文件运行在浏览器中,浏览器中已经集成了javascript运行环境,如chrome,edge,firefox,safari。
node -v
1.1.2 安装包管理工具
如果选择使用npm (node package manager),则此安装步骤可以跳过,因为在安装node.js时会顺带安装npm。除了npm,还可以选择使用yarn作为包管理工具,这里以npm为例。
npm -v
1.1.3 配置源地址
编辑~/.npmrc文件,内容如下(使用阿里的淘宝npm镜像)
registry = https://registry.npm.taobao.org
1.1.4 安装angular开发工具包 @angular/cli
npm i @angular/cli -g
ng --version
1.1.5 安装IDE
可以选择比较流行的Visual Studio Code,可到微软官网免费下载。除此还可以选择其它IDE如WebStorm、Sublime等。
1.2 准备测试项目
使用@angular/cli代码生成工具创建测试项目原型。
ng new myapp
1.3 安装项目依赖包
切换到项目根目录 myapp,运行如下命令安装项目开发框架和开发工具包依赖。
npm i
1.3.1 开发框架包
根据项目功能需要选择安装,以下为angular框架常用包,除此外还有其它开发框架依赖包:如ng-zorro-and, echarts, rxjs等。
-
@angular/core
-
@angular/common
-
@angular/forms
-
@angular/compiler
-
@angular/router
-
@angular/animations
1.3.2 开发工具包
-
@angular/cli
-
@angular/compiler-cli
-
@angular-devkit/core
-
@angular-devkit/architect
-
@angular-devkit/angular-builder
-
@angular-devkit/build-optimizer
-
@angular-devkit/build-webpack
-
@angular-devkit/schematics
-
typescript
-
webpack
-
babel等等
1.4 运行测试项目
在项目根目录myapp下如下ng serve命令,--open自动打开浏览器,--port=4500使用4500端口。serve也可以简写成s,命令简化为:
ng s
ng serve --open --port=4500
至此,angular项目开发环境搭建完毕。
2、项目配置
2.1 package.json
{
"name": "myapp",
"version": "1.0.0",
"description": "this is my test angular app",
"main": "index.js",
"scripts": {
"run": "ng serve",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"hello"
],
"author": "roy",
"license": "ISC",
"dependencies": {
"@angular/animations": "^12.2.4",
"@angular/common": "^12.2.4",
"@angular/compiler": "^12.2.4",
"@angular/core": "^12.2.4",
"@angular/forms": "^12.2.4",
"@angular/platform-browser": "^12.2.4",
"@angular/platform-browser-dynamic": "^12.2.4",
"@angular/router": "^12.2.4",
"rxjs": "~6.6.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^12.2.4",
"@angular/cli": "^12.2.4",
"@angular/compiler-cli": "^12.2.4",
"tslint": "^6.1.3"
}
}
配置说明
配置项 | 配置说明 | 配置举例 |
---|---|---|
name | 项目名称 | myapp |
version | 项目版本 | 0.0.1 |
description | 项目描述 | this is my test project |
main | 项目的入口javascript文件 | main.js |
scripts | npm命令脚本集合 | { run: "ng serve", test: "echo 'hello npm' "} |
keywords | 项目关键字,用于发布后的搜索筛选,比如github上搜索你的项目。 | ["angular", "guide"] |
author | 项目作者 | roy |
license | 项目license | MIT |
dependencies | 开发框架、类库依赖包 | rxjs, echarts, @angular/core, ng-zorro-antd, zone.js等。 |
devDependencies | 开发工具依赖包,比如一些代码生成器,编译工具,测试工具,构建工具,dev server,代码压缩工具,代码优化工具,打包工具。 | @angular/cli, webpack, typescript, babel, tslint, karma, jasmine等。 |
包的版本配置:
版本范围约束方式 | 解释说明 | 举例 |
---|---|---|
~a.b.c | patch版本号变化,major和minor不变 | ~1.2.3 表示版本号要大于等于1.2.3,但要小于1.3.0 |
^a.b.c | minor和patch版本号变化,major不变 | ^1.2.3 表示版本号要大于等于1.2.3,但要小于2.0.0 |
major.minor.patch
a.b.c
2.2 package-lock.json
指定了依赖包等具体版本已经下载地址。
2.3 angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"myapp": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {},
"serve": {},
"extract-i18n": {},
"test": {},
"e2e": {}
}
}
},
"defaultProject": "myapp"
}
配置说明
配置项 | 解释说明 | 配置举例 |
---|---|---|
$schema | angular.json的schema验证文件,比如可以自动填充属性或属性值 | |
version | 项目版本 | |
newProjectRoot | 这个属性定义了由CLI创建的新的内部应用和库放置的位置。默认值为projects |
projects |
projects | 这个属性包含了工作空间中所有项目的配置信息,一个angular工作空间可以包含多个项目。angular项目的worksapce类似vs中的solution。 | |
projects\ {pn} | 项目名称 | My app |
projectType | 项目类型,如application表示是一个应用程序,如library表示是一个类库项目。 | application library |
schematics | schematics 属性配置 Schematics packages |
|
root | root 属性 指定了项目文件的根文件夹,可能为空,但是它指定了一个特定的文件夹。 |
|
sourceRoot | sourceRoot 指定了项目源文件位置 |
|
prefix | prefix 属性 当CLI创建 component 或者directive 时,使用该属性 来区别他们。 |
app |
architect | angular项目的核心配置,为本项目的各个构建目标配置默认值。 常用的构建目标有:build、serve、test、lint。 | |
build | 打包应用,对应构建器为@angular-devkit/build-angular:browser | |
serve | 启动应用,对应构建器为@angular-devkit/build-angular:dev-server | |
test | 测试应用,对应构建器为@angular-devkit/build-angular:karma | |
lint | 静态代码分析,类似coverity 对应构建器为@angular-devkit/build-angular:tslint | |
defaultProject | 默认工程,类似vs中的默认启动项目 "startup project" | myapp |
2.3.1 构建器
@angular/cli中的构建器,可以类比maven中的plugin插件,使用不同的plugin来完成对应的任务,如编译、测试、打包。
mvn compile
mvn test
mvn package
angular中常用的构建器有build、serve、test、lint,对应的命令如下:
ng build
ng serve
ng test
ng lint
下面对各构建器的配置做详细解释。
2.3.2 build构建器
"architect": {
"build": {
//build构建器所对应的npm包。
"builder": "@angular-devkit/build-angular:browser",
"options": {
//打包输出位置
"outputPath": "dist/myapp",
//主页面
"index": "src/index.html",
//angular的入口ts文件。
"main": "src/main.ts",
//typescript配置文件。
"tsConfig": "tsconfig.app.json",
//是否启用预编译,true表示启用。
"aot": true,
//需要打包的资源文件,如图片,字体,图标等。
"assets": [
"src/favicon.ico",
"src/assets"
],
//需要打包的全局样式文件,会自动添加到index.html <style>标签中
"styles": [
"src/styles.scss",
"./node_modules/bootstrap/dist/css/bootstrap.min.css"
],
//需要打包的脚本文件,如jquery.js, bootstrap.js等。
//这些脚本的加载方式和在 index.html 的 <script> 标签中添加是完全一样的。
"scripts": [
"./node_modules/bootstrap/dist/js/bootstrap.min.js"
]
},
//构建参数配置
"configurations": {
//开发环境打包配置项
"dev":{
"optimization": false,
"sourceMap": true
},
//测试环境打包配置项
"qa":{
"optimization": false,
"sourceMap": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.qa.ts"
}
]
},
//prod环境打包配置项
"prod": {
//需要替换的文件,可以制定多个文件。
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
//是否启用js代码混淆,压缩。
"optimization": true,
//?
"outputHashing": "all",
//是否启用sourceMap, dev环境应该启动,方便调试ts文件。
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {},
"test": {},
"lint":{}
}
2.3.3 serve构建器
"architect": {
"serve": {
//serve构建器对应的npm包。
"builder": "@angular-devkit/build-angular:dev-server",
//应用运行配置项
"options": {
//引用build构建器的配置,格式为{project_name}:{builder_name}:{env}.
//如果{evn}缺失,则使用dev环境配置。
"browserTarget": "myapp:build:dev",
//指定dev-server监听端口号。
"port": 4200,
//程序运行后是否自动打开浏览器。
"open": false
},
//当然,你也可以在ng serve 中修改所使用的环境配置,通过指定 --c={env}
//在你需要使用本地代码调试qa环境问题时,可以使用ng serve --c=qa 切换到qa环境运行。
//例如:ng serve --c=qa
"configurations": {
"dev":{
//这里无需对构建参数(如optimization,sourceMap等等)重复配置,只需要引用build构建器中配置好的环境即可。
"browserTarget": "myapp:build:dev"
},
"qa":{
"browserTarget": "myapp:build:qa"
},
"prod": {
"browserTarget": "myapp:build:prod"
}
}
},
"build": {},
"test": {},
"lint": {}
}
2.3.4 test构建器
TODO 待续
2.3.5 lint构建器
TODO 待续
2.4 tsconfig.app.json
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
//扩张配置文件
"extends": "./tsconfig.json",
//tsc编译选项
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"files": [
"src/main.ts",
],
"include": [
"src/**/*.d.ts"
]
}
具体配置请见《typescript学习笔记》的编译配置章节。至此,angular配置完成。
3、开发基础
在进行angular开发前,请学习TypeScript相关基础知识。
3.1 基础概念
3.1.1 Module
每个应用会有一个根模块,默认类名为AppModule,被放在app.module.ts
文件中,应用启动时,就会加载这个模块。 每个根模块会有一个根组件,默认为类名为AppComponent,放在app.component.ts文件中
,其selecor名字默认为app-root
。
查看项目目录中的index.html
,会发现有<app-root>Loading...</app-root>
这样的代码,就是在加载这个根模块。
3.1.2 Component
组件(component)是使用angular进行web app开发的功能单元,通常由模板、UI逻辑代码ts和样式组成。
1、html模板文件:负责页面布局和UI显示,属于View层;
2、typescript文件:负责页面UI逻辑和交互处理,属于ViewModel层;
3、样式文件:有css、sass和less三种,辅助html模板文件完成页面布局和UI显示,也属于View层;
4、model类文件:负责承接业务逻辑的计算结果数据,属于Model层。
model类文件一般在组件之间共享,不属于具体哪一个组件。
3.1.2.1 创建组件
以TestComponent组件的创建代码为例:
1、组件的ts代码
import { Component } from "@angular/core";
@Component({
selector: "app-test",
templateUrl: "./test.component.html",
styleUrls: ["./test.component.scss"]
})
export class TestComponent {
public componentName:string ="TestComponent";
constructor(){}
//todo
}
2、组件的模板html文件 test.component.html
<div>
<span>This is a test component: {{componentName}}</span>
</div>
3、组件的样式文件 test.component.scss, 样式文件还可以是 test.component.css或者test.component.lcss
span {
font-size:15px;
color: red;
}
4、组件注册
需要将组件注册到其所在的module中,这样组件才可以对外暴露出来,被同module下的其它组件或者其它module下的组件所使用。
具体操作为:将TestComponent放置于其所在module:AppModule的装饰器@NgModule的declarations参数中,如下代码所示。
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TestComponent } from './test/test.component';
@NgModule({
declarations: [
AppComponent,
TestComponent
],
imports: [
BrowserModule,
AppRoutingModule,
CommonModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
3.1.2.1.1 @Component装饰器
其定义如下:
export interface Component extends Directive {
/**
* Defines the used change detection strategy.
* 定义使用的变化检测策略
* 当一个组件被实例化时, angular创建一个变更检测器, 它负责
传播组件的绑定。
*"changeDetection" 属性的定义是, 是否每次都检查更改检测
或者只有当组件告诉什么时候去检测变化
*/
changeDetection?: ChangeDetectionStrategy;
# 定义一组只对其视图子DOM可用的可注入的对象
viewProviders?: Provider[];
# 使用 SystemJS 才用,现在一般很少使用了
moduleId?: string;
templateUrl?: string;
template?: string;
styleUrls?: string[];
styles?: string[];
# angular 动画库的一种内联写法
animations?: any[];
# 指定模版和样式封装方式,基本不用
encapsulation?: ViewEncapsulation;
# 重写默认的封装开始和结束符( `{{` and `}}`) 基本不用
interpolation?: [string, string];
# 定义其它组件在本组件被编译时,其它组件也被编译,一般用于动态插入组件的情况 用的比较多
# Angular 将创建一个 {@link ComponentFactory} 并且存储在 {@link ComponentFactoryResolver}上
entryComponents?: Array<Type<any> | any[]>;
}
export declare const Component: ComponentDecorator;
3.1.2.1.2 selector
组件选择器,定义了组件被引用时的标签名称,如app-nav在html页面中被引用时则表示为 <app-nav></app-nav> 。其中app前缀从配置文件中获得,当然你也可以通过修改angular.json配置文件来使用不同的标签前缀。
selector: "app-nav",
angular.json中的标签前缀配置:
"prefix": "app",
3.1.2.1.3 templateUrl
指定了组件对应的模板文件路径
templateUrl: "./nav.component.html",
3.1.2.1.4 template
如果组件对应的模板内容很少,可以将html内容直接赋给template,而不必去创建单独的html文件。注意,html内容要放在``中。
template: `<h2>{{headerText}}</h2>`
template和templateUrl两者只能选择一个。
3.1.2.1.5 styleUrls
指定了组件所使用到的样式文件路径,可以为多个。
styleUrls: ["./nav.component.scss"]
3.1.2.1.6 styles
和template对应的也有styles,当组件所需样式很少时,可以使用styles将样式直接赋给styles。
styles: `.container {color:red}`
3.1.2.1.7 encapsulation
定义了组件样式的封装方式,如下所示。默认设置为Emulated,为了防止组件样式影响其他组件,不要将encapsulation设置为None。
export declare enum ViewEncapsulation {
/**
* Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
* Element and pre-processing the style rules provided via {@link Component#styles styles} or
* {@link Component#styleUrls styleUrls}, and adding the new Host Element attribute to all
* selectors.
*
* This is the default option.
*/
Emulated = 0,
/**
* Don't provide any template or style encapsulation.
*/
None = 2,
/**
* Use Shadow DOM to encapsulate styles.
*
* For the DOM this means using modern [Shadow
* DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) and
* creating a ShadowRoot for Component's Host Element.
*/
ShadowDom = 3
}
3.1.2.2 使用组件
组件创建后,可以被其它组件引用,获取该组件的界面和功能,从而达到界面和功能复用的目的。
如下html片段为A组件的目标内容,app-chart-box为B组件的选择器 selector。A组件引用了B组件,从而具备B组件的界面和功能。
A组件的模板html
<div>
<app-chart-box></app-chart-box>
</div>
B组件的定义:
import { Component } from "@angular/core";
@Component({
selector: "app-chart-box",
templateUrl: "./chart-box.component.html",
styleUrls: ["./chart-box.component.scss"]
})
export class ChartBoxComponent {
//todo
}
3.1.2.3 根组件
一个Angular应用至少有一个根组件,一般命名为AppComponent,同一module中的子组件将会自动继承根组件的html模板。所以根组件一般用来创建应用程序界面布局框架,例如导航菜单、工作区div等。
通过导航切换到相应组件路由时,该组件的html内容会自动填充到<router-outlet></router-outlet>标签之中,而<router-outlet></router-outlet>以外的内容不变,从而实现框架页的功能。类似一些后端Web开发框架中的母板页,例如asp.net的master page,asp.net mvc的_layout.cshtml。
下例为一个应用程序的布局实现,在根组件中完成上下结构的布局方式,上面为导航菜单,下面为工作区。当然,你也可以根据实际需要对布局做出相应的调整,例如实现典型的左侧导航,右侧工作区的布局方式。
<div class="navContainer">
<ul>
<li>
<a [routerLink]="['home']">HomeComponent</a>
</li>
<li>
<a [routerLink]="['a']">AComponent</a>
</li>
<li>
<a [routerLink]="['b']">BComponent</a>
</li>
<li>
<a [routerLink]="['test']">TestComponent</a>
</li>
</ul>
</div>
<div class="wkContainer">
<h2>individual page content comes here</h2>
<router-outlet></router-outlet>
</div>
3.1.2.4 父子组件
被引用的组件为子组件,引用的组件为父组件。例如在A组件的html模板中引用了B组件的标签,则A组件是B组件的父组件,B组件是A组件的子组件。
假设B组件的selector为: app-b
A组件的html模板如下所说:
<div>
<h1>This is A Component>
<app-b></app-b>
</div>
3.1.2.5 组件间通信
组件间的通信可以分为如下几种情况:
3.1.2.5.1 子组件向父组件传值
父组件直接访问子组件的public属性;
父组件模板文件的html片段:
<app-b #child></app-b>
<h3>
{{child.name}}
</h3>
子组件ts文件代码片段:
public name: string = "Child Component";
3.1.2.5.2 父组件向子组件传值
使用@Output和@Input实现父组件向子组件传值
父组件:
import {Component, Output} from '@angular/core';
@Component({
selector: "app-a",
template: "./a.component.html",
styleUrls: ["./a.component.scss"]
})
export class AComponent {
@Output()
count: number = 0;
constructor(){
}
clickMe():void {
this.count++;
}
}
<p>a works!</p>
<button type="button" (click)="clickMe()">
Click Me
</button>
<app-b [messageB] = "count"></app-b>
子组件:
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-b',
templateUrl: './b.component.html',
styleUrls: ['./b.component.scss']
})
export class BComponent implements OnInit {
@Input()
public messageB:string;
constructor() { }
ngOnInit(): void {
}
}
<p>b works!</p>
<h2>{{messageB}}</h2>
3.1.2.5.3 父组件调用子组件方法
1、父组件直接访问子组件的方法;
父组件模板文件的html片段:
<app-b #child></app-b>
<button (click)="child.testMethod()">调用子组件方法</button>
子组件ts文件代码片段:
public name: string = "Child Component";
public testMethod(): void {
console.log("method is called");
}
2、通过@ViewChild注解,父组件可以直接访问子组件的方法,注意一定要在ngAfterViewInit事件以后访问,否则子组件还没来得及实例化,会报空引用问题。
父组件ComponentA.ts文件代码片段:
import { AfterViewInit, Component, ViewChild } from "@angular/core";
import { ComponentB } from "../b/b.component";
@Component({
selector: "app-a",
templateUrl: "./a.component.html",
styleUrls: ["./a.component.scss"]
})
export class ComponentA implements AfterViewInit {
@ViewChild(ComponentB)
private componentB: ComponentB;
//直接调用B组件的方法
public clickHandler():void {
this.componentB.testMethod();
}
public ngAferViewInit():void {
this.componentB.testMethod();
}
}
父组件ComponentA的html片段
<div>
<app-b></app-b>
<button type="button" (click)="clickHandler()">
Test
</button>
other html for component A.
</div>
子组件ComponentB的ts代码片段
import { Component } from "@angular/core";
@Component({
selector: "app-b",
templateUrl: "./b.component.html",
styleUrls: ["./b.component.scss"]
})
export class ComponentB {
//直接调用B组件的方法
public testMethod():void {
console.log("method is called.");
}
}
3.1.2.5.4 父组件订阅处理子组件事件
父组件为订阅方subscriber,子组件为发布方publisher。
父组件ts代码:
import { Componet } from '@angular/core';
@Component({
selector: "app-sub",
templateUrl: "./sub.component.html",
styleUrls: ["./sub.component.scss"]
})
export class SubComponent {
eventData:any;
onSomeEvent(data:any):void {
this.eventData = data;
}
}
父组件html代码:
<h2>{{eventData}}</h2>
<app-pub (someEvent)="onSomeEvent($event)"></app-pub>
通过(someEvent) = "onSomeEvent($event)"方式订阅子组件发布的事件,订阅方处理函数为onSomeEvent,参数$event为事件所传递的消息。
子组件ts代码:
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
@Component({
selector: 'app-pub',
templateUrl: './pub.component.html',
styleUrls: ['./pub.component.scss']
})
export class PubComponent {
//定义事件名称
@Output()
someEvent = new EventEmitter<string>();
constructor() { }
publish(): void {
//事件所传递消息
let data: string = "test data from pub";
//发布事件
this.someEvent.emit(data);
}
}
子组件html代码:
<button type="button" (click)="clickHandler()">Publish Event</button>
3.1.2.5.5 组件没有直接关系通信方式
1、借助于 Service 单例进行通讯 2、利用 cookie 和 localstorage 进行通讯 3、利用 session 进行通讯
3.1.3 Router
3.1.3.1 路由基本配置
配置angular路由:通常在app-routing.module.ts文件中。
import { NgModule } from '@angular/core';
import type { Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { NavComponent } from './nav/nav.component';
import { AdminComponent } from './admin/admin.component';
import { MenuAComponent } from './menu-a/menu-a.component';
const routes: Routes = [{
path: "home",
component: NavComponent
}, {
path: "admin",
component: AdminComponent
}, {
path: "menuA",
component: MenuAComponent
}];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
使用路由:一般在导航组件对应的html页面中。
<ul>
<li>
<a [routerLink] = "['home']">Home</a>
</li>
<li>
<a [routerLink]="['menuA']" target="_blank">Test Menu</a>
</li>
<li>
<a [routerLink]="['admin']">Admin</a>
</li>
</ul>
3.1.3.2 路由传值
TODO待续
3.1.4 Pipe
TODO 待续
3.1.5 Directive
TODO 待续
3.1.6 Service
TODO 待续
可以使用@angular/cli的代码生成功能添加,命令如下所示。
ng generate module my-module
# generate - g
# component -c
ng g c my-component
ng g pipe my-pipe
ng g router my-router
ng g directive my-dir
ng g service my-service
3.2 Angular内置指令
3.2.1 *ngFor
<li *ngFor="let item of testArray; let i=index; let c=count;">
{{i+1}} of {{c}}- {{item}}
</li>
let testArray:Array<string> = ["123","abc","def","CI/CD", "Docker","K8S"];
3.2.2 *ngIf
<li *ngIf="flag">Test Item </li>
let flag:boolean = false;
3.2.3 ngClass
<h1 [ngClass]="{'testH': true}">{{envName}}</h1>
.testH {
color:red;
}
envName:string = "";
constructor( ) {
this.envName = environment.name;
console.log(environment.name);
}
这里的true可以替换成表达式或者ts中定义的boolean变量。
开发基础内容较多,待续。
4、代码检查
4.1 ESLint配置
1、安装依赖
添加相关依赖包,在对应的package.json中的devDependencies节点内容如下:
"devDependencies": {
"@angular-devkit/build-angular": "^12.2.4",
"@angular-eslint/builder": "12.4.1",
"@angular-eslint/eslint-plugin": "12.4.1",
"@angular-eslint/eslint-plugin-template": "12.4.1",
"@angular-eslint/schematics": "12.4.1",
"@angular-eslint/template-parser": "12.4.1",
"@angular/cli": "^12.2.4",
"@angular/compiler-cli": "^12.2.4",
"@typescript-eslint/eslint-plugin": "4.28.2",
"@typescript-eslint/parser": "4.28.2",
"eslint": "^7.26.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"prettier": "^2.4.0",
"prettier-eslint": "^13.0.0"
}
npm i
2、配置ESLint
在项目根目录添加.eslintrc.json文件
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "_"
}
],
"@typescript-eslint/array-type": "error"
}
}
在angular.json中添加如下配置:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"myapp": {
"architect": {
"build": {},
"serve": {},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
//配置需要检查的文件pattern为src下所有的ts和html文件。
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
}
}
}
}
}
}
5、打包部署
5.1 打包项目
一般项目开发需要准备三套环境,dev, qa, prod,不同的环境有不同的配置。Angular默认提供了dev和prod环境的配置文件,默认放在src\environments下,如下所示。
5.1.1 dev环境
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false,
apiUrl: "http://localhost:12345/api/"
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
5.1.2 prod环境
export const environment = {
production: true,
apiUrl: "http://192.168.10.20:8080/api/"
};
5.1.3 qa环境
ng new生成的项目原型中默认没有qa环境的配置,需要自行添加,步骤如下:
步骤一:在src\environments 下新增environment.qa.ts文件,内容如下:
export const environment = {
production: true,
apiUrl: "http://192.168.10.19:8080/api/"
};
步骤二:修改angular.json文件,在architect\build\configuration节点下新增qa环境配置,内容如下:
"configurations": {
"dev": {
"optimization": false
},
"qa": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.qa.ts"
}
]
},
"prod":{
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
}
}
在代码中使用相应的配置,比如用于后台api访问的基地址 apiUrl。
import { Component } from '@angular/core';
import {environment} from 'src/environments/environment';
@Component({
selector: 'app-nav',
templateUrl: './nav.component.html',
styleUrls: ['./nav.component.scss']
})
export class NavComponent {
constructor( ) {
console.log(environment.apiUrl);
}
}
在项目根目录如下如下命令,分别给prod, qa, dev环境打包,打包后的文件默认放在项目根目录下的dist文件夹下。
ng build --c=prod
ng build --c=qa
ng build --c=dev
5.2 部署项目
以nginx为例,将打包后的文件部署到web服务器。
5.2.1 部署准备
1、安装nginx
2、将dist下的文件拷贝至目录web服务器(使用centos),可以选择使用xManager套装中的xftp,将本地文件拷贝至服务器目标位置,比如: /data/www/myapp 。
5.2.2 部署执行
server
{
#监听端口
listen 4500;
#域名可以有多个,用空格隔开
server_name xxx.com.cn;
index index.html index.htm index.php;
root /data/www/myapp;
...
}
2、启动nginx服务,访问myapp首页
cd ~/nginx/sbin
./nginx
3、如需修改conf文件,需要运行如下命令重新加载
./nginx -s reload
至此、项目打包发布完成。