小型Web頁打包優化(下)

之前我們推送了一篇小型Web項目打包優化文章,(鏈接),我們使用了一段時間, 在這過程中我們也一直在思考, 怎麼能把結構做的更好。於是我們改造了一版, 把可以改進的地方和可能會出現的問題, 在這一版中進行了優化。小夥伴們, 有沒有迫不及待? 那好, 我們廢話少說, 進入正題^_^

一、背景

之前, 轉轉App端內有些Hybrid頁面和一些端外的落地頁, 一般是單個的一兩個小頁面, 不是所謂的大型的前端應用, 比較零散, 交互也比較簡單。如果用vue或react, 有點殺雞焉用宰牛刀的意思, 沒有必要, 而且業務代碼比框架代碼還少, 對頁面載入的性能來說, 效率也不高。

於是我們為了把這些頁面統一管理, 我們在自己的gitlab上創建一個項目, 作為這些小頁面的集合, 裡面有許多目錄, 每個目錄代表一個小項目。一切看似都很正常, 都很有序...

兩個月前, 我們組內發現, 這些頁面經歷了一年多的時間, 已經迭代了好多小項目, 由於規範不是很完善, 裡面的頁面也寫的五花八門, 尤其是打包構建工具, 有fis、有glup、還有webpack等。這無疑給後面接手的同學, 帶來了麻煩, 於是我們產生了第一版的統一。我們統一了打包工具的使用, 然後精簡了代碼, 優化了層級結構, 使每個目錄結構得到了統一, 形成了規範。

可是最近, 我們在思考, 雖然目錄結構統一了, 但是如果遇到了組件升級, 比如我們轉轉的JsBridge升級, 那麼要把每個項目的依賴都升級一遍, 這豈不是很頭疼的事。如果項目目錄超過20個, 那就要手動升級20個頁面, 帶來了麻煩不說, 而且還很容易出錯。所以, 操練起來吧, 讓我們一起來優化。

二、簡單介紹

1.原理圖

說到原理, 不得不先說下webpack, 這次的改造都是基於webpack來打包編譯的, webpack主要幫我們做了這些事, 也是webpack最最基本的功能, 如下圖:

眾所周知, webpack是全英文的文檔, 這裡給英文不好的小夥伴貼一個中文版的。下圖是整個項目的拆解圖

2.項目結構

廢話少說, 大家都是程序猿, 先上代碼。本人在自己的github里放了項目結構代碼, 後面以此為例, ZZDownload為眾多小項目的一個(例子)。為了方便大家查看, 把項目目錄結構截圖如下, 具體請移步這裡!

三、使用方法和場景

1.如何使用

- 安裝

npm installn

nodejs環境是前提, 我想大家應該沒有什麼疑問, 這個不做過多解釋, 你懂得~

- 配置

module.exports = {n "name": "ZZDownload", n "vendor": [es6-promise/auto, axios, mustache],n "pages": [{n "name": "Download",n "template": "/Download/Download.html",n "entry": "/Download/Download.js",n "output": "index.html"n }]n};n

每個src中的目錄, 可以稱之為一個獨立小項目。 每個小項目中, 需要有個此項目的配置, 即config.js。還是以ZZDownload為例, 見上面的配置, 可以是單個落地頁、也可以是多個頁面。配置在此不做過多闡述, 後面會有詳細解釋。

調試頁面可以使用

npm run dev 項目名n

待頁面發開完成, 需要打包上線, 執行

npm run build 項目名n

以我們git的例子來說, 我們就執行 **npm run build ZZDownload**。然後編譯產出的代碼就在根目錄的 **dist/ZZDownload** 里。

**至於頁面內部的業務實現, 隨便你! **

**至於頁面內部的依賴框架, 隨便你! **

**至於頁面內部的目錄結構, 隨便你! **

我們就是這麼人性化, 業務代碼隨你DIY! 不干擾個人習慣, 我們只是代碼的編譯打包的搬運工!

2.哪些情況來使用

  • 減小了產出代碼的大小

用事實說話, 以上面的項目為例, 我做了一個轉轉的下載落地頁面ZZDownload。看了下dist產出的頁面, 一共75k。是不是顯而易見了, 整個頁面不到80k, 我想就算是2G的環境, 載入起來也不算很慢吧。

  • 不建議搭建複雜的單頁應用

說到這, 好多同學會問, 如果我們利用像React/Vue這樣的框架, 搭建整個項目, 每個小頁面是一個路由, 那不也能達到同樣的效果么? 那麼升級jdk或者解決一些公共組件的問題, 不是也很方便么?

其實是這樣, 短期看這樣貌似沒什麼問題, 但是考慮到一段時間以後, 有可能小頁面數量會很多, 那麼每當新增一個小頁面的時候, 需要編譯整個項目, 那個時候項目產出的代碼可不是幾十K的大小能解決的。而且只是新增了一個小頁面, 卻需要整包編譯和上線, 這對於項目內其他小頁面, 還是比較有風險的。

雖然我們對複雜單頁面也支持, 但是為了精簡產出代碼, 就沒有引入babel, 像React/Vue這種構建複雜應用的項目, 不用es6, 開發起來也並不順手, 對於強迫症的我, 還是挺不能接受的。並且複雜的頁面應用, 本身就會依賴很多庫或者插件, 這也和我們為了精簡的出發點是相違背的。如果大家有複雜單頁應用的項目, 建議還是vue-cli比較來的方便, 也更快捷。

四、原理

1.代碼執行步驟

  • 我們對npm的命令, 進行了傳參, 項目名就是參數。
  • 將參數透傳到webpack里, 並根據參數查找src中對應目錄。
  • 讀取目錄內的config.js文件, 根屬性包括name、vendor、pages, 分別對應項目名(後續可能會優化掉此參數, 只用目錄名和參數匹配)、公共依賴、頁面集合(多個頁面, 數組配多項)。
  • 通過遍歷config的各個屬性, config可以理解為一個大的參數集合, 遍歷的結果傳入webpack的entry和plugins屬性里, 生成完整的webpack的配置。
  • 一切就緒之後, 就是webpack自己的編譯打包了。等待若干秒之後, 你就可以在dist里看到產出的代碼啦!

2.參數說明

module.exports = {n"name": "ZZDownload",n"vendor": [es6-promise/auto, axios, mustache],n"pages": [{n"name": "Download",n"template": "/Download/Download.html",n"entry": "/Download/Download.js",n"output": "index.html"n }]n};n

還是以上面的配置為例。

  • name: 為頁面名, 可以理解起到一個id的作用, 同一個項目中的多個頁面, name不能相同。
  • template: 頁面入口的模板, 就是產出頁面的html路徑
  • entry: 頁面入口的js文件路徑
  • output: 產出頁面的文件名
  • name: 為此項目的項目名, 需要與src里的目錄相同, 用作webpack編譯的目錄, 後續考慮是否可以把此參數優化掉, 因為執行npm run的參數, 可以找到目錄。
  • vendor: 為此項目的公共依賴, 比如我們依賴的模板(如mustache)、發送請求(如axios)等, 都可以放在此處配置。
  • pages: 屬於頁面的集合, 如果多個頁面, 就配置數組多項。

PS: 上面配置為單個頁面, 多個頁面只要在pages數組裡配置多個項即可。每個入口需要分別有html和js的entry, 每個頁面也要產出的頁面名(即output)。整個項目的模塊名為name, 總體的第三方功能依賴為vender。注意, 這裡的依賴, 是指每個小項目的依賴, 不是整個大項目的依賴。

五、總結

1.優勢

  • 依賴問題

目前所有項目的依賴得到了統一, 都依賴最外部的package.json的配置。即使有依賴升級, 只要修改package.json中的版本, 然後編譯一下就OK啦。

  • 產出代碼

每個項目的產出代碼, 都統一到根目錄的dist里, dist中會根據src中的項目目錄進行分割, 並且一一對應。進入自己的產出項目目錄, 裡面有html文件和static目錄, 然後分別部署到測試的伺服器和cdn就可以了。

  • 個性化頁面入口

此配置同時適用於單頁面和多頁面, 根據配置文件的入口而定。外部的webpack都是統一的, 只是每個項目需要自己的配置文件, 來個性化DIY。所以, 不管是你基於什麼技術站, vue/react或是早起的require/jquery, 統統一網打盡。

2.作用

此優化主要是針對零散的小頁面, 方便對小頁面的集合進行管理。如果每個小頁面作為一個項目, 既造成了項目數量的泛濫、不方便管理, 又會。如果在缺失文檔, 那後果可想而知, 估計每個接手的同學都會有怨言。

個人感覺, 這種形式試用與那種交互不複雜、迭代需求快的頁面, 類似一些運營頁面之類的, 我覺得是一種不錯的方式。

說到這裡, 我們要暫時告一段落了, 感謝大家能看到這裡。對於這種方案, 我們還會持續優化, 有了新的提升我會再給大家進行分享。也請看到本文的大神們多提寶貴意見, 我們會繼續加油努力......

推薦閱讀:

Node.js中的哪些庫讓你相見恨晚?
世界上還有哪些比 npm 更壞的包管理器?
已經全局安裝過gulp了,為什麼運行gulp命令提示 Local gulp not found ?
每個項目文件夾下都需要有node_modules嗎?

TAG:npm | Web开发 | 优化 |