Angular 架構設計

引言

Alice測試上線,發現包體積太大,加載太慢。決定啓用懶加載與預加載加速加載速度。typescript

整三天,課也沒去上。改得時候特別痛苦,哭了,爲何沒有早點發現惰性加載這個東西。小程序

clipboard.png

星期一,從新設計前臺架構,重構前臺代碼。api

星期二,分模塊加載,啓用惰性加載與預加載。架構

星期三,修改單元測試,添加provideasync

星期四,寫PPTide

星期五,.NET考試。單元測試

重構前臺以後,以爲本身當前設計的架構很合理,遂分享出來,供你們學習交流。學習

架構

理論

架構理論主要參考外國老哥的一篇文章,Angular (2+): Core vs Shared Modules測試

clipboard.png

CoreModule:核心模塊,只被AppModule引用,保證全局單例。spa

ShareModule:共享模塊,被各業務模塊引用,存儲各模塊必備的組件、管道以及模板。

實踐

CoreModule

核心Module,全局只導入一次。

稱之爲核心,由於沒有它應用跑不起來。

clipboard.png

核心模塊存放攔截器和服務,不過與正常的有些區別。

攔截器

@Injectable()
export class YunzhiInterceptor implements HttpInterceptor {
}
@NgModule({
    imports: [
        NgZorroAntdModule,
        RouterModule
    ],
    providers: [
        {provide: HTTP_INTERCEPTORS, useClass: YunzhiInterceptor, multi: true}
    ]
})
export class CoreModule {
}

服務

@Injectable({
    providedIn: CoreModule
})
export class CollegeService {
}

如今不往root裏注入了,由於發現有的時候寫root有人會搞不清楚模塊的層級關係,而後就懵圈了。

爲了規避這種問題,直接注入到核心模塊中,防止有人誤解。

norm

實際上是想起一個規範的英文的,可是spec卻被測試給用了,因此就去百度翻譯了個放這了。

clipboard.png

這個包主要是存儲數據規範的。

entity存儲實體,對應後臺實體。

target存儲自定義的規範對象,歷史的教訓告訴咱們,若是把全部都放到實體包裏,這很糟糕。

page

這個是向小程序抄來的,小組件能夠複用,大組件就須要單建目錄了,都放一塊兒看着混亂。

clipboard.png

分模塊加載,每一個功能一個單獨的模塊,模塊職責劃分清晰。

@NgModule({
    declarations: [
        SetupComponent
    ],
    imports: [
        SetupRouteModule,
        ShareModule
    ]
})
export class SetupModule {
}

模塊中就這幾行,什麼廢話都不要寫,就聲明本模塊的組件,並導入本模塊的路由和Share模塊。其餘的都不要寫,第三方的導入交給ShareModule去處理。本模塊只負責業務,不負責代碼。

ShareModule

clipboard.png

全局複用的組件,全局複用的管道,全局複用的驗證器,以及其餘第三方組件的導入導出。

@NgModule({
    imports: [
        ComponentModule,
        PipeModule,
        RouterModule
    ],
    exports: [
        ComponentModule,
        PipeModule,
        RouterModule
    ]
})
export class ShareModule {
}

規規矩矩,整整潔潔。

clipboard.png

ShareModule的子模塊的實現都放在api目錄裏。

子模塊示例:

@NgModule({
    declarations: [
        CourseTypePipe,
        SemesterStatusPipe,
        YunzhiGradeStatusPipe,
        YunzhiKlassStatusPipe,
        YunzhiScoreStatusPipe
    ],
    exports: [
        CourseTypePipe,
        SemesterStatusPipe,
        YunzhiGradeStatusPipe,
        YunzhiKlassStatusPipe,
        YunzhiScoreStatusPipe
    ]
})
export class PipeModule {
}

spec

測試目錄,爲何單拿出來這個目錄,主要是爲了解決Service的測試數據問題。

clipboard.png

本模塊存儲全部以.test.service.ts結尾的測試service

clipboard.png

而後全部的測試Service去繼承原Service,並重寫裏面的方法,這裏的@Injectable()註解中不用加providedIn,由於沒有專業的測試模塊,每一個測試用例中咱們使用provide進行注入。

@Injectable()
export class CollegeTestService extends CollegeService {
}

原來直接跑ng test特別快,根本看不清楚組件的建立,這兩天發現了一個新套路,跑測試的時候上YouTube點開個視頻看,而後電腦就特別卡,測試跑的時候就慢了。

而後就能夠清楚地看到每一個測試用例的執行過程,看到每一個組件如何建立並顯示。也不知道改了哪裏,如今Alice跑測試的時候最後給出一個Karma的測試報告。

clipboard.png

直接把錯誤報出來,也好修改。

測試

測試最後怎麼設計的呢?也說不明白,看代碼就是了。最近才發現以前的測試用例寫得都不正確。

其實一個測試,就是構建了一個測試的模塊,該模塊和其餘模塊都相同。

發現不少測試中爲了能跑過,直接把公共組件或公共管道寫在了declarations裏,這是不合理的,雖然測試能跑過,可是理論上,這個測試就是測這個的,因此模塊中的declarations只有它本身。

而後這裏的imports也是通過反覆的測試,導入BrowserAnimationsModuleHttpClientTestingModuleRouterTestingModuleShareModule這四個模塊,這個測試的全部依賴就都有了,其餘的什麼都不要導入,看着混亂。

providers聲明本模塊中要注入的對象,這裏受益於CoreModule的設計,Service都放在了CoreModule裏,而業務模塊是不能導入CoreModule的,只能導入ShareModule,因此模塊中是用不了已有的Service

因此,乖乖地給我建一個測試的Service,而後注入進去。也算是強制組員寫測試的一種手段。

describe('SetupComponent', () => {
    let component: SetupComponent;
    let fixture: ComponentFixture<SetupComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [SetupComponent],
            imports: [
                BrowserAnimationsModule,
                HttpClientTestingModule,
                RouterTestingModule,
                ShareModule
            ],
            providers: [
                {
                    provide: UserService,
                    useClass: UserTestService
                }
            ]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(SetupComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });
});

總結

最佳實踐,都是從坑裏爬出來後才總結出來的。

clipboard.png

clipboard.png

上次我感慨Angular架構設計難的時候是426日,當時只是對Alice進行小改,還不到一月,現在一次性對前臺作了這麼大的改動,坑也踩得多了,爬出坑後,最佳實踐,其實就在眼前。

此次的架構設計得很整潔,打完包後也很快,我很滿意。

clipboard.png

古人學問無遺力,少壯工夫老始成。
紙上得來終覺淺,絕知此事要躬行。
——陸游《冬夜讀書示子聿》

之後再設計不能紙上談兵,要努力去實踐,經歷得多了,最佳實踐天然就出來了。

相關文章
相關標籤/搜索