武裝你的小程式——開發流程指南

李初五發表於2019-02-18

前端工程本質上是軟體工程的一種。軟體工程化關注的是效能、穩定性、可用性、可維護性等方面,注重基本的開發效率、執行效率的同時,思考維護效率。一切以這些為目標的工作都是"前端工程化"。工程化是一種思想而不是某種技術。

本篇文章你可以學到:

  • 如何使小程式支援scss;
  • 怎樣通過gulp編譯你的專案;
  • 專案常用的模組封裝;
  • 小程式同webview之間如何優雅的進行互動;
  • 集中式管理你的專案提高可維護性;
  • 提升開發效率的小工具編寫;

全文全部基於原生的小程式開發所闡述,各種第三方框架開發不在此列。並不會將整個專案的搭建流程細緻的寫出來,而是挑其中我認為在開發過程中存在的一些很重要的點進行詳細陳述。

普通小程式開發流程有可能會遇到的坑

列舉部分常見的

  • 小程式本身不支援常用的css預編譯器,導致樣式規範隨意散落在各個檔案,無法統一進行管理,而現代前端開發中不論是less,sass,stylus 都可以提升css效率;
  • 缺少統一的request攔截請求;
  • 缺少統一的路由管理;
  • 缺少集中式的API地址和ENV環境變數管理;
  • 缺少統一的本地快取讀取管理;
  • 重複的webview頁面;
  • 不支援ES7以上的高階語法,如async await等特性;
  • 不管是體驗版還是開發版只能存在一種環境,一旦釋出預覽測試環境切換繁瑣;
  • 上線前需要手動修改線上環境,容易出錯......

如何解決?

要解決工程化的問題,需要從兩個角度入手:開發 && 部署

開發

Question

  • 如何提高開發生產效率?
  • 如何降程式碼維護難度?

Program

  • 制定開發規範,提高團隊協作能力;
  • 使用自動化編譯工具使專案支援各種外掛和提高效率的工具;
  • 模組/元件化開發;
  • 所有需要集中管理的地方進行統一封裝;

部署

  • 環境切換;
  • 壓縮打包;

專案搭建

完整目錄結構 

 

開發流程

 

 

工程化方案選型

對於目前常用的工程化方案,webpack,rollup,parcel等來看,都常用與單頁應用的打包和處理,而小程式天生是 “多頁應用” 並且存在一些特定的配置。根據要解決的問題來看,無非是檔案的編譯,修改,拷貝這些處理,對於這些需求,我們想到基於流的 gulp非常的適合處理,並且相對於webpack配置多頁應用更加簡單。所以小程式工程化方案推薦使用 gulp

Start

初始化一個專案,結構如下

 

  • src 為開發目錄
  • dist(開啟編譯後可見)為預覽/上傳目錄
  • .gitignore git上傳忽略檔案
  • gulpfile.js 編譯配置檔案
  • CHANGELOG.md 版本更新日誌
  • README.md 專案說明檔案
  • package.json 專案配置檔案

編譯用到的外掛 使用npm或yarn自行安裝,安裝過程不過多贅述,不會請自行搜尋。
"gulp": "^3.9.1"
"gulp-sass": "^4.0.2" scss編譯外掛
"gulp-postcss": "^6.4.0" 強大的css處理外掛
"gulp-rename": "^1.2.2" 更改檔名
"gulp-replace": "^1.0.0" 替換內容
"gulp-changed": "^3.2.0" 檢測改動
"autoprefixer": "^6.5.1" 自動新增字首

如何使用scss?

gulp配置打包sass非常簡單,唯一需要注意的是@import的使用,wxss是支援樣式匯入的,但上面說到過小程式是天生的多頁面應用,每一個頁面都對應一個wxss,因此sass打包會把import的檔案打包到當前檔案,從而導致當前檔案的體積變大。由於微信限制單包程式碼不能超過2M,因此當css越寫越多的時候,這種打包方式勢必會使樣式檔案越來越大。

解決import匯入問題

那如何解決import的匯入問題呢,其實也比較簡單,說白了就是sass處理的時候,讓其不處理import部分的語句就可以了。有兩種方式可以做到,第一種是改寫sass處理的原始碼,當遇到import語句時跳過。第二種是,在把檔案交給sass處理前,我們先把import語句部分註釋掉,這樣sass處理的時候就會忽略了,當sass處理完成後,再把註釋掉的語句開啟即可。顯然第一種成本比較高,也不好維護,所以我們採用第二種。
在處理import的時候,還有個地方是需要注意的。在sass中,import除了能引入css外,也可以引入變數,函式。因此,我們在處理的時候也需要注意區分,變數和函式最好有一個獨立的檔案目錄存放,並且在import的時候,對於變數和函式,是必須交給sass處理的,也就是不能註釋掉。因此我們單獨配置了sass變數和函式存放的位置,這樣我們在打包的時候,遇到這樣的import語句,我們就跳過,交給sass處理,否則就代表其是引入了共用的樣式檔案,這樣我們交給sass處理前,就先將其註釋掉,sass處理完成後再把註釋開啟。

完整實現支援scss思路如下:

  • 指定檔案處理目錄
  • gulp-replace通過正則匹配@import語句將其註釋
  • 判斷當前@import語句是否存在於變數和函式檔案的配置路徑中
  • 不存在就註釋,存在就跳過
  • 啟用gulp-sass編譯scss檔案,
  • 通過postcss對低版本ios和安卓進行相容樣式處理
  • gulp-rename更改檔案字尾為.wxss
  • gulp-replace通過正則匹配@import語句開啟註釋
  • 最後輸入到dist目錄

程式碼如下 

拷貝其餘頁面,注意要排除scss檔案,或者使用gulp-clean清理無用檔案 

建立監聽任務

建立預設執行任務

 

將生成的dist目錄作為根目錄丟進小程式開發工具即可實時重新整理預覽小程式,至此你的專案已經完全支援scss了,盡情的去浪吧。

提高你的程式碼維護性——封裝

request請求攔截器

wx.request是小程式中最常用的api,在實際專案中會涉及到很多需要統一攔截/傳送/處理,所以我們需要對wx.request進行二次封裝用來支援各類需求,以實現程式碼的可維護性。小程式本身已經支援promise語法, 在此用promise將其封裝成常用的.then的形式

要做什麼?

  • 可以通過header和data統一傳送公共引數,如請求驗證的token,使用者id等資訊...
  • 可以統一進行錯誤攔截處理,如全域性登入狀態判斷,特殊code碼的處理...
  • 可以根據配置自適應請求環境,如Mock,Dev,Test, Slave,Prod...

需要支援的功能

  • 請求方式
  • 引數傳遞
  • 成功回撥
  • 失敗回撥
  • 是否開啟mock資料
  • 請求時是否展示loading
  • 請求錯誤時是否展示toast

程式碼實現 

 
 
呼叫方式 

app.js入口檔案內引入,並將其掛載到App物件上,需要呼叫時可通過getApp()的方式呼叫

index.js為例,關於API的引入會在後文介紹:

 

Router路由

路由的封裝主要是為了防止路由地址各個檔案散落,無法集中管理的問題。

需要支援的功能

  • 無參路由和有參路由
  • 路由地址縮寫
  • 引數傳遞
  • 跳轉延時
  • 跳轉型別

程式碼實現

定義出存路由地址的物件,使用時直接通過key值匹配

 
實現一個parse方法解析引數為query拼接方式
 
 
定義一個push物件接收普通無引數path地址和有引數的option物件,option物件包含path(路由地址)、query(引數),duration(跳轉延時),openType(跳轉方式)
 
 
通過openType結合原生api實現路由的幾種跳轉方法
 
 
呼叫方式 還是老規矩,直接掛載App物件通過getApp()獲取直接呼叫
 

Stroage儲存

合理的Stroage方法封裝可以使你更優雅的管理你的本地快取。此功能需要支援三種常用的setItem(設定快取)、getItem(讀取快取)、clear(清除快取)方法,並且在你的團隊內部最好整理一套寫入快取的規範,不要一股腦丟在全域性,應該按一些模組進行劃分存取,這樣才能更好的維護你的本地快取資訊。 程式碼實現 寫入和讀取均支援key ---> value的普通方式也相容key--->value--->module的模組方式,預設使用同步的方式設定,之所以加catch是為了防止在特殊情況下小程式會報警設定快取錯誤,如同步報錯則採用非同步容錯。

setItem寫入快取

 
getItem讀取快取
 
 
clear清除快取 
 
 
呼叫方式 同上掛載App,使用方法如下:

寫入
 
讀取
 
 
清除
 

API地址和ENV環境變數管理

API地址和ENV環境變數可以做為兩個單獨配置的檔案進行配置,API檔案只存介面路徑,ENV儲存多個環境變數,環境物件內配置當前環境各種域名,然後在app.js配置當前環境變數,作為key值匹配ENV內的環境,將匹配的環境掛載App物件,配合前面封裝的fetchApi以env+url的方式實現自動環境適配。

API

 
ENV
 
 
app.js
 

 

統一的webview

微信小程式提供了在小程式中內嵌HTML頁面的能力,從微信小程式基礎庫1.6.4開始,可以在小程式內放置一個元件來連結HTML頁面。有了就可以方便的將幾端共用的h5頁面整合到小程式內部,為我們減少了可觀的工作量。

如果你有多個需要整合的webview頁面實際上無需為每個頁面都單獨建一個檔案,只需對一個公共的webview頁面進行簡單封裝配合路由即可集中管理你的webview頁面。

程式碼實現

wxml引入webview元件和載入中動畫,webview元件接收地址,和載入成功回撥。

js中在data內定義webview頁面的地址列表,key用type代表指定路徑,value用page代表頁面連結,通過onload接收一個formpage引數對應type,動態載入元件上的src即可。需要注意的一點是,如果需要在webvie連結拼接獲取的引數,在某些安卓機型會因為提前渲染webview而src地址沒有初始化而產生白屏,所以最好的方式是通過一個變數控制元件的展示隱藏,確保需要渲染元件時資料已經初始化完成以保證頁面正常展示。 

如何解決多環境切換問題

小程式不像h5網頁只要部署到對應環境,就可以隨意輸入指定的環境域名進行測試,而小程式像app一樣沒有網址這一說,它本身只會存在一個預覽版本,普通的流程是每次當測試同學需要在不同環境中測試時就需要找到開發同學手動更改環境並重新發布體驗版。這樣的流程是很不靈活的,所以我們需要想一個辦法,讓一個小程式版本自由的切換多個環境,而無需手動改程式碼配置釋出。

如何實現?

實現的思路有很多種,主要需要解決的就是環境如何進行切換的問題,在這裡我是通過利用小程式的重力感應api模擬搖一搖,將切換環境搓成一個一個隱藏的小彩蛋,測試人員只需要搖一搖彈出環境選項列表點選對應選項更改App物件的config內的env環境屬性即可成功切換環境。

程式碼實現

 
app.js也要進行處理,因為不能將該功能帶到線上所以需要進行邏輯判斷。
 

 

如何自動打包部署環境,防止手動配置易出錯的問題

在這裡其實還是要用到gulp這個神器,來實現不同環境的程式碼打包,配置起來很容易,無非就是通過gulp-replace在打包的時候對app.js的環境變數進行配置,但要配合微信開發工具的自定義處理命令每次在發版本稽核的時候只需要開啟該功能即可。

gulpfile.js

 
project.config.json
 
 
開發者工具
 

 

以上列舉了開發流程中常用的工程化解決方案,再此希望對大家有一個參考作用,如有問題歡迎指正。

 



相關文章