前言
都9102年了,筆者所在的公司的主要專案還是用AngularJS 1.6這種史詩的框架進行開發的。另外由於歷史的原因,程式碼的凌亂程度早已超越想象。為此,筆者決定痛下決心把整個專案重構了一遍…從此踏上了Angular升(跳)級(坑)之路。
先說說升級前後的變化:
專案管理:gulp -> gulp + Angular CLI
框架:AngularJS 1.6 -> AngularJS 1.6 + Angular 7
應用結構:多個AngularJS應用 -> 主專案:Angular、衛星專案:AngularJS
這個系列文章中涉及到
- Angular與AngularJS如何共存開發
- 使用Angular Cli編譯及開發Angular、AngularJS混合應用
—下面是坑,待填 - 如何在Hash模式中同步AngularJS、Angular的路由
- 在gulp或其他自動化構建工具中使用Angular CLI
- 在Angular中使用AngularJS的元件
- 在AngularJS中使用Angular的元件
本文使用的例子專案
AngularJS的例子專案angular-phonecat
為什麼升級為Angular框架
在筆者公司內部,大部分新專案已經開始使用Vue進行開發。筆者也更加傾向於Vue簡單、優雅的開發形式,較為符合前端(浪蕩)的開發模式。同時對於新手而言Vue更加容易上手。但對於筆者手上的專案而言,升級為Angular是為數不多可行的方案:
- 漸近式升級
由於專案年代久遠,專案涉及到了公司各個業務的方方面面。難以在短時間內完成全部的重構工作。在重構的同時,也需要兼顧到新業務的開發。(曾經這個專案在多個大佬的帶領下重構過,但無一倖免的全部夭折)。為此,選擇升級為Angular的第一考量的物件就是是否可以“在原有的基礎上進行重構”,而Angular官方提供的@angular/upgrade
則很好的解決了這個問題。直至完全重構為止,舊的程式碼仍能直接執行在專案中,不受重構的影響。 - 更加嚴謹的開發
在改造前的專案中包含了幾個5000+行的檔案,每次新增都非常“蛋疼”,出現這種問題的主要原因就是在這幾年間,都沒有對專案提交程式碼進行規範,同時也沒有進行Code Review等操作。使用TypeScript可以讓一部分Freshman放棄他們浪蕩的程式碼風格。此外,對於太過爛的程式碼,Angular甚至不能讓其編譯通過。這種框架以及語言特性決定了Angular更加擅長於開發更加嚴謹的專案。
當然,Vue也能使用TypeScript,經過規範的Vue編碼風格也能使其變得更嚴謹,前提是你得忍受編輯器對vue中的ts語言的支援:)
一、前期準備
檢查你的專案是否包含Angular cli無法支援的編譯特性。
在筆者公司專案中,使用gulp作為專案管理工具。其中包含了gulp-file-include
在html檔案中引入其他html片段的外掛,但是如果使用Angular cli(以下簡述為:ng cli)作為專案編譯開發工具,這些過程是不能被支援的。因此,應當先將它們去除。
安裝Angular CLI
筆者使用的是yarn:
yarn global add @angular/cli
複製程式碼
如果你是使用npm:
npm i @angular/cli -g
複製程式碼
二、新建一個種子專案
Angular的迭代更新速度是有目共睹的,筆者建議直接新建一個種子專案,而非直接複製本文提及的依賴關係。
具體的使用方法見官方文件
執行完畢後,將以下檔案複製到你的專案中:
- package.json
若專案中已存在package.json你可以直接複製與angular有關的依賴。"dependencies": { "@angular/animations": "~7.1.0", "@angular/common": "~7.1.0", "@angular/compiler": "~7.1.0", "@angular/core": "~7.1.0", "@angular/forms": "~7.1.0", "@angular/platform-browser": "~7.1.0", "@angular/platform-browser-dynamic": "~7.1.0", "@angular/router": "~7.1.0", "core-js": "^2.5.4", "rxjs": "~6.3.3", "tslib": "^1.9.0", "zone.js": "~0.8.26" }, "devDependencies": { "@angular-devkit/build-angular": "~0.11.0", "@angular/cli": "~7.1.2", "@angular/compiler-cli": "~7.1.0", "@angular/language-service": "~7.1.0", "typescript": "~3.1.6" } 複製程式碼
- tsconfig.json。typescript配置檔案
- angular.json。angular配置檔案
- src 目錄。angular原始碼資料夾,你可以將其放到你的專案中適當的地方。
三、新增升級依賴
在種子專案中,是不包含AngularJS升級模組的,你需要手動新增該模組。
yarn add @angular/upgrade
複製程式碼
四、將AngularJS的js、style交給angular cli管理
AngularJS的引入方式一般有兩種形式
-
使用了模組化的
如果本身已經使用了模組化的程式設計,那麼你要做的就是移除原本的模組引導器(如SystemJs等)、在index.html中移除ng-app。並在main.ts中import AngularJS入口檔案即可。
注意:你或許還需在tsconfig.json
中加入:"compilerOptions": { ... "allowJs": true, ... } 複製程式碼
-
一般引入形式的
如果專案中使用的是傳統引入形式,你需要將他們全部刪除掉,並在angular.json中projects -> porjectName -> architect -> build
中的styles
、scripts
屬性新增相應的樣式、js檔案。在此新增的檔案,angular cli會在編譯、開發過程中,進行合併壓縮操作。然後在index.html中將ng-app
移除。
新增assets資料夾
在AngularJS中,存在一些如templateURL
等,需要從伺服器載入的內容。因此,我們需要在angular.json中對映原始碼資料夾,使它能在serve
的過程中,能被訪問到。
具體路徑:angular.json projects -> porjectName -> architect -> build -> assets
五、在index.html中新增angular的入口
<app-root></app-root>
是angular的入口標記,你可以將其新增至index.html中合適的位置,一般為了結構一致,會放在與AngularJS相鄰的地方。
六、引導AngularJS模組
到這裡,你已經可以使用ng serve
進行開發了。但實際上,如果此時開始執行的話,在頁面中只會有Angular模組的內容,沒有AngularJS模組的內容。
實際上,js的指令碼已經通過ng cli進行處理,併合併為scripts.js,但由於在此前的操作中,我們將AngularJS的ng-app指令移除了。為此我們需要在angular載入過程中手動載入AngularJS模組。
app.module.ts
import { BrowserModule } from `@angular/platform-browser`;
import { NgModule, DoBootstrap, ApplicationRef } from `@angular/core`;
import { AppRoutingModule } from `./app-routing.module`;
import { AppComponent } from `./app.component`;
import { UpgradeModule } from `@angular/upgrade/static`;
@NgModule({
declarations: [
AppComponent
],
entryComponents: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
UpgradeModule
],
providers: [],
})
export class AppModule implements DoBootstrap {
constructor(private upgrade: UpgradeModule){}
// 手動接管載入程式
ngDoBootstrap(appRef: ApplicationRef) {
this.upgrade.bootstrap(document.documentElement, [`phonecatApp`]); // 引導AngularJS模組
appRef.bootstrap(AppComponent) // 引導Angular模組
}
}
複製程式碼
七、大功告成
現在執行ng serve
就可以看到同時執行Angular、AngularJS的頁面了!
(未完待續)
原始碼
由於篇幅有限,實際上還有幾處修改未在文段中展示。在此,你可以獲取到本文修改後的angular-phonecat專案。
[github.com/yskun/angul…]