[觀點]微信小程序開發(fā)三宗罪和解決方案

在微信公布小程序的文檔和開發(fā)工具后,我們在第一時間進(jìn)行了學(xué)習(xí)和體驗,發(fā)現(xiàn)微信小程序的技術(shù)架構(gòu)和開發(fā)體驗讓我們有些失望。由于微信小程序的運行環(huán)境并不是一個標(biāo)準(zhǔn)的瀏覽器環(huán)境,而且微信的封裝工作并不完善,所以我們以往開發(fā)中的很多經(jīng)驗并不適用。這并非簡單的開發(fā)習(xí)慣不適應(yīng),更重要的是我們的開發(fā)流程、規(guī)范將不適用。
微信小程序開發(fā)第一宗罪: 無法調(diào)用NPM包
雖然微信小程序開發(fā)工具打包時實現(xiàn)了require函數(shù)加載依賴,但并不是完整的CommonJS依賴管理。因為require函數(shù)僅僅能夠加載項目中的JS文件,而且必須嚴(yán)格定義JS文件路徑,路徑不支持CommonJS的路徑風(fēng)格。例如如下加載方式都將出錯:
require('lodash');require('lodash/map');require('./foo');

在微信小程序開發(fā)工具中,我們必須對應(yīng)寫為如下格式:
require('node_modules/lodash/lodash.js');require('node_modules/lodash/map.js');require('./foo.js');

雖然我們可以像上面代碼一樣加載node_modules目錄中的庫,但是實際運行時卻發(fā)生了:


在調(diào)試工具的Network選項卡中,我們看到運行時加載了1000多個文件,總數(shù)據(jù)量1.8MB,而我們僅僅是在代碼中加載了一個lodash庫而已!這是因為微信小程序開發(fā)工具會將所有項目下的js文件視為項目文件,并進(jìn)行打包。而實際開發(fā)中,我們需要安裝很多的NPM擴展庫,而這些擴展庫中有大量的不需要打包的文件,例如lodash中有上千文件,而我們只需要用到其中的非常少的一部分。
另外,在開發(fā)中,我們往往需要安裝babal、eslient、webpack、grunt等待開發(fā)工具,微信小程序開發(fā)工具會一視同仁將這些工具的源碼也進(jìn)行打包......實測開發(fā)者工具將崩潰!開發(fā)者將崩潰!我崩潰!
所以不支持NPM包的原因,是微信開發(fā)者工具不支持CommonJS標(biāo)準(zhǔn),不支持CommonJS標(biāo)準(zhǔn)的原因,是微信開發(fā)者工具想當(dāng)然地認(rèn)為項目目錄下的js文件一定是項目文件,所以只實現(xiàn)了簡單的require函數(shù),想當(dāng)然的原因是。。。
微信小程序開發(fā)第二宗罪: 無法使用Babel轉(zhuǎn)碼
無法使用Babel轉(zhuǎn)碼的原因其實仍然歸結(jié)于無法加載NPM庫。但是后果將十分嚴(yán)重。因為你將不能再安全使用ES6/7特性,你將無法使用async/await函數(shù),你將和無盡的callback做斗爭,你該怎樣描述自己?回調(diào)地獄中的苦逼程序員?
如果你看到這里不明白Babel為何物,那么祝賀你,因為不曾見過天堂就不知何為地獄,你無須為不支持ES6/7而煩惱。但一旦你的大腦支持了ES6/7,用過了Babel,你就回不去了,像我一樣,無Babel不編碼。
微信小程序開發(fā)第三宗罪: 無法重用組件
**其實微信小程序開發(fā)是并非完全不能重用組件,比如WXML語法中支持import和 include。但是那僅僅是視圖模板可重用,并非組件可重用,因為我們認(rèn)為組件在應(yīng)當(dāng)包含視圖和邏輯。
WXML其實是基于可重用的組件,但是不允許我們自定義組件。如果你有React經(jīng)驗,你就會明白我的意思。
例如,你的小程序是個電商APP,項目中有兩個頁面中同時包含了商品列表組件,比如某分類下商品列表和搜索結(jié)果列表,我們知道這兩個列表其實僅僅是參數(shù)不同而已。但是在小程序開發(fā)中,你只能將列表的模板抽象出來,不能將邏輯抽象出來,所以你就需要在兩個頁面上都實現(xiàn)一遍列表組件的控制邏輯,比如刷新、加載更多。。。
我們的實踐
只吐槽、管殺不管埋是不道德的,既然發(fā)現(xiàn)了微信小程序開發(fā)中的各種弊端,我們在開發(fā)之中總結(jié)出了一套流程和工具,專為解決上述三個問題,并免費發(fā)布到了開源社區(qū),這就是Labrador。接下來我們一起來嘗試一下我們的開發(fā)體驗。
安裝Labrador
通過命令 npm install -g labrador-cli
全局安裝Labrador控制行工具。
初始化項目
通過如下命令新建一個Labrador項目:
mkdir democd demonpm initlabrador init

項目初始化完成后,該目錄是這個樣子的:

圖中的src是我們的源碼目錄,node_modules是NPM包目錄,dist是目標(biāo)輸出目錄。請在開發(fā)者工具中新建一個項目,并設(shè)置路徑到dist目錄,請勿設(shè)置為demo目錄!使用WebStorm或Sublime打開demo目錄,開發(fā)過程中,我們使用WebStorm或Sublime修改src目錄下的源碼,請勿直接修改dist目錄中的文件,因為dist目錄是通過labrador命令生成的。
在demo目錄中運行 labrador build
命令編譯項目,該命令會將src目錄下的文件一一處理并生成dist目錄下對應(yīng)的文件。我們也可以運行 labrador watch 命令監(jiān)控src目錄下的文件變化,這樣就不用每次修改后手動運行編譯命令。
加載NPM包
我們以lodash包為例,在src/app.js中鍵入代碼 const _ = require('lodash');
編譯后,我們看到dist目錄下的文件是這樣的:[圖片上傳中。。。(3)]
我們看到dist目錄下有一個npm/lodash目錄,該目錄下只有一個lodash.js文件,那么在微信web開發(fā)者工具中打包預(yù)覽,lodash的庫將只有這個文件被加載。
這一切是怎么發(fā)生的?
我們看一下dist/app.js的源碼,發(fā)現(xiàn)源碼中const _ = require('lodash');
被編譯為 var _ = require('./npm/lodash/lodash.js');
然后labrador命令將node_modules/lodash/lodash.js
文件復(fù)制到了 dist/npm/lodash/lodash.js
。這就是通過labrador可以調(diào)用NPM包的原理。
重要的是,只有真正用到的js文件才被labrador命令加入到項目目錄中。這樣一個小小的改進(jìn)象征著我們的小程序可以便捷調(diào)用NPM倉庫中海量的擴展庫!
Babel轉(zhuǎn)碼
在初始化的示例代碼src/app.js中的內(nèi)容是這樣的:
[圖片上傳中。。。(4)]
圖中timer和getUserInfo屬性都為async函數(shù),函數(shù)體內(nèi)使用await調(diào)用異步操作。labrador 庫對微信API進(jìn)行了封裝,使用 const wx = require('labrador'); 覆蓋默認(rèn)的全局變量wx; 封裝后的wx對象提供的異步方法返回的都是Promise異步對象,結(jié)合async/await函數(shù)徹底終結(jié)callback,將異步代碼同步寫,輕松逃離回調(diào)地獄!
但目前async/await函數(shù)是不被瀏覽器支持的,我們需要使用babel對其轉(zhuǎn)碼,labrador編譯命令已經(jīng)內(nèi)置了babel轉(zhuǎn)碼,轉(zhuǎn)碼后的代碼可以查看dist/app.js,內(nèi)容過長,不再張貼。
重用組件
重用組件最需要解決的問題是組件的邏輯代碼怎樣重用。在實例代碼中有一個src/components目錄,用來存放項目內(nèi)的可重用組件,其結(jié)構(gòu)是這樣的:[圖片上傳中。。。(5)]
子目錄src/components/list中存放著一個可重用的組件。list.js / list.less / list.xml 分別對應(yīng)微信小程序的 js / wxss / wxml 文件。JS為控件的邏輯層,其代碼如下:[圖片上傳中。。。(6)]
文件導(dǎo)出一個List類,這個組件類擁有像Page一樣的生命周期函數(shù)onLoad, onReady, onShow, onHide, onUnload 以及setData函數(shù)。LESS文件對應(yīng)微信的WXSS文件,因為微信小程序?qū)崿F(xiàn)的限制,LESS中無法使用連級選擇語法,但是可以定義變量,方便開發(fā)。XML文件對應(yīng)微信的WXML文件,是組件視圖描述文件,list.xml內(nèi)容為:[圖片上傳中。。。(7)] 文件中導(dǎo)出一個名為list的template。組件不但可以存放在src/components目錄內(nèi),還可以單獨做成NPM包,這樣就可以輕松做到跨項目間的組件共享。
組件定義完成后,接下來是在頁面中調(diào)用,在 src/pages/index/index.js 中有如下代碼:[圖片上傳中。。。(8)] 代碼中首先引入了labrador庫替換全局的默認(rèn)wx對象,并使用labrador.createPage方法代替全局的Page函數(shù)聲明頁面。然后加載List組件類,在頁面聲明配置中,增加了components屬性,并將List組件類實例化傳入。labrador.createPage方法是對Page方法的一層封裝,目的是在頁面初始化時和組件對象進(jìn)行關(guān)聯(lián)。
在 src/pages/index/index.less 中加入代碼@import 'list' 即可調(diào)用list組件的樣式,如果在src/components/list中找不到list.less,那么編譯命令將在NPM包中尋找 node_modules/list/index.less 。
在 src/pages/index/index.xml 中加入代碼 <component key="list"/> 即可調(diào)用list組件的模板文件,component 是Labrador自定義的組件,編譯后對應(yīng)生成 import 和 template。如果在src/components/list中找不到list.xml,那么編譯命令將在NPM包中尋找 node_modules/list/index.xml
具體的體驗還需要你親自動手才行,文章到此結(jié)束,謝謝!
Hello小程序將與您共同成長。微信號:130870319 QQ群:40726600
**

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內(nèi)容