Dojo 進階

官網 https://dojo.iohtml

序言 - 構建企業級 web 應用程序

在熱衷敏捷交付的時代,鼓勵將小功能點持續地交付給用戶。軟件行業開始青睞這種方式,由於它最大限度地下降風險,並最大限度地提升用戶的參與度和滿意度。git

即便採用現代的交付方式,一些風險仍然不可避免。複雜性就是這樣一種風險,對於成熟的應用程序而言,複雜性更成爲一個重要的關注點。不管應用程序遵循什麼樣的系統架構,隨着時間的推移,許多小功能彙集出一個龐大且使人畏懼的代碼庫,須要幾個團隊監督。程序員

應用程序上線的時間越久,實現一個設計簡潔的新功能的機會就越少。相反,更多的是在現有功能的基礎上調整、修復 bug 或擴展。一個成功的應用程序——以及所包含的功能——大部分時間都花在維護上。github

維護複雜的應用程序須要通過嚴格的訓練。團隊很容易陷入泥潭,將時間花在抱怨代碼和同事上面,而不是向用戶交付價值。要下降這種風險涉及不少方面,包括標準化、模式化、技術選型和工具等領域。web

管理複雜性

在軟件交付的生命週期中,錯誤發現的越早越好。在開發階段修復一個錯誤,比在交付環節修復錯誤,或者已給用戶帶來負面影響的上線階段修復錯誤要快的多,成本也低得多。typescript

強類型

早期捕獲錯誤的好方法是在應用程序的開發階段支持強類型。若是應用程序的代碼中顯式指定了類型信息,就能夠避免數據類型不匹配而致使的邏輯錯誤。編譯器和靜態類型檢查程序能夠驗證類型信息,並當類型不匹配時讓構建失敗。只有修復了這些錯誤,軟件才能從我的的工做空間進入到交付管道的後續環節。數據庫

Dojo 構建在 TypeScript 之上,提供了顯式的類型和靜態編譯時的類型檢查。使用 Dojo 構建的應用程序能夠用到 TypeScript(而不是普通的 JavaScript)帶來的優點。瀏覽器

當使用 Dojo CLI 構建應用程序時,應用程序的構建過程會默認包含 TypeScript 的編譯階段。開發人員從一開始就能編寫出類型安全的應用程序。安全

模塊化——單一職責原則

理想狀況下,一個組件應該足夠小,以便它只實現單一職責。一個組件越簡單、封裝程度越高,則大量程序員長期理解和維護時就越容易。擁有龐大代碼庫的大型應用程序就是由大量的更小、更容易理解的組件組合而成的。性能優化

試圖下降複雜度時,在單個組件中隔離職責有如下好處:

  • 限制範圍。假設組件維護一套一致的 API,則能在不影響外部用戶使用的狀況下更改內部實現。相反,組件的詳細信息保存在定義模塊的內部,這意味着其定義不會與其餘組件的定義衝突,因此就不會與其餘組件的命名約定重疊。
  • 簡化測試需求,由於單元測試只需關注單一職責,而不是多個條件組合成的愈來愈多的應用程序邏輯。
  • 組件能夠在多處重用,避免多處重複實現。修復錯誤時,只需專一於單個組件,而不是散落在各處的單獨實例。

對於 web 應用程序而言,隔離還能爲終端用戶帶來額外的好處。應用程序能夠劃分爲多個層,用戶在給定的時間點只加載他們感興趣的層。這減小了資源大小和網絡傳輸需求,從而縮短了加載時間。

Dojo 應用程序的組件

Index 網頁

HTML 頁面是每一個應用程序的基本內容,Dojo 應用程序也不例外。傳統上,單個 index.html 文件既是應用程序的入口點,也是將應用程序的總體結構存入 DOM 的根容器。

Dojo 應用程序一般會注入到單個 DOM 元素中,默認狀況下是注入到 document.body 中。這使得 Dojo 應用程序能夠與頁面中的其餘內容共存——靜態資源、傳統的應用程序、甚至是另一個 Dojo 應用程序。

部件

Dojo 中的部件與 DOM 元素相似,是 Dojo 應用程序中封裝的核心概念。正如傳統網站是經過 DOM 元素逐層構建的同樣,Dojo 應用程序則是經過部件逐層構建的。

部件能夠描述一切,從單個界面元素(如 label 或 textbox)到更復雜的容器(如 form 表單、頁面或者整個應用程序)。

相似地,並不是 DOM 中的全部元素都對用戶可見,Dojo 部件不只提供用戶界面,也能夠實現應用程序的全部幕後需求。

詳見建立 Dojo 部件參考文檔,瞭解如何在應用程序中建立部件。

TypeScript 模塊

Dojo 部件能夠是一個渲染函數工廠或者 TypeScript 類,一般包含在單個 TypeScript 模塊中。該模塊封裝了組成部件的大部份內容,包括它的行爲以及虛擬 DOM 的語義化表示。

部件經過屬性接口向外部消費者提供 API。這個接口既可包含狀態字段列表,在渲染時注入到部件中;也能夠包含函數,當事件發生時,部件須要通知應用程序的其餘部分時調用,好比部件狀態的變動。

CSS 模塊

部件的外觀樣式是交由 CSS 設置的,與常規的 HMTL 元素樣式相似。CSS 模塊用於封裝單個部件的樣式,避免與其餘部件的 CSS 類名衝突。

部件導入 CSS 模塊跟導入其餘 TypeScript 模塊同樣,並容許經過對象屬性引用 CSS 類名,這些屬性會在開發人員的 IDE 中自動提示。在定義部件的語義元素結構時,可使用這些屬性名指定樣式類。部件中的 CSS 類名和最終的樣式類名不一致,而這能夠在構建階段識別出來。

雖然部件的 CSS 模塊能夠徹底封裝自身的樣式,但一般也須要一些靈活性。部件能夠在應用程序的不一樣配置下使用,每一個配置都有本身獨特的外觀需求。Dojo 提供了覆蓋特定樣式的能力以知足這個需求。

爲了支持應用程序層面外觀的一致性,能夠經過主題進一步控制部件的樣式。

詳見 Dojo 樣式和主題參考文檔,瞭解如何爲單個部件設置樣式。

狀態管理

企業應用程序一般須要持久化狀態,並容許用戶以各類方式查看和操做這些數據。當須要同時在多處訪問和編輯同一數據,且要保持數據的一致性時,狀態管理能夠成爲大型應用程序中最複雜的領域之一。

狀態一般存在位於 web 應用程序組件外部的數據存儲或數據庫中,這意味着一些狀態管理複雜性須要在應用程序以外解決。然而,對於數據在應用程序與其用戶之間流動的狀況,有幾個範例可以大大的下降管理複雜狀態的風險。

響應式的數據修改

以命令式方式編寫的應用程序會描述應更改哪些數據,應該如何更改,以及指定必須在什麼時候何地更改。若是經過某種形式的計算或賦值在邏輯上鍊接多塊數據,則這些鏈接在一段時間後只能表示成離散的點。長此以往,除了這些點以外,可能會以違反預期邏輯鏈接的方式修改任何數據值。

相反,以響應式方式編寫的應用程序設法提高數據之間的邏輯鏈接,並放棄對明確地指定什麼時候何地修改數據的控制,以使邏輯數據鏈接始終保持一致。

具備多個服務層的複雜應用程序可能會在多處描述相同的數據,由於它們散落在應用程序的各處——這方面的一種常見模式是使用數據傳輸對象。一段數據的描述位置越多,則維護應用程序狀態完整性的複雜度呈指數級增加。

任何應用程序只要 UI 須要動態展現(包括 web 應用程序),都會遇到維護邏輯數據鏈接一致性的問題。這些應用程序中的數據一般至少有兩種表示方式。

舉例說明問題

假設有一個代辦事項應用程序,它存儲了一組任務,當向用戶顯示時,每一個任務都有如下兩種數據表示方式:

  • 任務的確切描述(它的「真實來源」,例如它在數據存儲中的值)
  • 任務描述的副本,經過 UI 元素(如 label 或 textbox)呈現給用戶。

若是用戶只能查看任務,則有幾個問題與如何修改任務的描述以讓用戶可見有關。

若是在底層的數據存儲中更改了任務,則須要經過 UI 向上傳播新的描述信息,這樣用戶就不會查看過期的數據。若是任務顯示在 UI 的多個位置,則全部實例都須要更新,確保用戶不會在不一樣位置看到的數據不一致。

若是用戶還能夠修改任務(好比更改描述信息),則還須要解決其餘問題。

任務描述如今有兩處真正的來源:數據存儲中的舊值,以及用戶在 textbox 中輸入的新值。

而後,須要將修改請求傳回給底層的數據存儲,以便用新值替換舊值。修改完成後,須要將新的任務描述返回給用戶,讓用戶看到更改後的正確值。嘗試修改任務描述時會發生的任何錯誤也須要在數據交換時考慮。

Dojo 的狀態管理

對於最基本的狀態管理需求,部件可使用本地變量管理自身的狀態。雖然這種方法有助於隔離和封裝,但它只適用於很是簡單的用例,如只在應用程序中出現一次的部件,或者與應用程序處理的全部其餘狀態都斷開了鏈接的部件。

隨着在部件間共享狀態的需求增長,Dojo 支持響應式的控制反轉。將狀態提高到父容器部件中,而後使用子部件的 properties 接口注入到子部件中。若是須要,這種狀態提高能夠橫穿整個部件層級,將狀態集中在應用程序根部件中,而後將部分狀態注入到相關的子分支中。

對於更復雜的需求,或者對於較深的部件層級且不但願在不相關的中間層傳遞狀態,則外部的數據存儲多是最好的方法。集中的數據存儲可以幫助應用程序處理大量的狀態,容許複雜的狀態編輯操做,或者在多處請求相同的狀態子集。

Dojo 提供了一個 Store 組件,它支持多種高級的狀態管理需求,例如:

  • 內置支持異步調用,例如調用遠程服務進行數據管理。
  • 狀態操做按肯定的順序執行。
  • 記錄狀態操做歷史,容許回滾或撤銷操做。
  • 中間件用於包裝數據操做流程,可添加橫切點,如用於受權或記日誌。
  • 內置支持基於 LocalStorage 的數據存儲,有助於實現 PWA。
  • 支持樂觀的數據更新,失敗時會自動回滾。

用戶體驗

Web 應用程序本質上是經過用戶界面提供體驗的,應用程序的做者須要考慮各類因素,以向用戶展現最好的界面。一致的可視化外觀和可訪問性一般是最顯眼的因素,但也須要關注效率和性能,不管是應用程序的邏輯,仍是交付的內容,都有助於提高 web 應用程序的用戶體驗。

主題

應用程序提供最佳用戶體驗的一種方式是向最終用戶提供一致的外觀。這可能與在相似的元素中使用一致的字體同樣簡單,但一般會擴展到使用相同的色調顯示應用程序,甚至實現一整套設計語言,如 Material Design。

Dojo 的樣式管道使用 CSS 模塊將樣式規則封裝到特定的部件中,避免在大型代碼庫中交叉污染。可是,樣式並非徹底隔離的——集中的 CSS 變量可以定義公共的主題屬性並在應用程序的全部部件間共享。也能夠爲 Dojo 部件套件提供自定義主題。

詳見 Dojo 樣式和主題參考文檔,瞭解如何建立應用程序主題。

UI 部件套件

經過部件套件,Dojo 提供了一些現成的 UI 組件。開發人員能夠當即使用這些部件製做許多常見的頁面,如 combobox、button、list、tab、text input 和 calendar 等部件。

Dojo 的部件支持國際化、可訪問性主題,讓開發人員在無需自定義 UI 組件的狀況下,可以靈活的交付應用程序專有的用戶體驗。

導航路由

雖然有些應用程序爲用戶提供了一個主視圖,其中能夠處理大部分工做,但不少應用程序中用戶須要訪問更多的區塊。幫助頁面、設置面板或者分步驟工做流這些例子中,應用程序可能有多個界面,用戶能夠在任什麼時候間訪問這些界面。

應用程序的每塊內容都須要惟一標識符,這樣用戶就能夠訪問它們。這些標識符也必需要支持爲連接設置書籤和分享連接,以便跳轉到應用程序特定區塊。用戶也須要在不一樣區塊間導航,以即可以訪問應用程序提供的全部功能。導航能夠前進到下一步、後退到上一步或者根據用戶的選擇在多個選項間跳轉。

使用靜態文件的傳統網站包含可單獨識別的內容,由於站點中的每一個靜態文件都能單獨訪問。HTML 文件可以使用錨點元素,經過點擊連接在不一樣文件間導航,而沒必要手動修改瀏覽器地址欄中的 URI。

顧名思義,單頁面 web 應用程序只有一個主文件,用戶經過該文件訪問整個應用程序。可是,這些單頁面應用可使用 URI(連同 URI 已有的優勢)來標識每個小節。

路由組件爲跨層級的路由提供了導航選項,並會將相應的已標識的路由分發到相應的應用程序區塊。路由還將處理任何錯誤條件,例如導航到不存在的路由。

Dojo 路由

Dojo 的路由系統容許將 URL 的子路徑註冊爲路由,以連接到某個特定類型部件上,這個特定類型的部件稱爲 Outlet。當用戶導航到特定的路由時,將會渲染註冊到該路由上的 Outlet 部件。

當用戶導航到 Outlet 時,就會「渲染」 Outlet,但 Outlet 不多直接處理應用程序的渲染。Outlet 主要是處理導航的封裝器(傳入查詢參數或者處理錯誤的回調),而將渲染功能委託給應用程序中的其餘部件。

相似於在傳統 HTML 頁面中使用的錨點,應用程序可使用與 Outlet 關聯的 Link 部件向用戶提供導航選項。

當使用路由時,Dojo 的構建系統能爲應用程序中的全部頂級路由自動生成單獨的包。而後能夠根據須要將每一個包獨立的交付給用戶。

詳見 Dojo 路由參考指南,瞭解如何在本身的應用程序中實現路由。

效率和性能

高效的渲染

動態網站內容(即包含 JavaScript)成爲 web 的一部分已經有不少年了。長期以來,站點就能夠包含一些腳原本操做 DOM,進行添加、更新或刪除內容。可是,Web 的起源(至今仍然是它的一大關鍵特徵)是以靜態頁面爲基礎的。隨着時間的推移,瀏覽器的 DOM 實現獲得了優化,以便儘量高效地、快速地向最終用戶渲染靜態內容。

近年來,隨着 web 應用程序愈來愈複雜,瀏覽器已經過 DOM 性能優化作出了迴應,針對動態內容做了優化。然而,爲了渲染用戶界面,web 應用程序仍然須要與一套幾十年不變的命令式 API 交互。圍繞響應式數據傳播而設計的現代 web 應用程序須要一種更高效的方式,將用戶界面轉換爲網頁的 DOM。

Dojo 將 DOM 從應用程序中抽象出來,推薦使用響應式狀態流來最小化應用程序的樣板文件,同時提升了渲染性能。部件會在渲染函數中輸出虛擬節點,這些渲染函數使用虛擬 DOM 描述部件的結構層級。而後,框架以儘量高效的方式處理 VDOM 的渲染,只會影響實際須要修改的 DOM 元素。

須要從 DOM 中獲取具體信息來實現其需求的應用程序,Dojo 經過中間件系統提供了另外一種 DOM 抽象層。Dojo 中間件以一致的方式解決了這些問題,並仍然支持橫跨應用程序的響應式數據流。

應用程序的交付——分層和包

隨着 web 應用程序規模的增加,當一個任務只須要訪問一部分資源時,卻必須加載應用程序的全部資源,這樣效率就會愈來愈低。每個應用程序資源都有一個與大小相關的成本:內存空間需求和網絡上的數據傳輸;全部這些都會影響到用戶開始工做以前須要的等待時間。讓應用程序只在須要的時候加載所需的內容,從而將此成本保持在最低水平,這符合用戶的最大利益。

獲取應用程序的資源時,在 HTTP 資源協商方面會產生額外的開銷。客戶端須要請求數據,而後客戶端必須等待服務器發送完資源的最後一個字節。更嚴重的狀況下,開銷還包括 DNS 解析、TCP 鏈接重建和 TLS 密碼/證書協商。

瀏覽器能夠有效地減小這一開銷,可是瀏覽器不能徹底消除這一開銷——應用程序也有責任來減小資源傳輸的開銷。與資源的大小相比,獲取一個應用程序資源的開銷是相對不變的。獲取1KB 文件的開銷與獲取100KB 文件的開銷相似。

所以能夠經過兩種方式下降開銷:減小資源總數和增長單個資源的大小。web 應用程序能夠經過分層和將相關的資源打包來實現這兩種方式。

單個層中應該包含應用程序中特定功能相關的資源集。當用戶訪問該功能時,層中的全部資源可能同時加載。而後一個層包含的全部內容均可以打包到一個文件中,以便更高效地傳送給用戶。

自動分層

當使用 Dojo 的路由系統時,應用程序能夠從自動分層和打包中獲益。應用程序中的每一個頂級路由都成爲一個單獨的層,Dojo 的構建系統會自動打包每層內容。這樣就能夠對層分離,以及打包資源,而不須要配置額外的工具鏈。這種自動化方案有一處折衷,即在每一個包中都內聯和複製了跨多個層的公共依賴項。

聲明分層

複雜的應用程序可能須要對層或包的定義作更細粒度的控制。例如,若是應用程序有一組橫跨多個路由的公共依賴項,不要在每一個包中內聯或複製這些依賴,則須要將公共依賴提取到本身的包中,而後在第一次引用時延遲加載。

Dojo 的構建管道容許在應用程序的 .dojorc 構建配置文件中指定資源,而後能自動將橫跨多個包的模塊依賴項轉換爲延遲加載的引用。

可訪問性與國際化

Web 本質上是全球性的,爲其編寫的應用程序須要支持全部用戶。文本須要按用戶選擇的語言和腳本顯示,而且須要根據用戶的區域設置對日期、時間、數字和貨幣等值進行相應的格式化。

Dojo 容許輕鬆使用消息包將文本消息從應用程序邏輯中分離出來,而後根據須要選擇使用 Unicode CLDR 數據的相關部分支持更高級的值格式化。

開發 web 時,須要應用程序對用戶足夠包容,不論用戶是否須要可訪問性。W3C 的可訪問性提案已經幫助標準化了許多這方面的需求,包括對可訪問的富 Internet 應用程序作的額外工做。

使用 Dojo 的部件套件開發的應用程序已提供了現成的 WAI-ARIA 屬性。雖然 Dojo 在這一點上提供了幫助,但它只也只能作這麼多——應用程序做者有額外的責任來驗證他們的應用程序提供的可訪問性級別。建議在應用程序的交付生命週期中包含顯式的可訪問性測試步驟。

詳見 Dojo 國際化參考文檔,瞭解如何爲全球用戶開發 Dojo 應用程序。

可適配的外觀

當前社會,Internet 的重要性與日俱增,應用程序被要求能適應用戶訪問 web 的各類方式。較小尺寸的移動體驗已經超過了桌面,但較大的外觀仍然能夠知足複雜的應用程序需求。Dojo 提供了多種解決方案,幫助開發人員建立適應用戶訪問需求的應用程序。

當須要預渲染內容時(如開發靜態站點時),Dojo 應用程序能夠利用構建時渲染(BTR),應用程序結構的一部分或所有都是在構建時計算的,而不是在用戶瀏覽器中運行時計算的。Dojo 提供了一個靈活的基於塊 BTR 的解決方案,當構建應用程序時能運行 Node.js 腳本,支持讀取文件來獲取內容等功能。Dojo 的 BTR 解決方案也支持漸進式融合,以在預渲染內容之上支持動態行爲。

漸進式 web 應用程序(PWA)有助於提供與本地設備 App 接近的體驗,同時依然能從 web 支持的可移植性和易交付等功能中受益。Dojo 經過簡單的構建配置就能幫助建立 PWA,開發人員能夠在應用程序中添加離線使用、後臺數據同步和推送通知等。

Dojo 容許開發人員經過中間件系統,在全部的交付目標上以一致的方式使用幾個即將可用的 web API。Intersection observer API 用於更好的控制渲染,僅渲染用戶可見的部件,例如支持無線滾動列表。Resize observer API 可以讓應用程序動態響應視窗大小的變化,容許界面在桌面和移動視窗的全部分辨率間逐步適應。

應用程序的開發生命週期

Dojo 爲開發 web 應用程序提供了一個端到端的管道。應用程序的做者可使用 dojo create app CLI 命令快速建立 Dojo 應用程序。而後可使用 dojo build app 命令在開發模式和生產模式下構建應用程序。使用本地 HTTP 服務運行應用程序,並監視對項目文件的修改,構建工具爲快速開發和迭代提供支持。使用這種機制,開發人員能夠在運行的應用程序中更改代碼並能當即看到結果。

這些命令是模塊化 Dojo CLI 工具鏈的一部分,該工具鏈支持開發生命週期中的各類使用。經過應用程序根目錄下的 .dojorc 配置文件,能夠配置應用程序的構建管道。

詳見 Dojo 構建參考文檔,瞭解如何使用 Dojo 構建各類應用程序。

測試的策略

編譯器和靜態類型檢查程序沒法捕獲出全部的錯誤。編寫的功能在語法和邏輯上是有效的,但要麼在運行時出現沒法預見的問題,要麼不是按預期的要求執行功能。爲了下降這種風險,須要進行額外的測試。

當使用 Dojo CLI 構建應用程序時,默認會內置一個 Intern 測試庫的測試運行器。這樣開發人員人員在編寫應用程序功能的同時就能夠當即編寫測試代碼。

Intern 爲不少測試場景提供瞭解決方案,但可能不足以知足項目的全部測試需求。Dojo 也提供了一個簡單的測試工具,容許應用程序測試代碼在 VDOM 的抽象層級驗證框架和部件。這個工具能夠用在不少測試運行器中,如 Intern、Jest 或應用程序測試策略所需的任何其餘程序。

詳見 Dojo 測試參考文檔,瞭解如何高效測試 Dojo 應用程序。

相關文章
相關標籤/搜索