1、寫在前面
我曾嘗試過利用vue自身的模塊化與webpack配合實現此功能,可是因爲webpack編譯時不能識別代碼中的條件判斷,他只會將從入口文件開始的import和require引入的文件所有打包進去,不能根據代碼中的條件判斷動態引入須要的文件實現自定義打包。因此我想到能夠直接將以前手動拼裝文件的過程自動化,那自動化我就會想到使用linux的一些命令,寫一個自動化腳本,交給程序去執行就行了。個人這個方法確定不是最好的,有更好的方式歡迎你們評論留言,共同進步。css
2、需求
咱們公司有一款app,它有一些通用化的功能,也存在一些根據客戶需求定製化的一些功能,同時還會不定時升級,功能拆分組裝等,這種就會出現遺漏升級,重複開發,出錯率也會增長。因此我就想實現只寫一套代碼,經過勾選☑️的配置方式實現非技術人員也能夠自助生成app,這樣釋放了勞動力,也提升了工做效率。前端
3、設計思想
首先要將功能細化並拆分紅模塊,這點利用vue天生的模塊化思想很容易就可實現;其次拼裝好模板,比方說功能1+功能2是一種模板,功能3和功能4是一種模板,由於vue我沒找到能夠動態註冊局部組件的方法(此方法很笨,後來我想到了能夠利用sed命令寫文件以實現動態引入組件);最後就要在服務器上部署打包環境了,這個我是首先在docker上將環境配置好,以後將配置文件上傳到服務器上便可。vue
4、使用到的技術棧
5、目錄設計
這是一個基於cordova的appjava
5.1 整體目錄解釋
- platforms:cordova項目自帶,項目安裝的平臺
- plugins:cordova項目自帶,項目安裝的cordova插件
- vuxProject:vue項目目錄
- build:webpack配置文件
- config:webpack配置文件
- src:webpack打包的目錄
- srcAllVersions:全部功能模塊文件,以後根據配置文件將須要的文件移入src文件夾下
- static:靜態資源文件
- www:vue打包以後的文件
5.2 srcAllVersions目錄解釋
- assets:靜態資源文件,包括圖片,css,js等
- components: 細化的功能組件
- cordova:cordova的一些配置文件
- main:vue的入口文件
- pages:頁面模板文件
- resources:app的資源文件,包括啓動動畫圖片,applogo圖片
- router:vue的路由文件
- services:一些服務的js文件,包括接口服務,與第三方sdk對接的服務
- APP.vue: vue-cli建立的主vue文件
- common.js: 本身封裝的公共方法文件
- CONSTANT.js:自定義的常量js文件
- Listener.js:監聽push的文件
- Vue.js:主要用來加一些攔截器,定義一些全局的方法
6、docker配置cordova打包所須要的環境
- 在cordova項目中命令行輸入
cordova requirements
便可看到cordova所依賴的環境
- java jdk:1.8.0版本
- android sdk
- android target:我這邊安裝了23,25,26,27,28
- gradle:4.1版本
-
配置docker鏡像node
2.1 鏡像文件目錄以下:linux
我將須要的gradle,jdk,sdk都直接放在鏡像中了,這裏要注意的是要根據你docker的系統下載相應的包,我這裏下載的都是linux的包。以前我是用使用wget命令在建立docker鏡像的時候命令行下載相應的包,此種方式比較耗費服務器資源,因此改用直接將本地文件上傳到docker某目錄下便可。
- Dockerfile文件是建立鏡像時,執行的一些腳本,內容以下:
[注]: 當時遇到的最大困難就是在.bashrc文件中配置環境變量,使用source命令未能保存成功,致使不能執行下面的命令 解決辦法:使用docker的ENV命令,直接寫入系統環境變量便可android
- 配置docker實例 目錄結構以下:
- logs:記錄日誌的文件
- node-Dockerfile:配置文件
- .env
- docker-compose.yml:在此文件中我將本地項目文件映射到docker實例中
7、模塊化打包
7.1 更細節的設計思想
- 從總代碼池(srcAllVersions文件夾)中選擇好須要的功能模塊與模板,要定義好從form的文件夾,以及to的文件夾
- 將其放入目標代碼池中(src文件夾),並修改文件名,ex:總代碼池中叫template01,可是在目標代碼池當中須要修改成main.js
接下來看一下node項目的目錄結構:webpack
- api.js:定義接口
- app.js:node主文件
- config.js:自定義組裝文件夾的配置文件
- CONSTANT.js:定義了一些常量,好比路徑常量
7.2 詳細講解config.js文件
在此文件中我定義了一個Objgit
- indexBg:爲前端傳的key
- source下的key爲indexBg的值,一個值對應一個文件,即根據用戶傳的自定義配置,從總代碼池中摘取對應的文件
- sourcePath:表示源文件路徑,這裏面出現的
Source_Path
等變量都在CONSTANT.js文件中定義了
- aimsPath:目標路徑,即將此源文件的副本移到哪一個目錄下
- oldName:源文件的文件名
- newName:移入到目標文件夾下,須要修改成新的文件夾,若是新文件名和源文件名相同,則不須要配置
7.3 詳細講解組裝文件接口
- 首先若是存在舊文件,須要先刪除歷史文件
- 將源文件拷貝到目標文件夾內
- 修改文件名(針對多模板的文件)
- 返回成功
7.4 詳細講解設置app信息的接口
- 獲取app名字,版本,appid
- 刪除歷史config.xml文件
- 將源文件中的config.xml拷貝到cordova目錄下
- 將app相關信息寫入到config.xml的對應的位置
- 返回成功
7.5 詳細講解安裝插件的接口
- 因爲此接口所作的shell腳本須要過長的時間執行,會致使超時,因此我設計了一個輪詢機制,在調取此接口的同時也要調取輪詢接口
- 輪詢接口的設計思想,在調取安裝插件接口的最開始,建立一個此用戶的的文件,並在文件中寫入「build-init」標誌,當次接口執行完,會在文件中覆蓋寫入「build-suucess」標誌,而後輪詢接口只要輪詢到此文件寫入了「build-success」標誌就返回成功
- 進入到src目錄,運行
npm run build
更新www文件
- 更新cordova(此步驟必需,否則執行其餘cordova命令會先出現此提示),而後刪除原android平臺
- 從新添加android平臺,注意版本
- 須要向這兩個文件中寫入兼容語法
5. 因爲咱們app的底層須要根據硬件設備選用不一樣的底層sdk,且多個sdk同時安裝了會出現打包錯誤 1. 首先要判斷當前項目中是否已經存在所須要的sdk,若是存在則返回正確,繼續;不然安裝相應的sdk,同時刪除其餘sdk插件 2. 這個判斷我是根據package.json文件匹配相應的sdk名字,匹配成功表示已存在,不成功則表示不存在
6. 以上都執行完畢,向輪詢的文件寫入「build-success」標誌 7. 返回成功
7.6 詳細講解生成apk接口
- 此接口同上,也須要配一個輪詢接口
- 輪詢成功返回生成的apk地址,前端可下載
- 先建立一個該用戶的輪詢文件,並寫入「apk-init」標誌
- 根據要生成apk的環境(正式/測試/本地調試),使用不一樣的打包命令,只有正式環境須要加上簽名
- 爲了防止出現同名文件,因此將存在的apk刪除
- 生成apk文件
- 在輪詢文件中寫入「apk-success」標誌
- 返回成功
8、後期維護
8.1 添加新的功能模塊
- 作好組件化,減小耦合性,放到srcAllVersions文件夾內相應的components/pages文件下便可
- 組合新的頁面模板
- 須要在打包平臺的前端,添加新的配置項
- 後端組裝文件接口的config文件須要加一條配置項
8.2 修改bug
找到源文件,修改bug便可github