Angular-Cli创建项目的全部过程

华飞驰
2023-12-01
  • 使用 CLI 创建一个项目并配置默认路由:

ng new helloAngular –routing

如果要跳过npm install 安装,则使用以下命令:

ng new my-app --skip-install
  • 项目结构目录分析

|--E2e	应用的端对端(e2e)测试,用 Jasmine 写成并用 protractor 端对端测试运行器测试。
|--Node_modules	依赖包
|--Src	
|--App	Angular应用文件
|--App.module.ts	
|---App.component.ts	
|--assets	资源文件
|--environments	环境配置:开发、部署
|--index.html	应用的宿主页面。 它以特定的顺序加载一些基本脚本。 然后它启动应用,将根AppComponent放置到自定义<my-app>标签里。
|--main.ts	项目的入口文件
|--polyfills.ts处理浏览器兼容问题
|--angular.json	Cli配置文件
|--.editorconfig	统一代码风格工具配置,不支持的需要安装插件
|--.gitignore	Git配置文件
|--karma.conf.js	在测试指南中提到的 karma 测试运行器的配置。
|--package.json	项目指定npm依赖包
|--tsconfig.app.json	Typescript编译配置
|--tsconfig.spec.json	Typescript测试编译配置
|--tsconfig.json	Typescript编译配置
|--tslint.json	Typescript语法检查器

在新建的项目app文件下的根组件同一层级就会有一个ts文件【app-routing.module.ts】//用来定义根路由

注意:把 AppRoutingModule 导入 AppModule .ts文件,并把它添加到 imports 数组中。 Angular CLI 会默认为你执行这一步骤。但是,如果要手动创建应用或使用现存的非 CLI 应用,请验证导入和配置是否正确。 

此时在【app.module.ts】文件中就会新增如下信息:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './components/home/home.component';
import { LoginComponent } from './components/login/login.component';
//@NgModule接受一个元数据对象,告诉Angular如何编译和启动应用
@NgModule({
  declarations: [ //引入当前项目运行的组件
    AppComponent,
    HomeComponent,
    LoginComponent
  ],
  imports: [ //引入当前模块运行依赖的其他的组件
    BrowserModule,
    AppRoutingModule
  ],
  providers: [], //定义的服务回头放到这里
  bootstrap: [AppComponent]//指定应用的主视图(称为根组件),通过引导根Appmoudle来启动应用,这里一般写的是根组件
})
//根模块不需要导出任何东西,因为它就是最高层级的模块,不需要导入根模块,但仍一定要写
export class AppModule { }

同时在根组件的【app.component.html】文件中默认添加如下信息: 

<router-outlet></router-outlet>
  • 创建组件【homelogin

打开命令行,并且把路径cdapp目录

PS C:\Users\Desktop\angular练习\helloAngular\src\app>

在命令行中执行以下命令分别创建home组件和login组件

创建home组件
ng generate component components/home

创建login组件
ng generate component components/login

执行结果
S C:\Users\Desktop\angular练习\helloAngular\src\app> ng generate component components/home

CREATE src/app/components/home/home.component.html (19 bytes)

CREATE src/app/components/home/home.component.spec.ts (612 bytes)

CREATE src/app/components/home/home.component.ts (267 bytes)

CREATE src/app/components/home/home.component.css (0 bytes)

UPDATE src/app/app.module.ts (478 bytes)

PS C:\Users\Desktop\angular练习\helloAngular\src\app> ng generate component components/login

CREATE src/app/components/login/login.component.html (20 bytes)

CREATE src/app/components/login/login.component.spec.ts (619 bytes)

CREATE src/app/components/login/login.component.ts (271 bytes)

CREATE src/app/components/login/login.component.css (0 bytes)

UPDATE src/app/app.module.ts (567 bytes)

PS C:\Users\Desktop\angular练习\helloAngular\src\app>
  • 组件说明

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home', //使用这个组件的名称
  templateUrl: './home.component.html', //HTML模板
  styleUrls: ['./home.component.css'] //CSS样式
})
export class HomeComponent implements OnInit { //实现接口

  constructor() { //构造函数

  }

  ngOnInit(): void { //初始化加载的生命周期函数
  }

}

此时CLI会在app.module.ts文件中自动将这两个组件引入

angular模块类描述应用的部件是如何组合在一起的,每个应用都至少有一个angular模块,也就是根模块,用来引导并运行应用。你可以为他取任何名字。常规名字是AppModule,也就是app.module.ts文件
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './components/home/home.component';
import { LoginComponent } from './components/login/login.component';
//@NgModule接受一个元数据对象,告诉Angular如何编译和启动应用
@NgModule({
  declarations: [ //引入当前项目运行的组件
    AppComponent,
    HomeComponent,
    LoginComponent
  ],
  imports: [ //引入当前模块运行依赖的其他的组件
    BrowserModule,
    AppRoutingModule
  ],
  providers: [], //定义的服务回头放到这里
  bootstrap: [AppComponent]//指定应用的主视图(称为根组件),通过引导根Appmoudle来启动应用,这里一般写的是根组件
})
//根模块不需要导出任何东西,因为它就是最高层级的模块,不需要导入根模块,但仍一定要写
export class AppModule { }

 

此时只是引入,但若要访问,还要在在【app-routing.module.ts】文件中配置组件路由信息,以使我们的路由地址能够指向该组件,将其显示到我们的根组件当中‘’

  • 创建路由

import { NgModule } from '@angular/core';

import { Routes, RouterModule } from '@angular/router';

//引入(需要的)自定义组件

import { HomeComponent } from './components/home/home.component';

import { LoginComponent } from './components/login/login.component';



/* 【路由配置信息】 */

/* 路由配置使用符号“**”匹配时,注意顺序,路由匹配到信息不会再往后匹配 */

const routes: Routes = [

  // {path:'', pathMatch:'full', redirectTo:'home'}, /* 当为''的时候,从下面定义的路由中寻找,重定向到指定的组件home */

  // {path:'', component: HomeComponent}, /* 当为''的时候,重定向到指定的组件home */

  { path: 'home', component: HomeComponent },

  { path: 'login', component: LoginComponent },

  { path: '**', redirectTo: 'home' } /* [**]任意路由,匹配不到路由的时候加载组件或者跳转(重定向)的路由 */



];



@NgModule({

  imports: [RouterModule.forRoot(routes)],

  exports: [RouterModule]

})

export class AppRoutingModule { }

以上配置就实现路由链接的基本配置;从上文我们可以看出Angular cli帮我们干了如下事情:

src/app/ components目录被创建
components目录下会生成以下2个文件(home和login):

home和login目录下分别对应4个文件
CSS 样式文件,用于设置组件的样式
HTML 模板文件,用于设置组件的模板
TypeScript 文件,里面包含一个 组件类和组件的元信息
Spec 文件,包含组件相关的测试用例
这两个组件会被自动地添加到 app.module.ts @NgModule 装饰器的 declarations 属性中。

  • 默认选中路由

在根组件【app.component.html】文件中编写基本标签:

<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<!-- * * * * * * * * * * * The content below * * * * * * * * * * * -->
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * -->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<!-- * * * * * * * * * Delete the template below * * * * * * * * * * -->
<!-- * * * * * * * to get started with your project! * * * * * * * * -->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<h1>我是根组件</h1>
<!--target="_self"     不另外打开新窗口(默认)
    target="_blank"    另外打开新窗口
    routerLinkActive="active" -->
<a title="原生默认" href="http://www.jd.com" target="_blank">我们去京东</a> &nbsp;&nbsp;
<a title="blank打开" routerLink="/home" routerLinkActive="active">首页</a> &nbsp;&nbsp;
<a title="self打开" routerLink="/login" routerLinkActive="active" target="_self">登录</a> &nbsp;&nbsp;
<!-- 【等效代码】 -->
<a [routerLink]="['/home']" routerLinkActive="active">首页</a> &nbsp;&nbsp;
<a [routerLink]="['/login']" routerLinkActive="active">登录</a> &nbsp;&nbsp;

<!-- routerLinkActive指令在路由激活时添加样式class
        .active{
          color: red;
        }
        <a routerLink="/user/login" routerLinkActive="active">login</a>
        当url是user或者/user/login的时候,a标签将会被加上class 即active。当url变化为别的时,class将会被移除。
        如何添加两个class???
    
        <a routerLink="/user/login" routerLinkActive="class1 class2">login</a>

        routerLinkActive的两种写法
        <a routerLink="/user/login" routerLinkActive="class1 class2">login</a>
        <a routerLink="/user/login" [routerLinkActive]="['class1', 'class2']">login</a>
        重点来了: 使用routerLink元素的父元素上使用RouterLinkActive指令

        是不是给每个路由都分别添加样式好费事?给它父元素添加上路由高亮指令即可解决问题!

        <div routerLinkActive="red" [routerLinkActiveOptions]="{exact: true}">
         <a routerLink="/user/login">login</a>
         <a routerLink="/user/reset">reset</a>
        </div>

        只要给a标签的父元素div添加上routerLinkActive和routerLinkActiveOptions, 当路
        由是/user/login或/user/reset时其所在dom元素分别被添加上red样式。 这里需要注意的是要添加
        上routerLinkActiveOptions指定完全匹配,不然会出现url为user时两个路由均被匹配上添加了red样式。
       -->
<h2 style="text-decoration: underline">下面现显示的是当前选中路由对应的组件内容</h2>

<router-outlet></router-outlet>

 

  • app.component.ts文件分析

Angular应用中,模板指的的是@Component装饰器的templatetemplateUrl指向的HTML页面。例如:

import { Component } from '@angular/core';

@Component({
  // Angular应用中,模板指的的是@Component装饰器的template或templateUrl指向的HTML页面
  selector: 'app-root',
  // 根组件的templateUrl指向app.component.html,因为其与的子组件最终全部会显示在根组件中,这样也就做到了根组件
  // 对所有子组件的显示;正如子组件自己的**.component.ts文件中templateUrl地址指向自己的html文件;同理styleUrls也是如此
  templateUrl: './app.component.html', 
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'helloAngular';
}


// import { Component } from '@angular/core';
// interface Course {
//   id:number,
//   description:string
// }
// @Component({
//   selector: 'app-root',
//   // templateUrl: './app.component.html',
//或者直接将templateUrl这个参数直接改为一个template模板元素来显示对应模板元素中的内容
// 很明显Angular不是简单地用一个字符串来处理模板。 那么这是如何工作的?
// Angular不会生成HTML字符串,它直接生成DOM数据结构
// 实际上,Angular把组件类中的数据模型应用于一个函数(DOM component renderer)。 该函数的输出是对应于此HTML模板的DOM数据结构。
// 一旦数据状态发生改变,Angular数据检测器检测到,将重新调用
// 该DOM component renderer。

//   template:`
//     <div class="course">
//         <span class="description">{{courseObj.description}}</span>
//     </div>
//   `,
//   styleUrls: ['./app.component.css']
// })

// export class AppComponent{
//   title = 'ng-module-routes';
//     id:number = 1;
//     description:string = 'sss';
   
//    public courseObj: Course = {
//       id: 1,
//       description: "Angular For Beginners"
//   };
// }

 

  • 很明显Angular不是简单地用一个字符串来处理模板。 那么这是如何工作的?

Angular不会生成HTML字符串,它直接生成DOM数据结构,实际上Angular把组件类中的数据模型应用于一个函数(DOM component renderer)。 该函数的输出是对应于此HTML模板的DOM数据结构。

一旦数据状态发生改变,Angular数据检测器检测到,将重新调用DOM component renderer

 

  • 启动项目

安装完成之后就可以启动项目了,此命令可以在package.json文件中找到

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  }

打开命令终端到对应项目中执行以下命令启动项目

npm start 或者 ng serve //启动服务

ng serve命令会启动开发服务器,监听文件变化,并在修改这些文件时重新构建此应用
使用–open(或-o)参数可以自动打开浏览器并访问http://localhost:4200/

 

ng serve命令提供了很多参数,可以适当参考。
以下参数仅供参考:

--dry-run: boolean, 默认为 false, 若设置 dry-run 则不会创建任何文件
--verbose: boolean, 默认为 false
--link-cli: boolean, 默认为 false, 自动链接到 @angular/cli 包
--skip-install: boolean, 默认为 false, 表示跳过 npm install
--skip-git: boolean, 默认为 false, 表示该目录不初始化为 git 仓库
--skip-tests: boolean, 默认为 false, 表示不创建 tests 相关文件
--skip-commit: boolean, 默认为 false, 表示不进行初始提交
--directory: string, 用于设置创建的目录名,默认与应用程序的同名
--source-dir: string, 默认为 'src', 用于设置源文件目录的名称
--style: string, 默认为 'css', 用于设置选用的样式语法 ('css', 'less' or 'scss')
--prefix: string, 默认为 'app', 用于设置创建新组件时,组件选择器使用的前缀
--mobile: boolean, 默认为 false,表示是否生成 Progressive Web App 应用程序
--routing: boolean, 默认为 false, 表示新增带有路由信息的模块,并添加到根模块中
--inline-style: boolean, 默认为 false, 表示当创建新的应用程序时,使用内联样式
--inline-template: boolean, 默认为 false, 表示当创建新的应用程序时,使用内联模板

其他文件:
  .editorconfig: 给你的编辑器看的一个简单配置文件
  .gitignore: git 排除文件
  angular.json: angular cli 的配置文件
  package.json:npm 配置文件,项目使用到的第三方依赖包
  protractor.conf.js:运行 ng e2e 的时候会用到
  README.md:项目的基础文档
  tsconfig.json:TypeScript 编译器的配置
  tslint.json:运行 ng lint 时会用到
  • 补充

单元测试

Angular默认帮我们集成了``karma`测试框架,我们只需要执行:

ng test

端到端测试

ng e2e

构建应用程序,即项目打包

ng build

其中过程应该是这样的:
Angular CLI 从 .angular-cli.json 文件中加载配置信息
Angular CLI 运行 Webpack 打包项目相关的 JavaScript、 CSS 等文件
打包后的资源,将被输出到配置文件中 outDir 所指定的目录,默认是输出到 dist 目录。

其他命令

Angualr CLI提供了许多常用命令供我们选择:

ng generate class my-new-class // 新建类, 新建一个名为my-new-class的类 (class)
ng generate component my-new-component // 新建组件
ng generate directive my-new-directive // 新建指令
ng generate enum my-new-enum // 新建枚举
ng generate module my-new-module // 新建模块
ng generate pipe my-new-pipe // 新建管道
ng generate service my-new-service // 新建服务

 

 类似资料: