主要介紹 Vue 框架下、在工程化的前端項目中如何實現前端模塊化、分佈式部署方案。css
這也是一份在我所在部門內已經使用近一年的一套前端架構及工程化方案。前端
PS:webpack
這是一部連續劇...ios
這是裏的模塊指業務功能模塊,不是 js 範疇的模塊。爲便於區分,後文將 js 範疇的模塊稱爲 jsModule.web
這是一段現實場景的回憶錄,因此,1. 可能有細節遺漏;2. 它不是一個目標的最簡版實現,可能會有點複雜ajax
若是是在一個項目內,完成業務與非業務邏輯、業務組件之間的解耦,增長代碼引用規範的校驗,基本能夠知足業務功能的模塊化。可是若是指望模塊可以獨立部署,問題就複雜起來了。npm
獨立部署意味着:axios
這會帶來一些問題:後端
曾經的一個
npm run dev
會打包全部代碼,webpack或者其餘打包工具會解決代碼拆分和加載的問題。如今須要:分別打包平臺、模塊的代碼,分別啓動平臺資源服務、模塊資源服務,而後本身加載這個模塊的代碼並執行跨域
模塊是後加載的,異步的,模塊須要各自負責本身的路由、狀態管理,對平臺而言這是不可預測並先行定義的,因此 Router 和 Vuex 須要改成動態注入的方式,不過很幸運的是,它們都支持這個特性
工程內使用的打包工具是 webpack, 它會註冊一個全局的變量(默認是 webpackJsonp), 並以數組的方式管理 jsModule。若是加載另一段一樣的方式打包的代碼,二者管理的 jsModule 會變得混亂,由於 jsModule 的引用是以數組索引的方式實現的。
模塊打包後的結果,可能產生 js、css以及其它靜態資源文件,若是指望保留 chunkId 拼接文件名的方式,或者考慮打包配置變動、後期資源變化的狀況,模塊的最終資源列表將是不可人工枚舉的。因此我須要打包工具打包完成後輸出一個資源列表,不過 webpack 的插件很優秀,沒必要擔憂。
考慮一個模塊間依賴的場景:若是A依賴B,如何知道B已經加載完了?再考慮一個場景,模塊 C 和 D,同時請求加載一樣的資源,如何管理?因此我須要知道模塊是什麼,是否已經徹底加載,還須要一個獨立資源加載器避免重複資源請求。
考慮這樣的場景:某系統A(平臺)已經集成了模塊B(B的資源指向了測試或生產環境地址),開發時如何將模塊B的資源指向開發環境?(理想狀況下可能指望提供一個純淨的平臺,不過現實總會有驚喜)
一個功能的上線須要通過:開發環境 > 測試環境 > 預發環境 > 生產環境,平臺和模塊都各自有對應的以上這些環境。以上不一樣的流程,除域名不一樣之外,代碼自己及其運行環境並無任何差異,那怎樣保證測試環境的平臺加載測試環境的模塊資源?生產環境加載生產的?
這也是處理起來最麻煩的一個問題,模塊的請求事實上有兩部分:模塊資源(js/css等) 和 數據資源(ajax請求)。一般不一樣的模塊都對應不一樣的後端服務(b.com)。當模塊集成到平臺上運行的時候,實際上發出請求的對象不是模塊自己而是平臺(a.com)。固然咱們能夠選擇同一走平臺代理,或者要求模塊服務器信任平臺來源的請求。其次,從開發上講,原則上禁止代碼中的任何形式的域名硬編碼,模塊中沒有域名的記錄,那應該怎樣讓平臺知道模塊的數據資源請求的域名呢?
舉個例子,平臺選擇用 axios 提供 http 服務,若是模塊A引用axios並提供了並不當心作了全局配置,好比加個 baseUrl,其它的模塊怕是會全軍覆沒了。。。我不但願每一個模塊引入本身http服務,這很混亂,也會帶來不少功能重複的代碼,我也不但願採用 iframe,這會帶資源和性能的浪費,也會帶來佈局上的一些坑。我作了部分隔離,以確保不會出現無心識的AOE
實際上也還一些其它細節問題,好比
npm run dev
後自動打開瀏覽器的功能,我須要分別啓動平臺的服務和模塊的服務,這是兩個進程,我須要肯定平臺的代碼編譯工做已經完成,因此進程間通訊成了必需品。再好比,抽離了全局的編譯命令,hotreload 也讓我踩了點坑, 等等。。。
不管是模塊仍是平臺的開發,保留原來的味道
npm run dev
, 該有熱加載會有,該有自動打開瀏覽器也會有。固然,配置文件變了~
這就有點扯淡了,事實上當時在發展過程當中讓前端的兄弟陪我踩了很多的坑,這部分處理也是經歷一次大的修改的,固然,如今工做得好不錯。
以上輸出順序或結構可能會有調整