鹏叔(https://pengtech.net)

导航

创建angular项目

1. 说明

本项目使用的angular, nodejs, npm, cnpm版本如下

$ ng version
Angular CLI: 13.2.6
Node: 14.17.1
Package Manager: npm 6.14.13
OS: win32 x64

Angular: 13.2.7
... common, compiler, compiler-cli, core, forms, localize
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1302.6
@angular-devkit/build-angular   13.2.6
@angular-devkit/core            13.2.6
@angular-devkit/schematics      13.2.6
@angular/animations             13.3.1
@angular/cli                    13.2.6
@schematics/angular             13.2.6
rxjs                            7.5.5
typescript                      4.5.5

2. 打开命令行工具找到你要创建项目的目录

3. 创建项目

3.1. 创建项目命令

ng new <项目名称>

3.2. 创建项目示例

ng new <project_name>
# e.g. ng new angulardemo

如果要跳过依赖安装, 可以添加--skip-install

ng new --skip-install <project_name>
# e.g. ng new --skip-install angulardemo

3.3. 输入参数

执行以上命令是, 系统会询问两个问题

  1. 是否添加路由.
    如果创建项目的目的为了体验angular的指令, 模板, 语法, 编译过程等等, 不涉及页面跳转, 可以不需要添加路由.
    如果需要涉及到页面之间的跳转, 则需要添加路由功能.

    如果创建项目过程中下载依赖包不成功, 可以停止, 然后手动输入cnpm install安装依赖包
    使用--skip-install选项. 由于npm install经常会出现卡住没有反应的现象, 在创建项目过程中可以跳过安装依赖, 等项目结构创建完成后手动安装依赖包
    此时可以添加选项 --skip-install 例如 ng new angulardemo --skip-install

  2. stylesheet样式格式
    现代web开发, 已经不止css一种样式语法, stylesheet技术也在不断的进步和升级. angular集成的stylesheet包括传统的css样式, less, sass, scss, stylus. 这里可以选择自己擅长的技术. 选择样式意为着angular cli会帮我们添加相应依赖, 解析器, 配置. 在实际开发过程中, 我们也可以混合使用以上技术. 这些样式最终会被解析器, 编译成浏览器可以识别的css代码.

    如果要在命令行中指定css预处理器, 可以选项--style 例如 ng new angulardemo --style=scss 来指定

3.4. 项目目录结构介绍

执行完以上命令后系统会为我们创建很多文件. 下面对这些文件进行简单介绍.
执行完以上命令后, 项目的目录结构树大致如下.

Test
├── README.md
├── angular.json
├── karma.conf.js
├── node_modules
├── package-lock.json
├── package.json
├── src
    └── app
        ├── app.component.css
        ├── app.component.html
        ├── app.component.spec.ts
        ├── app.component.ts
        ├── app.module.ts
        ├── components
        ├── pipes
        └── services
    ├── assets
    ├── environments
    ├── favicon.ico
    ├── index.html
    ├── main.ts
    ├── polyfills.ts
    ├── styles.css
    └── test.ts
├── tsconfig.app.json
├── tsconfig.json
└── tsconfig.spec.json

3.4.1. 一级目录介绍

目录 说明
node_modules 第三方依赖包存放目录
src 应用源代码目录
.angular.json Angular命令行工具的配置文件。后期可能会去修改它, 引一些其他的第三方的包 比如jquery等
karma.conf.js karma是单元测试的执行器,karma.conf.js是karma的配置文件
package.json 这是一个标准的npm工具的配置文件,这个文件里面列出了该应用程序所使用的第三方依赖包。实际上我们在新建项目的时候,等了半天就是在下载第三方依赖包。下载完成后会放在node_modules这个目录中,后期我们可能会修改这个文件。
package-lock.json package-lock.json 是在 npm install时候生成一份文件,用以记录当前状态下实际安装的各个npm package的具体来源和版本号.
README.md 项目说明文件
tsconfig.json 是typescript的配置文件,用于配置typescript编译的一些选项.
tsconfig.app.json tsconfig.app.json是tsconfig.json的扩展. TypeScript编译器的配置,添加第三方依赖的时候会修改这个文件, 用于指定编译,打包,运行时的一些ts选项.
tsconfig.spec.json tsconfig.spec.json也是tsconfig.json的扩展, 用于指定运行测试时的一些ts选项.

3.4.2. 二级目录介绍

src目录:
| 目录 | 说明 |
| app目录 | 包含应用的组件和模块,我们要写的代码都在这个目录 |
| assets目录 | 资源目录,存储静态资源的 比如图片 |
| environments目录 | 环境配置。Angular是支持多环境开发的,我们可以在不同的环境下(开发环境,测试环境,生产环境)共用一套代码,主要用来配置环境的 |
| index.html | 整个应用的根html,程序启动就是访问这个页面 |
| main.ts | 整个项目的入口点,Angular通过这个文件来启动项目 |
| polyfills.ts | 主要是用来导入一些必要库,为了让Angular能正常运行在老版本下 |
| styles.css | 主要是放一些全局的样式 |
| test.ts | 也是自动化测试用的 |
| typings.d.ts | 对于一些纯js编写的nodejs模块, 在typescript中被引入时, 由于缺少类型定义,tslint会报告类型错误, 须在此文件中定义才能被typescript正常引用 |

3.4.3. 三级目录介绍

src/app目录
app目录是我们要编写的代码目录。我们写的代码都是放在这个目录。
一个Angular程序至少需要一个模块和一个组件。在我们新建项目的时候命令行已经默认生成出来了。
在src/app下可以建立更多子目录, 来存放相应的元素, 比如component存放到src/app/components下,
service存放到src/app/services下, pipe 存放到src/app/pipes目录下.

3.4.4. 项目是如何启动的

上一节我们讲到了angular项目的目录结构, 在如此复杂的目录结构中, 我们第一想了解, 也是应该了解的是项目的入口文件是哪个?
如果是做c, c++, java约定俗成的是找main方法. 在web1.0, 2.0开发中是找index.html. 当前我们所处的时代, 个人认为已经不能简单归属于web2.0时代了.
web2.0的标志是ajax技术的兴起即页面局部刷新. 而现代应用开发, 不仅仅是ajax的大量应用, 还包括前端开发的工程化, 模块化开发, 组件化趋势. 当然也不同于严格意义上的去中心化的web3.0, 暂且将其称为web2.0+时代. 在web2.0+从index.html源文件中, 我们已经无法明显的看出项目的入口在哪里了.
以下是项目生成后的index.html, 从该文件中我们能一眼看出项目的入口文件在哪里吗?
有人说, 我一眼能看出是<app-root></app-root>, 如果你认为项目的入口是app-root这个component的话, 那就是踏入了一个陷阱, 或者被误导了, 或者是一种想当然. 这就是wen2.0+中很明显的一种误导, 无论是angularjs 的class='app'也好, 还是vue的<app />也好, react的<div id="root"></div>, 这些主component或者根component的渲染都不是项目入口位置.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Test</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

不信我们打开app-root这个component看看.
从根component我们能看出, 服务是从哪里加载的吗, 路由是哪里加载的吗, 项目依赖的模块有哪些吗? 答案是不能, 而根component也只是众多普通component中的一个.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'test';
}

而项目真正的入口实际上是src/main.ts, 所以在angular开发中. 我们依然要找main, 而这个main不是main方法或函数, 而是一个main.ts文件.

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

而这里的main.ts, 也是一个默认的入口文件, 他是在angular.json的配置文件中指定的. 也就是说, 入口文件也是可以被修改的, 但是如非必要建议不要去修改入口文件的名字.
本来入口文件就很难找到了, 还要将其修改为一个更难理解的名字, 对new joiner是很不友好的, 毕竟项目需要更多的new joiner来维护, 改成一个更不约定俗成的名字, 无异于是当头棒喝. 对于一个angular老手来说, 当我们打开一个angular项目后, 还是要看看angular.json的指定的主文件到底是不是src/main.js

"options": {
            "outputPath": "dist/test",
            "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.css"
            ],
            "scripts": []
          },

知道了main.ts是入口文件后, 我们很容易就会发现, 项目启动使用的是下面这一行代码.
很容易猜测到AppModule里面应该会包含更多的信息, 怎么做到的? 靠得是一个开发者的嗅觉? 😃, 这是事后诸葛亮的的说法.
当然是靠探索精神, 当你拿到这样一段代码后, 当然要开始探索, 首先ctrl+click进platformBrowserDynamic发现是angular的api, 不是以下就能懂的.
然后在ctrl+click进AppModule, 一下就看到了component, services. 当然回过头来我们也要刨析一下platformBrowserDynamic 和 bootstrapModule, 但是这里我们先刨析app.module.ts这个文件.

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

打开app.module.ts, 可以看到, 项目的bootstrap(引导程序)是AppComponent.
从这里我们可以看出, 项目需要首先加载AppComponent, BrowserModule, 然后启动AppComponent, 由于main.ts会被编译挂载到index.html的<script></script>区域.
所以angular会在index.html中根据AppComponent的选择器selector: 'app-root' 找到<app-root></app-root>所处的位置渲染根component. 至此我们基本了解angular的启动过程了.

bootstrap的数据类型是array, 所以很明显, bootstrap属性可以指定多个component, 回到index.html, 说明angular是支持多根组件的, 也即index.html中可以指定多个组件<app-root></app-root>

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

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

打开编译后的index.html文件, 我们可以看到更加清晰的angular SPA程序的启动加载过程.
首先向服务器请求index.html, 然后加载runtime.js, polyfills.js, 异步加载styles.js, vendor.js, main.js,
最后渲染app-root组件. 如果路径是子目录, 例如http://localhost:4200/login 则涉及到angular路由的知识, 将在我的另一篇文章angular路由中讲到, 关注鹏叔的博客空间,查找更多angular相关文章.

<html lang="en">
 <head>
  <meta charset="utf-8">
  <title>Test</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="styles.css"><style>
 </head>
 <body>
  <app-root _nghost-nnf-c11="" ng-version="13.3.1">
  ..........
  </app-root>
  <script src="runtime.js" type="module"></script>
  <script src="polyfills.js" type="module"></script>
  <script src="styles.js" defer=""></script>
  <script src="vendor.js" type="module"></script>
  <script src="main.js" type="module"></script>
 </body>
</html>
  • 回过头来我再来深入刨析一下platformBrowserDynamic到底为我们做了些什么.

3.4.5. 重点文件介绍

3.4.6. 刨析一个component

创建component 可以使用

 ng g c <component_path/component_name>

这里的g表示generate生成的以上, c表示component, 最好使用component_path给component指定一个保存路径, 不至于使得项目过于扁平, 而component文件散落在项目根目录下. 命令执行完成后, 在component_path/component_name目录下会指定创建html, style, 测试文件, typescript等组件相关的文件.

3.5. 启动项目

3.5.1. 如果下载依赖包不成功, 可以停止

ng serve --open

--open 指定该选项会在服务器启动后自动打开项目首页,
也可以手动在浏览器端输入网站访问项目首页http://localhost:4200/

4. 创建新组件(component)

4.1. 使用命令行创建新组建

ng g component <path>/<component_name>
# 例如
ng g component components/news

另外使用ng g可以创建以下angular元素:

  • appshell
  • application
  • class
  • component
  • directive
  • enum
  • guard
  • interface
  • library
  • module
  • pipe
  • service
  • serviceworker
  • universal

5. angular 数据绑定

这里我们创建一个component, 并将其命名为TestDataBindingComponent, 用于测试数据绑定.

ng new component components/TestDataBinding

命令说明:

  • ng 是angular cli的主命令
  • new 为新建angular元素的子命令
  • component 为angular元素的类型, 更多元素可以参考上一节的angular元素列表
  • components/TestDataBinding 其中components为元素的存放路径, TestDataBinding为元素名称, 元素名称不必添加component后缀, angular会自动在创建元素时添加component后缀作为完整的元素名称.
  • 执行以上命令后, angular会在components目录下创建一个名为test-data-bingding的子目录, 里面会存储与conponent相关的 typescript, 样式文件, html文件, 以及测试文件. 同时该命令会修改src/app/app.module.ts, 自动添加对该component的引用.
  • 如果执行以上命令后, 发现拼写, 或者路径有误, 需要反悔时, 只需要删除components/test-data-bingding整个目录, 并修改src/app/app.module.ts将相关引用删除, 即可彻底清除该component. 当然在熟悉angular的原理以后, 发现问题可以做局部的修改, 这里不做展开.

posted on 2022-12-31 10:52  eagle.supper  阅读(224)  评论(0编辑  收藏  举报