Angular初探
本文作为自己学习Angular的记录文,意在之后的用途中回顾所学的知识。目标是打造一个通过angular-cli生成的demo应用,汇集Module,Component,Service,模板语法,生命周期,组件间的交互,指令,管道,动画,Rxjs,国际化(i18n),懒加载,ssr(服务端渲染)等知识点的一个示例应用。
angular-cli
安装angular-cli
1
npm install -g @angular/cli
认识angular-cli
安装版本:@6.1.3
运行代码下述命令可查看帮助:1
ng --help
常用命令有如下,也可以在每个命令下加上 –help查看帮助
- ng new 新建
- ng generate 生成文件
- ng build 构建
- ng serve 运行服务
- ng help 帮助
- 初始化文件:
1
ng new demo --routing --style=sass --skip-tests
生成了一个带有路由模块,样式为sass(也可不带或者less),跳过测试文件的demo目录,所有初始安装包均已install。详细配置可查看ng new –help
- 开启服务
1
ng serve
详细配置可查看ng serve –help 例如–aot 开启aot编译(开发阶段常用jit编译,生产阶段常用aot编译)–host 监听的端口号等。
- 生成组件
1
2ng generate component home
ng g c home
生成了一个home的组件,generate可简写为g,component可简写为c,这样就生成了
- home.component.html
- home.component.sass
- home.component.ts
三个文件(如果之前没有通过配置项设置为内联引用的话)。
路由
在之前生成的app-routing.module.ts路由模块中添加如下代码:1
2
3
4
5
6import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', component: HomeComponent },
];
定义了home路由的模块组件已经空路由的重定向以及未匹配到路由的组件。注意:1
2
3
4@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
自能有一个根路由,其他的子路由用forChild,还需要把RouterModule模块导出,由app.module模块导入才能正常使用路由系统。
在app.component.html页面中:1
<router-outlet></router-outlet>
定义路由位置,只后匹配的路由组件会在该定义的下方展示
懒加载
一般为了首屏加载时间缩短会把其他路由定义为懒加载,angular中定义懒加载的方式也非常简单,但是也很强大,不仅能完成懒加载的任务,同时可以通过配置的方式实现守卫(在进入该路由前先检验权限),预加载等等。1
2ng generate module lazy
ng generate component lazy
通过命令生成lazy模块和lazy组件,另外再为lazy模块添加路由组件lazy-routing.module.ts1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LazyComponent } from './lazy.component';
const routes: Routes = [
{
path: '',
component: LazyComponent,
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LazyRoutingModule { }
最后在lazy的module中导入该路由模块,这样一个异步加载的模块就完成了。
服务端渲染
为什么要服务端渲染在这里就不多说了,这里主要关注的点在怎么实现服务端的渲染以及客户端渲染的切换(TODO 能通过webpack直接配置而不走angular-cli吗?)
通过下列步骤达到的效果:页面初始化时,走一遍服务器渲染,页面会很快的显示出来,但是一些点击事件是没有办法触发的,然后等待客户端的渲染,重新渲染一次根模块(会重新走根组件的构造函数),然后页面就是一个整正的客户端程序,完成切换。
- 安装依赖
1
npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine
@angular/platform-server - Universal 的服务端元件。
@nguniversal/module-map-ngfactory-loader - 用于处理服务端渲染环境下的惰性加载。
@nguniversal/express-engine - Universal 应用的 Express 引擎。
ts-loader - 用于对服务端应用进行转译。
在app.module.ts中导入BrowserModule模块
1
BrowserModule.withServerTransition({ appId: 'tour-of-heroes' }),
增加src/app/app.server.module.ts
这个模块是服务端渲染的入口模块代码地址增加src/main.server.ts
这是应用服务器入口点,需要在稍后的angular.json配置中用到1
export { AppServerModule } from './app/app.server.module';
server.ts
这是express框架的web服务器,理论上可以用任何的框架,只要它能调用 Universal 的 renderModuleFactory (TODO 这个用Koa测试一下)代码地址- 配置
- src/tsconfig.server.json
- webpack.server.config.js
- angular.json
最后在package.json中的scripts增加如下行:1
2
3
4"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:ssr": "node dist/server",
"build:client-and-server-bundles": "ng build --prod && ng run angular.io-example:server",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors"
- 运行
1
2npm run build:ssr
npm run serve:ssr
分别执行构建和启动服务器命令,完成!
总结
基本案例参考官网的步骤,也算是完成了效果,也由此引发了几点思考,在今后补充答案:
- 什么时候由服务端渲染切换成客户端渲染?
- 能不能不通过angular-cli的方式加载服务端渲染?
- 服务端的渲染能不能选择一些模块进行渲染,比如说只渲染首页的路由?
- 怎么用其他web服务器开启服务端渲染?比如说koa。。。