微信小程式差不多已經推出了兩年半的時間,對於還沒有入坑或剛準備動手的開發同學,本文件將嘗試在幾分鐘內讓你快速的瞭解其基本開發生態,雖嫌蜻蜓點水零零碎碎,但應該可對接下來的開發做出合理的抉擇。
秉持乾溼分離的原則,本文將組織成以下結構:
I. 優點
II. 資源和生態
III. 小程式和雲開發點滴
IV. 小程式和開發者工具的基本原理
V. 《組隊點餐寶》雲開發 DEMO 小程式
VI. 擴充套件閱讀和參考資料
複製程式碼
大部分內容非常初級,大佬請輕拍或繞行,另外...
I. 優點
- 輕量,目前最大 4M,沒有手動安裝過程,點開即用
- 使用體驗:
HTML5
<微信小程式
<RN/Weex
<原生
- 開發難度:
微信小程式
<HTML5
<RN/Weex
<原生
- 開發體驗接近 Vue 和 React,相容問題少,人力成本和開發時間優勢明顯
- 推廣和上線相比原生應用更簡單
- 和微信服務號、模板訊息等互相打通
- 易用且安全的微信資料開放
- 附近小程式等功能,不用開發就能獲得實體店商業推廣
- 雲開發將開發門檻降至最低,一個前端人員就能快速完成整個開發過程
II. 資源和生態
微信公眾平臺 mp.weixin.qq.com
2.1 - 文件
2.2 - 官方社群
2.3 - 開發者工具
在原有的公眾號網頁除錯工具的基礎上,整合了公眾號網頁除錯和小程式除錯兩種開發模式
- 使用公眾號網頁除錯,開發者可以除錯微信網頁授權和微信JS-SDK 詳情
- 使用小程式除錯,開發者可以完成小程式的 API 和頁面的開發除錯、程式碼檢視和編輯、小程式預覽和釋出等功能
相關概念:公眾號網頁
許多複雜的業務場景,需要通過網頁形式來提供服務,這時需要用到:
- 通過網頁授權獲取使用者的 OpenID 和基本資訊等
- 開發者在網頁上通過微信 JS-SDK 工具包,在網頁上實現錄製和播放微信語音、監聽微信分享、上傳手機本地圖片、拍照等許多能力
相關概念:微信小遊戲
- 一種特殊型別的小程式,沒有小程式 WXML 等,更接近傳統 H5 遊戲
- 主要程式設計物件是 Canvas 畫布,所有東西都是通過繪製到可見畫布來展示的
- Cocos、Egret、Laya 等遊戲引擎都適配了小遊戲開發
擴充套件雜談:Egret 白鷺引擎
- 創始人原來是 Adobe 中國的 flash 佈道師,很大程度上覆制了原有的成功思路和生態
- 提供了完整的 2D/3D 開發引擎、完善的開發除錯工具等產品
堪稱 ActionScript3 復刻版的 API 設計:
2.4 - 市場上的同類小程式
2.5 - 第三方開發框架
微信小程式必須在官方的開發者工具圖形介面中開發、除錯、上傳,這限制了預處理樣式、轉譯圖片等前端開發常用能力,也無法使用 npm 引入第三方包或使用常見的開發框架
一種最簡單的思路是開發一些用 npm scripts 執行 node.js 指令碼,完成上述官方工具中不方便的工作,此時一般的目錄結構是在“官方規範程式碼”外面包裹一層,如:
├ mock/
├ assets/
├ dist/ # 這裡存放開發者工具中的標準程式碼
│ ├ ...
│ └ pages/index/
│ ├ index.js
│ ├ index.json
│ ├ index.wxml
│ └ index.wxss # 由外部 less/sass 實時生成,不手動編輯
├ # 也包含了轉換後的外部路徑或編碼後的圖片
├ styles/
├ nodemon.json
├ package.json
└ dev.js # 一些 watch、轉譯等工作
複製程式碼
這種方式雖然“簡陋”,但由於基本上還是用的原生開發,所以不用擔心官方升級後(還是相當頻繁的)不匹配等問題。
不過畢竟 bigger 略低,能力提升很有限,更多平時前端專案中積累的程式碼也無法直接複用;
藉助 AST 轉譯的能力,市面上更多成熟的解決方案提供了更好的選擇:
Taro
一套遵循 React 語法規範的多端統一開發框架
- 京東“凹凸實驗室”出品,長期保持更新維護
- 一鍵生成 微信小程式、H5、ReactNative、百度小程式、位元組跳動小程式、支付寶小程式
- 採用 React 語法標準,支援 JSX 書寫,讓程式碼更具表現性
- 支援 TypeScript
- 支援使用 npm/yarn 安裝管理第三方依賴
- 支援使用 ES7/ES8 甚至更新的 ES 規範,可自行配置
- 支援使用 CSS 預編譯器,例如 Sass 等
- 支援使用 Redux/MobX 進行狀態管理
- 小程式 API 優化,非同步 API Promise 化等等
- 配套的開發工具 Taro CLI 讓開發流程自動化
WePy
騰訊開發的“讓小程式支援元件化開發的框架”
- 開發風格接近於 Vue.js,支援 Props、自定義事件、Mixin、computed、slot 等
- 支援使用第三方 npm 資源
- 通過 polyfill 讓小程式完美支援 Promise
- 可使用 Generator Fu-nction / Class / Async Function 等特性
- 支援 Less/Sass/Styus,wx-ml/Pug,Babel/Typescript
- 支援多種外掛處理,如檔案壓縮,圖片壓縮,內容替換等,擴充套件簡單
mpVue
美團出品的“一個使用 Vue.js 開發小程式的前端框架”
- 徹底的元件化開發能力:提高程式碼複用性
- 完整的
Vue.js
開發體驗 - 方便的
Vuex
資料管理方案:方便構建複雜應用 - 快捷的
webpack
構建機制:自定義構建策略、開發階段 hotReload - 支援使用 npm 外部依賴
- 使用
Vue.js
命令列工具vue-cli
快速初始化專案 - H5 程式碼轉換編譯成小程式目的碼的能力
2.6 - 適用於小程式的元件庫等
WeUI
視覺規範
幾種具體技術的實現版本
應用在小程式中
wxParse
微信小程式富文字解析元件,支援 HTML 及 Markdown 轉 WXML 視覺化
小程式釋出之初並不支援直接內嵌 h5 頁面,這讓很多躍躍欲試直接用既有公眾號頁面擴充入口的商家和開發者怨聲載道。
不到一年後,開始支援 <web-view>
元件,但也特別宣告瞭個人型別與海外型別的小程式暫不支援使用。
這使得一些嵌入網頁和構建富文字的工作變得困難,也讓 wxParse
元件至今仍然富有意義。
miniprogram-simulate
新出現的小程式自定義元件測試工具集
由於小程式有獨特的執行環境,所以對於小程式自定義元件的單元測試一直沒有比較優雅的解決方案;
此工具集就是為了解決這一痛點,將原本小程式自定義元件雙執行緒分離執行的機制調整成單執行緒模擬執行,利用 dom 環境進行渲染,藉此來完成整個自定義元件樹的搭建。
執行此工具集需要依賴 js 執行環境和 dom 環境,因此可以採用 jsdom + nodejs(如 jest),也可以採用真實瀏覽器環境(如 karma)
const path = require('path')
const expect = require('chai').expect
describe('component', () => {
it ('should run successfully', () => {
// 直接使用全域性的 simulate
const id = simulate.load(path.resolve(__dirname, '../src/component/index'))
const comp = simulate.render(id, {prop: 'index.test.properties'})
comp.attach(document.body) // 掛載在 body 下面
expect(
simulate.match(
comp.dom,
'<wx-view class="main--index">index.test.properties</wx-view>'
)
).to.equal(true)
})
})
複製程式碼
III. 小程式和雲開發點滴
登入態和幾種術語
AppID
每個小程式對應一個,在開發階段開始前從開放平臺申請
- 註冊成功之後,點選 “開發”—“開發設定” 可以看到 AppID
- 需要在開發者工具中填入 AppID,才能開始編輯專案
- 當場景為由從另一個小程式或公眾號開啟時,能在小程式的 wx.onShow 回撥中獲得來源的 AppID
- 用 iOS 或 Android 的 OpenSDK 開發原生 APP,並涉及到開啟小程式時,需要配置 AppID
- AppId 是公開資訊,洩露 AppId 不會帶來安全風險
AppSecret
- AppSecret 是開發者的隱私資料不應該洩露
code
由小程式端呼叫 wx.login(),從微信伺服器獲取的一個帶有時效性的憑證
- 有效期為 5 分鐘
- 由開發者伺服器傳送 code 等到微信伺服器,換取 openid、session_key、unionid 等
openid
也就是使用者 id,可以用這個 id 來區分不同的微信使用者
unionid
使用者在微信開放平臺的唯一識別符號
- 同一個微信開放平臺帳號下的移動應用、網站應用和公眾帳號(包括小程式),使用者的unionid是唯一的
- 在滿足不同條件的前提下,可以通過 wx.login() 或 wx.getUserInfo() 獲得
session_key
微信伺服器給開發者伺服器頒發的身份憑證,開發者可以用 session_key 請求微信伺服器其他介面來獲取一些其他資訊
- 如果每次都通過小程式前端 wx.login() 生成 code 去微信伺服器請求資訊,整體耗時嚴重
- 對於一個比較可信的服務端,session_key 相當於給開發者端頒發一個時效性更長的會話金鑰
- session_key 也存在過期時間
SessionID
開發者伺服器和開發者的小程式之間的會話金鑰,一般稱為 SessionID
- 使用者登入成功之後,由開發者伺服器需要生成,並儲存對應的使用者身份資訊
- 把 SessionId 返回給小程式,在後續發起的請求中攜帶上 SessionId
- 這樣就不需要每次都重新獲取 code,省去了很多通訊消耗
OpenSDK
開發者的第三方 APP 需要喚起小程式等操作時,需要整合對應版本的開發工具包
JS-SDK
微信公眾平臺面向網頁開發者提供的基於微信內的網頁開發工具包
wx-server-sdk
雲開發時,在“雲函式”中引用的 npm 包,
wx-server-sdk
與小程式端的雲 API 以同樣的風格提供了資料庫、儲存和雲函式的 API
雲開發簡述
開發者可以使用雲開發開發微信小程式、小遊戲,無需搭建伺服器,即可使用雲端能力
雲開發弱化了後端和運維概念,無需搭建伺服器,使用平臺提供的 API 進行核心業務開發,即可實現快速上線和迭代。
目前提供三大基礎能力支援:
- 雲函式:在雲端執行的程式碼,微信私有協議天然鑑權,開發者只需編寫自身業務邏輯程式碼
- 資料庫:一個既可在小程式前端操作,也能在雲函式中讀寫的 JSON 資料庫
- 儲存:在小程式前端直接上傳/下載雲端檔案,在雲開發控制檯視覺化管理
在雲開發中簡化登入態的獲取
不同於之前章節中獲取登入態的複雜,雲開發時極度的簡化了這一過程。
比如有一個雲函式 test
:
// cloudfunction/test/index.js
const cloud = require('wx-server-sdk')
exports.main = (event, context) => {
// 這裡獲取到的 openId、 appId 和 unionId 是可信的
const {OPENID, APPID, UNIONID} = cloud.getWXContext()
return {
OPENID,
APPID,
UNIONID,
}
}
複製程式碼
上傳並部署該雲函式後,可在小程式中測試呼叫:
wx.cloud.callFunction({
name: 'test',
complete: res => {
console.log('callFunction test result: ', res)
}
})
複製程式碼
會在偵錯程式看到輸出的 res
為如下結構的物件:
{
"APPID": "xxx",
"OPENID": "yyy",
"UNIONID": "zzz" // 僅在滿足 unionId 獲取條件時返回
}
複製程式碼
部分資源配額
分類 | 配額種類 | 額度 |
---|---|---|
儲存 | 容量 | 5 GB |
雲函式 | 呼叫次數 | 20 萬次 / 月 |
資料庫 | 容量 | 2 GB |
IV. 小程式和開發者工具的基本原理
小程式實現原理
執行環境 | 邏輯層 | 渲染層 |
---|---|---|
iOS | JavaScriptCore | WKWebView |
安卓 | X5 JSCore | X5瀏覽器 |
小程式開發者工具 | NWJS | Chrome WebView |
不太一樣的 JS 方言
小程式中的 JavaScript 同瀏覽器或 NodeJS 中的 JavaScript 都是不相同的:
- 小程式缺少相關的 DOM API 和 BOM API,這導致了 jQuery 等無法執行
- JSCore 的環境同 NodeJS 環境也是不盡相同,所以一些 NPM 的包也無法執行
JSCore
JSCore 是 WebKit 預設內嵌的單執行緒 JS 引擎,進行詞法分析、語法分析以及解釋執行等工作
- 詞法分析階段,將原始碼分解成 Token 序列
- 對 Token 序列進行語法分析,並生成對應的一棵抽象語法樹(AST)
- ByteCode Generator 根據 AST 生成 JSCore 的位元組碼,完成語法分析
- 用 LLInt 和 JIT 解釋執行位元組碼
雙執行緒模式
- 在傳統網頁開發中, JS 引擎與 GUI 渲染引擎兩個執行緒是互斥的,所以 JS 執行指令碼時間過長會引起頁面渲染載入阻塞導致其渲染的不連貫
- 在小程式中,邏輯層和渲染層是分開的,邏輯層執行在 JSCore 中,渲染層用 webview 實現
- 渲染層和邏輯層的通訊會經由 Native 中轉
- 邏輯層傳送網路請求也經由 Native 轉發
- 在渲染層,宿主環境會把 WXML 轉化成對應的表示樹狀結構的 JS 物件
- 在邏輯層發生資料變更的時候,通過宿主環境提供的 setData 方法把資料從邏輯層傳遞到渲染層,形成新的結構 JS 資料物件
- 再經過對比新舊結構 JS 物件的前後差異,把差異應用在原來的 Dom 樹上
- 一類事件是“使用者在渲染層的行為反饋”,比如點選
- 另一類事件是“元件的部分狀態反饋”,比如播放進度變化
- 以上兩類渲染層事件抽象後,經過 Native 轉發給邏輯層
開發者工具實現原理
- 基於 NW.js,一種 Chromium + Node.js 實現的跨平臺桌面打包技術
- 用系統 API 來實現底層模組,使用 React、Redux 等前端技術框架來搭建使用者互動層
- 引用了 monaco-editor 等外掛實現編輯器功能
- 用 webview 實現預覽視窗部分
- 用 webview + chrome 原生除錯工具實現偵錯程式
結合官網的介紹,並基於開源的 github.com/cytle/wecha… 專案,一窺相關實現:
預覽視窗
預覽視窗檢視在微信開發者工具上 WebView 是一個 chrome 中的 <webview />
標籤。與<iframe />
標籤不同的是,<webview/>
標籤是採用獨立的執行緒執行的。
- 移動端的 JsCore 是一個單純的指令碼解析器,為此開發者工具做了一個很巧妙的工作,將瀏覽器的 BOM 物件區域性變數化,從而使得在開發階段就能發現問題。
- 用於模擬小程式邏輯層的
<webview/>
載入的連結是
http://127.0.0.1:9973/appservice/appservice
複製程式碼
預覽視窗邏輯
編輯視窗
編輯器檢視 編輯器邏輯 編輯器邏輯 編輯器邏輯除錯視窗
偵錯程式邏輯- nw.js 對
<webview/>
提供開啟 Chrome Devtools 除錯介面的介面,使得開發者工具具備對小程式的邏輯層和渲染層進行除錯的能力 - 同時為了方便除錯小程式,開發者工具在 Chrome Devtools 的基礎上進行擴充套件和定製
- 通過在 devtoolsWebView 中注入指令碼的方式將 Chrome Devtools 的 Element 皮膚隱藏,同時提供了 Chrome Devtools 外掛 WXML 皮膚
V. 《組隊點餐寶》雲開發 DEMO 小程式
午飯吃什麼?每到此時總是和同事同學意見不統一?來試試這個小程式~
當然選好地方後也可以看看原始碼,對雲函式、雲資料庫的用法有個直觀印象:
VI. 擴充套件閱讀和參考資料
--End--
搜尋 fewelife 關注公眾號
轉載請註明出處