緣由:
uni-app同一套代碼 無法區分 微信小程序插件 和微信小程序
當前項目開發微信小程序、支付寶小程序、業務需求需要開發微信小程序插件
但是uni-app只能區分運行平臺微信 支付寶 app等,無法區分插件和小程序,因此決定自己寫一個條件預編譯來區分。
方案思路:
參考當前條件編譯模式,通過自定義腳本將不同平臺的代碼刪除,保留當前符合條件的代碼。
- 將代碼編譯生成新的目錄
- 如何刪除非當前條件的代碼
- 如何匹配條件標識開始和結束
----- 優化----- - html js css json文件類型的適配
- 在當前平臺需要支持其他平臺
- 差量編譯
- 資源文件處理
- 環境適配
思考1 --- (將代碼編譯生成新的目錄)
目前開發代碼都是在一個src目錄下,通過腳本將需要打包的目錄,
遍歷文件 將刪除后的代碼寫入新的目錄
/*
參考系統工具,我們平時開發的內容代碼,最終也是在另一個目錄下運行;
系統的也是通過將當前代碼經過編譯 生成對應的平臺的文件的代碼
*/
思考2 --- (如何刪除非當前條件的代碼)
按行讀取文件
我們可以發現,條件標識 #ifdef #end結束等 都是單獨一行;
所以我們可以通過按行讀取文件的內容, 判斷符合#ifdef條件, 并且不是當前平臺的時候,
下面的每一行開始不再寫入,
直到碰到對應的結束標記,重新在開始寫入.
思考3 --- (如何匹配條件標識開始和結束)
正則表達式 判斷
我們可以通過正則表達式,將當前一行判斷是不是符合 #ifdef 微信 || 支付寶|| 插件 等
截取出后面的部分,按照 || 分隔 判斷是否包含當前條件 不包含則后面的代碼需要刪除
需要解決的問題就是這幾步!
深度考慮
1. 當前平臺條件編譯有 html js css的代碼
因此我們需要添加配置,將 #ifdef 、/* #ifdef */ 等 根據不同格式的統一處理,添加所有需要的平臺的格式的條件標識
2. 在當前平臺需要支持其他平臺
因為我們的微信小程序插件 也是運行在微信小程序上的,而我們的小程序和插件是一套代碼, 因此插件編譯的時候 ,需要支持微信小程序的代碼,
- 因此我們需要對當前平臺 設置一個可以匹配其他平臺的配置, 在判斷是不是當前平臺同時也判斷一下符不符合配置的其他條件
優化體驗
1. 差量編譯
上面的步驟完成后 我們實際已經完成了條件編譯;
但是對于文件較多的時候,每次修改一個文件,重新在編譯生成的,非常耗時間,也不方便我們調試.
因此我們做了差量編譯,監聽處理變更的文件.
2. 資源文件處理
由于資源文件都在一個目錄下,并且還有一些不需要編譯的目錄可以直接copy過去的,
在配置文件中 添加不需要區分條件編譯的相關目錄,則直接copy.
3. 環境適配
開發中 都有開發環境,測試環境,線上環境;
我們的小程序有些功能只能在上線才能測試,因此我們會發布兩個不同id的小程序 一個用于測試,一個用于線上.
對于區分開發 測試 線上環境,我們處理方式 也是將
這三種環境 當做 三個平臺處理,因為我們的條件平臺支持配置其他條件平臺;
所以 當處理其他條件平臺的時候,系統會自動添加當前運行環境 到 對應平臺的適配條件中,
例如 運行命令 node build.js weixin dev
則會在 weixin.coexist中 添加dev 條件 這個是在運行時添加的
weixin: {
coexist:['dev']
}
附言
下面是一些偽代碼:
function 遞歸遍歷文件夾 {
function 讀取單個文件 {
for (遍歷文件內容 按照行讀取) {
var line = 按行讀取;
if 條件編譯已經開始 {
if line == 是條件編譯模式,并且不包含當前平臺 {
開始下一行的判斷;
continue;
}
if line == #end {
結束條件編譯標記,重新開始讀寫;
continue;
}
直接進入下一行
continue;
}
將line寫入新的文件;
}
}
}
其中 在讀取文件的時候 使用異步的方式,提高速度,可以縮短一半多的時間;
對于異步結束判斷會延遲判斷 延遲也會有一個標記,最后一個延遲到的時候,判斷是否結束 ,
同時有一個文件寫入的計數,最后只要判斷文件是否在寫入
附件源碼:
直接在 precompile 下面 運行
鏈接: https://pan.baidu.com/s/1asmHTc2tZl3cfAmhv_kIMQ 密碼: t35f