在上一篇博客中,我向大家介绍了这个系列要开发的博客的技术栈以及总体架构图,相信大家对我们要开发的东西已经有了一个初步的了解。在这期博客中,就让我们把相关的软件工具安装好,并开始我们第一个angular项目。
三 软件工具的安装
1 node.js的安装
从node.js官网https://nodejs.org/zh-cn/download/下载node.js的LTS版本(当前为14.17.3),下载好后选好安装路径,一路next即可。安装完成后,打开cmd界面,输入node -v命令,若能显示版本号,则说明node.js安装成功。
2 angular的安装
我们通过npm工具来安装angular11。npm与node.js的关系就像pip与python的关系一样,npm是node.js提供的一个包安装工具,可以方便地安装、更新、卸载各种包。为了能更快地使用npm安装包,我们首先把npm的源设置为淘宝源:
在cmd窗口中输入以下命令:
npm config set registry https://registry.npm.taobao.org/
意思是将npm的config中的registry设置为淘宝源,可以使用如下命令来查看是否设置成功:
npm config get registry
在设置好淘宝源后,我们就可以开始使用npm来安装angular11了,以及后续的各种第三方angular插件也都是通过npm来安装的。
我们输入以下命令,来安装angular11:
npm install -g @angular/cli@11
来解释一下这条命令。npm install是命令的关键字,表示要通过npm来安装某个包;-g表示全局安装,即在任何工程中都可以使用这个包,这和稍后我们要安装的第三方插件包有一点区别;@angular/cli是包的名字,这个名字可以再拆分为两部分:scope和name。node.js的包遵循以下命名方式:[@scope/]name,其中scope是可选参数。所以,@angular/cli的含义是,angular提供的cli脚手架工具。再接下来的第二个@,表示要指定包的版本号。如果不指定版本号,默认是安装最新版本。这里我们只指定大版本为11版,如果需要更精确的版本指定,也可以将中版本和小版本写上。更详细的内容大家可以在cmd命令中输入npm help install命令来查看。
在输入完这行命令后,我们就可以等一会,等npm把angular装完,然后就可以新建我们的第一个项目了。
3 python的安装
到python官网https://www.python.org自行下载安装python即可,我这里选用python3.9.0。
在安装完python后,我们可以使用pip依次安装tornado,sqlalchemy和alembic:
pip install tornado
pip install sqlalchemy
pip install alembic
4 SQLite3的安装
我们可以去SQLite的官网https://www.sqlite.org/download.html去下载windows下的sqlite3工具sqlite-tools-win32-x86-3360000.zip,当然如果喜欢用图形界面的也可以自行下载Sqlite Expert。我们这里一般只是查看一下数据有没有成功插入,所以简单的命令行工具就足以满足我们需要了。
5 Nginx的安装
到nginx官网http://nginx.org/en/download.html下载windows版本即可,在开头的部分我们暂时用不到它。
6 推荐的IDE
Python这边显然是推荐Pycharm这款IDE,angular这边推荐VS Code+Angular插件:
好了,我们把这个系列要用的软件和工具都安装好了,下面让我们开始第一个angular项目。
四 新建angular项目
让我们来找一块风水宝地来正式建立我们的博客项目。我这里是建了三个目录,分别命名为TreeHoleDB,TreeHoleServer和TreeHole。TreeHoleDB用于存储sqlite3数据库,TreeHoleServer用于存放python的后端工程,而TreeHole用于存放前端的angular工程。
我们进入TreeHole,在该目录下打开cmd,输入如下命令:
ng new treehole
ng就是我们刚才安装好的@angular/cli脚手架工具提供的命令。通过ng命令,我们可以生成angular中各种所需要的东西,如项目、组件、服务、管道等等。我们在这里就是使用ng new命令来生成了一个angular的新项目,项目名为treehole。
在输入完命令后,等待大概5-6秒,会进入如下画面:
这里会让你选择是否要开启严格模式,即会增强语法检查,如在类中声明了变量没有初始化时,那么就一定要在构造函数中初始化之类的语法规范检查。这里我建议大家开启,所以这里我们选y。
紧接着,angular会问你是否需要angular的默认路由,这里我们也选择y,让angular来帮我们建立一个路由模块:
再然后,angular会让我们选择样式表的语言,这里我们选择SCSS,因为SCSS可以与CSS兼容,但CSS不能与SCSS兼容。如果我们选择CSS的话,有些第三方组件是基于SCSS的,这样我们就不能使用这种组件了。所以,为了兼容更多的组件,我们选择SCSS。
接下来进入到一个相对漫长的等待期,等angular把相关的包装完,我们的新项目就建好了。
我们在VS Code中打开这个项目,然后在下方的终端中输入如下命令:
npm start
这会开始编译angular项目,会编译一小会。
当看到编译完成时,我们就可以打开浏览器,输入localhost:4200,来查看我们的第一个angular项目:
如果大家看到以上画面,就说明我们的angular项目建立成功了!
五 angular中的重要文件
一个angular项目的初始目录结构如下图所示:
项目目录下有三个目录:e2e,node_modules和src,我们重点关注后面两个目录。node_modules是我们这个项目中用到的所有包,而src是我们项目真正的工作目录,之后的一切开发都会在这个目录中进行。
下面来看一下angular中的重要文件:
1 app-routing.module.ts
这个就是angular为我们提供的路由模块文件,通过这个文件,我们可以在之后指定url与组件的映射关系。在之后,我们会将url和组件的映射关系存储在routes这个数组里。
//app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
2 app.module.ts
对于angular项目来说,每个项目至少要有一个ng module作为root module,从而将整个项目启动起来。app.module.ts就是这个根模块的模块文件,在其中定义了这个模块声明的组件以及引入的模块:
//app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
从文件内容可知,该模块引入了NgModule,BrowserModule,AppRoutingModule这三个模块,并且声明了AppComponent这一组件。跟在import们之后的是@NgModule装饰器,由这个装饰器来表明该文件定义了一个NgModule。NgModule装饰器的参数均为json格式,其参数分为四项:declarations,imports,providers和bootstrap。declarations数组表示在这个模块中声明了哪些组件,这里就只有一个AppComponent组件;imports数组表示这个模块要使用哪些模块,只有将上面import的模块写在这个imports数组中,才可在这个模块下属的组件中使用;providers数组表示这个模块要提供哪些service,而bootstrap表明以哪个组件作为工程的启动组件。
3 index.html和styles.scss
工程的主页面,也是唯一的一个页面。因为angular通常用于开发单页面应用,不同的页面体现在不同的组件中,所以这是工程层面的唯一一个html页面,其余的html都隶属于各自的组件。
<!--index.html-->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Treehole</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>
这个页面很简单,仅包括html页面中最基本的元素——html,head,body标签。在body标签里的app-root标签表明它是一个angular组件,具体的页面逻辑全部写在了这个组件中。
而styles.scss是全局样式文件,以后我们可以把全局样式加入到这个文件中。
4 组件四件套
下面让我们来看一下app.component.html,app.component.scss,app.component.spec.ts和app.component.ts这四个文件。这四个文件是app组件的组成部分,任何一个组件都会包括html, scss,spec.ts和ts这四个文件。html用于描述组件在前端显示的样子,scss用于提供组件的样式,当然你也可以把样式写在html中;spec.ts是用于单元测试的文件,一般我们用不到;而component.ts是用于处理组件背后的逻辑的。总的来说,一个angular组件就包括了前端的显示部分(html,scss)和背后的逻辑部分,如包括从服务器中读取数据、表单验证等功能(compoent.ts)。通过angular组件的组织形式,可以将复杂的前端逻辑隐藏在html背后,使得代码更加简洁,且提高复用性。
由于html文件过长,这里不再贴上,只贴出app.component.ts的内容:
//app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'treehole';
}
组件和模块类似,都是通过一个装饰器来定义。组件的装饰器叫@Component,包括以下内容:selector,templateUrl和styleUrls。selector表明了当在外部使用这个组件时,要使用的html标签名称;templateUrl表示了组件所用的html文件;而styleUrls表示了组件要使用的样式文件列表。再往下是一个TypeScript类,之后的代码逻辑都要在这里书写。
5 package.json
这个json列出了当前工程需要的各种npm包依赖,下面来让我们看一下它有哪些关键字段:
{
"name": "treehole",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~11.2.14",
"@angular/common": "~11.2.14",
"@angular/compiler": "~11.2.14",
"@angular/core": "~11.2.14",
"@angular/forms": "~11.2.14",
"@angular/platform-browser": "~11.2.14",
"@angular/platform-browser-dynamic": "~11.2.14",
"@angular/router": "~11.2.14",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.11.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1102.13",
"@angular/cli": "~11.2.14",
"@angular/compiler-cli": "~11.2.14",
"@types/jasmine": "~3.6.0",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.1.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.5.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.1.5"
}
}
name、version:包的名称和版本。如果你要把你的工程发布出去,name和version会作为唯一标识符。当然如果不发布的话,那这俩值无所谓,一般也不需要特意去动它。
scripts:项目不同生命周期要跑的命令。
private:如果设为true的话,那么npm就不会把这个包发布出去,是防止误推送的一个机制。
dependencies:项目运行时所需要的依赖项,即生产环境中要用的依赖,需指定每个项的不同版本。
版本号有以下几种:~a.b.c,指a和b要和配置中一样,而并不在乎c是什么版本;^a.b.c,指a要和配置一样,而并不在乎b和c是什么版本。
举个例子,"@angular/cli" "~11.2.14",意思是可以用11.2.0-11.2.14的任何版本,但不能用11.1;"@types/node" "^12.11.1",意思是可以用12版,后两位版本无所谓,但就是不能用除12版之外的版本。
devDependencies:开发时所需要的依赖项,不会发布到生产环境中。
在这期博客中,我们安装好了所需要的所有软件和工具,并建立了我们第一个angular项目,也对angular项目的结构有了一个简单的了解。在下期博客中,我们将安装angular的第三方库,并开始构造我们的第一个组件,希望大家继续关注~