如何快速又(yòu)高效地編寫微信小(xiǎo)程序?
2017-05-19 22:29:29
廣州小(xiǎo)程序開發正在互聯覺得,微信小(xiǎo)程序是一個工(gōng)程,就和蓋房子一樣,打好了地基,才能(néng)保證後續工(gōng)程師建立在可(kě)靠牢固的基礎上。
微信小(xiǎo)程序開發者需要經常新(xīn)建項目,每次都要重複“修改項目結構 -> 從老項目中(zhōng)複制粘貼文(wén)件 -> 删除一些老項目中(zhōng)代碼”這樣的過程,實在是…費心費力。另一個痛點是:每次新(xīn)建小(xiǎo)程序頁(yè)面要生成三個文(wén)件名(míng)相同的文(wén)件 ( .wxml、.wxss 和 .js ),命令行太長(cháng)(據微信同事:也可(kě)以在 app.json 的 pages 字段下添加新(xīn)頁(yè)面的路徑,保存後也會生成對應的文(wén)件)。
目标
我們現在有(yǒu)兩個目标:
1、根據通用(yòng)模闆新(xīn)建項目
2、一鍵新(xīn)建頁(yè)面目錄以及在目錄中(zhōng)的三個文(wén)件 :.wxml、 .wxss 和 .js也可(kě)以直接在 app.json 的 pages 字段創建頁(yè)面,保存後生成這三個文(wén)件。筆(bǐ)者沒有(yǒu)采用(yòng)這個方法的緣由一個是開始時不知道有(yǒu)此功能(néng),另一個是不合平時的操作(zuò)習慣,再者想到 js 文(wén)件初始化後,需要引入常用(yòng)庫,要插入代碼片段,所以保留了這個功能(néng)。
這兩個需求其實很(hěn)簡單,不需要 GUI,所以我們可(kě)以做一個 npm 命令行工(gōng)具(jù)。想象一下這個命令行用(yòng)起來應該是什麽樣的呢(ne):
~ npminstallwxapp -g ~ wxapp -i myapp && cd myapp ~ wxapp -plist用(yòng)流程圖示意就是:
實現
正式開始之前,請先确認本地的開發環境,開發者的本地環境是:
~npm-v3.10.10~node-vv6.9.4我們把問題分(fēn)解為(wèi)三步:
1、實現命令行工(gōng)具(jù),可(kě)以在任意目錄直接運行
2、通過輸入不同的命令行參數,以執行不同的功能(néng)
3、考慮項目模闆的存放位置,是集成到工(gōng)具(jù)中(zhōng),還是和工(gōng)具(jù)分(fēn)開呢(ne)
不用(yòng)擔心,都很(hěn)容易解決,我們一個個看。
命令行工(gōng)具(jù)
package.json 中(zhōng)有(yǒu)一個字段是 bin:
{ ..."bin": {"mywxapp":"./index.js"} }等價于在 terminal 中(zhōng)執行:
~/path/to/index.js
執行 index.js 時,可(kě)以通過 process.argv 獲取執行時的參數,但是要從參數數組中(zhōng)拆分(fēn)出參數無疑很(hěn)麻煩。不過,npm 發展至今,處理(lǐ)命令行參數的庫肯定存在,就是commander。簡單好用(yòng)易上手,那麽第二個問題也解決啦。
項目模闆的存放位置
考慮項目模闆的存放位置,是集成到工(gōng)具(jù)中(zhōng),還是和工(gōng)具(jù)分(fēn)開呢(ne)?
開發者選擇分(fēn)開管理(lǐ)。 在一個單獨的模闆代碼倉庫中(zhōng)管理(lǐ)模闆内容,方便我們維護。目前的模闆還比較簡單(詳見下文(wén)“模闆詳解”),隻有(yǒu)标準目錄結構,預期後面會加上自動化的部分(fēn)(比如 less -> wxss),所以未來會改動比較頻繁。
download-git-repo 可(kě)以把給定地址的倉庫内容拷貝到執行目錄中(zhōng)。API 簡單,所以就是它了。
問題都解決了,現在就讓我們看看僞代碼(注意:僞碼中(zhōng)沒有(yǒu)考慮出錯情況):
const mkdirp = require(\'mkdirp\'); const download = require(\'download-git-repo\'); // 創建項目functioninitProj(projName){if(currentDir.exsits(projName)) console.warn(projName \'項目已經存在于當前目錄中(zhōng),請使用(yòng)别的名(míng)字\');elsedownload(\'path/to/tmpl\', currentDir \'/\'projName); } // 注冊頁(yè)面functionregisterPage(pagesName) { // 讀配置文(wén)件readFile(configFile,function(data){ // 将新(xīn)建的所有(yǒu)頁(yè)面都寫入配置文(wén)件中(zhōng)for(nameinpagesName){ data.pages.push(\'pages/\'name \'/\'name); } writeFile(configFile); }); } // 創建頁(yè)面functioncreatePage(pages) {for(var indexinpages) { var page = pages[index]; mkdirp(pagePath,function(){ createFile(page \'.wxml\'); createFile(page \'.wxss\'); createFile(page \'.js\'); }) } // 将頁(yè)面注冊到 app.json 中(zhōng) registerPage(pages); }
使用(yòng)
在編寫好了這個工(gōng)具(jù)之後,隻需要在本地全局使用(yòng)的話:
npminstall -g在本地開發過程中(zhōng),如果更新(xīn)了開發版本的代碼,需要更新(xīn)同步到全局,這時候需要執行:
npmlink
~/Documents/kmokidd/cli-build$npmlink/usr/local/bin/wxapp -> /usr/local/lib/node_modules/@kmokidd/wxapp-generator/index.js/usr/local/bin/node_modules/@kmokidd/wxapp-generator -> /Users/kmokidd/Documents/kmokidd/cli-build/index.js
使用(yòng)起來是這樣的:
發布 NPM 插件
如果和筆(bǐ)者一樣,希望在多(duō)個機器上使用(yòng)這個工(gōng)具(jù),可(kě)以選擇發布到 npm 官網上。發布步驟非常簡單,基本上就是:
npmloginnpmpublish不過廣州微信小(xiǎo)程序開發正在互聯考慮到,項目模闆畢竟是因人而異的東西,所以選擇了發布 scope package,也就是在插件的 package.json 中(zhōng)的 name 字段使用(yòng) @scopeName/wxapp-generator 這樣的值。
如果你也有(yǒu)類似的想法,并且也是個 npm 免費用(yòng)戶,那麽發布的時候要執行:
npmpublish --access publicscope 對使用(yòng)沒有(yǒu)任何影響,但是安(ān)裝(zhuāng)的時候要記得帶上 scope name 執行:
npminstall@scopeName/wxapp-generator-g模闆詳解
一千個人中(zhōng)有(yǒu)一千種項目模闆。根據業務(wù)/個人愛好不同,大家的項目模闆可(kě)能(néng)也相去甚遠(yuǎn)。筆(bǐ)者自覺目前的模闆用(yòng)起來還不錯,将在這一節介紹一下。以下是項目的文(wén)件結構:
wxapp ├── app.js ├── app.json ├── app.wxss ├──base-styles/ ├── images/ ├── pages/ │ ├── tmpl/ ├── utils / │ ├── view.js │ ├── util.js │ ├── polyfiil.js └── └── Deferred.js之所以采用(yòng)這樣的結構,是希望盡可(kě)能(néng)解耦 UI 邏輯與業務(wù)邏輯。但是由于完全解耦是不可(kě)能(néng)的,基本思路是單純的“變量分(fēn)離”。通常 UI 的改變是通過 class 的切換或者内聯樣式的調整,所以筆(bǐ)者的思路,是将“要切換的 class”或者“要調整的内聯樣式”作(zuò)為(wèi)變量,由于大部分(fēn)情況下業務(wù)邏輯和 UI 變化是聯動的,通過抽離出來的變量,實現在業務(wù)邏輯中(zhōng)簡單直白地改變 UI。
可(kě)能(néng)看到這裏,讀者會有(yǒu)些困惑,那讓我們直接以「企鵝聽書」為(wèi)例,具(jù)象地看看筆(bǐ)者是怎麽做的吧。聽書的界面會出現變化的時以下兩種場景:
1、一共有(yǒu)兩種播放器:minibar 和 全屏的播放器,播放器的播放按鈕有(yǒu)“播放”和“暫停”兩種狀态(圖片)切換,這個可(kě)以通過 class 來控制。
2、當播放器進入全屏模式後,節目列表将被隐藏;點擊箭頭以後,節目列表将重新(xīn)顯示出來。
上文(wén)的文(wén)件結構中(zhōng)的 view.js 就是 UI 邏輯的代碼。pages/ 目錄中(zhōng)的 js 文(wén)件将通過import 引用(yòng) view.js,view.js 中(zhōng)的接口分(fēn)為(wèi)“通用(yòng)”和“頁(yè)面使用(yòng)”這兩個類型:
module.exports = { // 通用(yòng) general: { hide: \'hide\', // 變量分(fēn)離在此 show: \'show\'}, // 播放器頁(yè)面 playerView : { class: { listItemPlaying: \'playing\'} } // 其他(tā)頁(yè)面如果也有(yǒu)需要,以頁(yè)面為(wèi)單位添加... }
如果未來出現更多(duō) UI 變化的場景,可(kě)以再通過變量添加上去,比如 pageView.id。
舉個超級簡單的例子(如下),模拟工(gōng)作(zuò)流程:
- 在 wxss 中(zhōng)定義好控制不同樣式的 class
- 将需要變化的 class 寫到 view.js 中(zhōng),并暴露接口
- 在 wxml 中(zhōng)的對應結構中(zhōng)綁定 event handler
- 在對應的 page.js 裏實現 event handler 的具(jù)體(tǐ)内容,也就是切換 class 的觸發條件
老司機一看就知道是 MVVC 模式,這樣分(fēn)離也就是為(wèi)了 UI 有(yǒu)獨立的控制器,不至于和業務(wù)邏輯耦合嚴重,在頁(yè)面開發的階段就可(kě)以完成 UI 上的變化。從這個角度上看,小(xiǎo)程序反而能(néng)給 UI 工(gōng)程師更多(duō)控制 UI 邏輯的能(néng)力,确定好代碼規範和接口。
總結
初始化一個項目是開始編碼的第一步,值得多(duō)花(huā)一些時間找到合适團隊合适自己的項目模闆。
-
1497448715在剛剛結束的微信公(gōng)開課小(xiǎo)程序專場,官方講師及案例嘉賓關于小(xiǎo)程序規則、規劃,以及小(xiǎo)程...
-
1495204169據廣州微信小(xiǎo)程序開發公(gōng)司正在互聯小(xiǎo)編了解,2016年12月30日,微信公(gōng)衆平台上線(xiàn)小(xiǎo)程序二維碼...