又是许久没有动笔写博客了,18年换了公司,一直很忙。最近临近过年,几个项目也都告一段落,趁着测试和Refactor
Code的功夫,想总结一下自己过去三年使用Angular搭建项目的经验。
从当初使用Angular1到现在手里的Angular6,还有已经发布几个月的Angular7,不断迭代的Angular,不断进步,不断优化。
经验的积累使我感受到一个好的Angular项目结构对于开发和维护项目是多么的重要,他能够提升我们的开发效率,团队协作,统一规范,再大型的项目都可以很好的进行协同开发。
目前我负责的项目都会按照以下的结构来搭建:
首先app.routing.ts里面类似这样:
{ path: 'login', canActivate: [IsNotSignedInGuard], loadChildren:
'../pages/login/login.module#AppLoginModule' }, { path: '', loadChildren:
'../pages/layout/layout.module#AppLayoutModule' }, { path: '404', loadChildren:
'../pages/not-found/not-found.module#NotFoundModule' }, { path: 'password',
loadChildren: '../pages/password/password.module#PasswordModule' }, {path:
'**', redirectTo: '404'}
一:概述
这里layout是我们网站的主要布局,比如公共的header,footer,还有各个业务模块都会在里面,而login模块这里因为比较独立,所以设计在layout外部,找不到的路由都会跳转到404页面。canActivate是控制用户是否能够进入路由的权限guard,可以是异步的,比如从后端获取某些权限设置,然后处理权限逻辑,再决定何时执行observer.next(true)即可进入,否则不可进入,并执行你想要的操作。
pages文件夹是业务页面,可能包含非常多的模块,我们采用大家已经很熟悉的懒加载模式,各个模块里面包含各自的页面和组件,相对独立,便于维护不同的模块。如果是这个模块里面公用的组件,则会在这个模块文件夹下建立compoents文件夹,如果是整个项目公用的组件,则放在shared/components文件夹。
各个模块会引入自己需要使用的服务和管道,指令等。管道和指令一般都是整个项目公用的,放在shared文件夹下,遇到少数只有某一个模块特有的,就放在这个模块里面无妨。服务我们根据不同的功能模块,在shared/core文件下面建立各种不同的目录,里面主要包含两类文件,一类是XXXXX.data.ts,也就是model数据层,一类是XXXX.service.ts,也就是请求层。这样结构清晰,纯业务的model和service都在这边,和pages文件分离。类似这样:
二:shared文件
最开始我们需要建立的是shared.module.ts,在这里我们把原本经常在app.module.ts引入的各种基础的,公共的模块在这里统一管理,比如FormsModule,RouterModule,HttpClientModule,TranslateModule,还有全局引入的各种第三方库。
另外就是我们自己写的各种公共的组件,管道,指令,服务都需要在这里引入,声明,导出,方便整个项目使用。类似:
@NgModule({ imports: [ RouterModule, CommonModule, FormsModule,
HttpClientModule, ReactiveFormsModule, TranslateModule, ], declarations: [
TimeFormatPipe, AppLoadingComponent, QrCodeDirective, DecimalControlDirective,
MemberStatusPipe, ], exports: [ CommonModule, FormsModule, ReactiveFormsModule,
TimeFormatPipe, AppLoadingComponent, TranslateModule, DecimalControlDirective,
MemberStatusPipe, ], entryComponents: [TwoFactorDialogComponent] }) export
class SharedModule { static forRoot(): ModuleWithProviders { return { ngModule:
SharedModule, providers: [ DecimalPipe, HttpClientService,
CurrencyChannelService, UtilsService, CookieService, LanguageService,
LinkGuard, PrivateAuthBeforeRouteGuard, IsNotSignedInGuard,
InputNumberLimitPipe, CurrencyService, ExportDataService, ] }; } }
然后在app.module.ts里面,我们引入:
SharedModule.forRoot(),
这样在不同的功能模块里,我们只需要引入SharedModule,而不需要每次都做重复的引入表单等等一些公共的模块。
三:shared下面的各个内容:
1:component文件里面是项目共用的组件,比如loading,网络错误等等。
2: config文件是各种配置文件,比如一些常量,服务器地址,状态值,等等,基于单一原则,最好按照不同种类分开文件夹。
3:core文件是业务模型,网络请求,根据不同功能模块建立不同文件夹,数据Model和Service放在对应的模块下面。
4:directives是项目共用的指令,主要用来控制DOM变化,比如交互操作,表单输入操作,DOM显示
5:functions里面是公共的方法,比如每个model需要用到的parseData函数,处理解析对象
6:guard是各种路由权限控制逻辑
7:modules是非业务类的公共模块,比如我们封装的动态表单,或者其他的公共模块
8:pipes是公共管道,处理数据格式化
9:services是各种公共服务,比如我们自己封装的HTTP请求,Utils,大多是非业务类的,如果跟业务相关,那么也是比如导出数据这种和具体模块无关的,尽量保持这里的服务具有全局属性。
10:styles文件夹是我们自己的样式文件,比如我们项目的base.scss,button.scss这种。
四:总结
这样一个比较清晰的项目结构就搭建好了,数据和业务分离的非常独立,页面可以很方便的使用各种公共的工具,不需要太多重复的代码。
另外关于项目的数据流,最好全局使用RXJS进行开发,当然,这是另外一个课题了,不过,使用了RXJS来管理数据状态之后,你会爱上它的简洁优雅,函数式编程和强大的性能。
我们使用Angular可以提高我们的开发效率,开发出更好的产品,前提是我们一定要好好的使用它。学习之旅未止,后面我打算开始RXJS的系列博客,深入的总结和学习RX编程思想。