中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

從源碼看微信小程序啟動(dòng)過(guò)程

2018-07-20    來(lái)源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

一、寫作背景

接觸小程序一年多,真實(shí)體驗(yàn)就是小程序開(kāi)發(fā)門檻相對(duì)而言確實(shí)比較低。不過(guò)小程序的開(kāi)發(fā)方式,一直是開(kāi)發(fā)者吐槽的,如習(xí)慣了 Vue,React 開(kāi)發(fā)的開(kāi)發(fā)者經(jīng)常會(huì)吐槽小程序一個(gè) Page 必須由多個(gè)文件組成,組件化支持不完善或者說(shuō)不能非常愉快的開(kāi)發(fā)組件。在以前小項(xiàng)目中沒(méi)太大感覺(jué),從加入有贊,參與有贊微商城小程序的開(kāi)發(fā),是真切的體會(huì)到對(duì)于大型小程序項(xiàng)目開(kāi)發(fā)的復(fù)雜性。

有贊從微信小程序內(nèi)測(cè)就開(kāi)始開(kāi)發(fā)小程序,在不支持自定義組件的時(shí)代,只能通過(guò) import 的形式拆分模塊或?qū)崿F(xiàn)組件。在業(yè)務(wù)復(fù)雜的頁(yè)面,可能會(huì) import 非常多的模塊,而相應(yīng)的 wxss 也需要 import 樣式,除了操作繁瑣,有時(shí)候也難免遺漏。

作為開(kāi)發(fā)者,我們當(dāng)然希望可以讓工作更簡(jiǎn)單,更愉快,也希望改善我們的開(kāi)發(fā)方式。所以希望能夠更了解微信小程序框架,減少不必要的試錯(cuò),于是有了一次對(duì)小程序框架的 debug 之旅。(基礎(chǔ)庫(kù) 1.9.93)

通過(guò)三周空余時(shí)間的 debug,也算對(duì)小程序框架有了一些淺顯的認(rèn)識(shí),達(dá)到了最初的目的;對(duì)小程序啟動(dòng),實(shí)例,運(yùn)行等有了真切的體會(huì)。這篇文章記錄了小程序框架的基本代碼結(jié)構(gòu),啟動(dòng)流程,以及程序?qū)嵗^(guò)程。

本文的目的是希望把我看到的分享給對(duì)小程序感興趣或者正在開(kāi)發(fā)小程序的讀者,主要解答“框架對(duì)傳入的對(duì)象等到底做了什么”。

二、從啟動(dòng)流程一窺小程序框架細(xì)節(jié)

在開(kāi)發(fā)者工具中使用 help() 方法,可以查看一些指令和方法。使用其中的 openVendor 方法可以打開(kāi)微信開(kāi)發(fā)者工具在小程序框架所在目錄。其中以包括以基礎(chǔ)庫(kù)命名的目錄和其他幫助文件,如其中有兩個(gè)工具 wcc,wcsc。wcc 可把 wxml 轉(zhuǎn)換為對(duì)應(yīng)的 JS 函數(shù) —— $gwx(path, global),wcsc 可將 wxss 轉(zhuǎn)換為 css。而基礎(chǔ)庫(kù)目錄包括 WAService.js 和 WAWebview.js 文件。小程序框架在開(kāi)發(fā)者工具中以 WAService.js 命名(WAWebview.js 不知其作用,聽(tīng)說(shuō)在真機(jī)環(huán)境使用該文件)。

在開(kāi)發(fā)中工具命令行使用 document.head 可以查看到小程序的啟動(dòng)流程大致如下: 以小節(jié)的方式分別介紹這些流程,小程序是如何處理的(小節(jié)編號(hào)與圖中編號(hào)相同)。

1、初始化全局變量

下圖是小程序啟動(dòng)是初始化的一些全局的變量:

那些使用“__”開(kāi)頭,未在文檔中提及可使用變量是不建議使用的,__wxAppCode__ 在開(kāi)發(fā)者工具中分為兩類值,json 類型和 wxml 類型。以 .json 結(jié)尾的,其 key 值為開(kāi)發(fā)者代碼中對(duì)應(yīng)的 json 文件的內(nèi)容,.wxml 結(jié)尾的,其 key 值為通過(guò)調(diào)用 $gwx('./pages/example/index.wxml') 將得到一個(gè)可執(zhí)行函數(shù),通過(guò)調(diào)用這個(gè)函數(shù)可得到一個(gè)標(biāo)識(shí)節(jié)點(diǎn)關(guān)系的 JSON 樹。

2、加載框架(WAService.js)

使用工具對(duì) WAService.js 進(jìn)行格式化后進(jìn)行 debug?梢园l(fā)現(xiàn)小程序框架大致由: WeixinJSBridge 、 NativeBuffer 、 wxConsole 、 WeixinWorker 、 JavaScript 兼容 (這部分為猜測(cè))、 Reporter 、 wx 、 exparser 、 __virtualDOM__ 、 __appServiceEngine__ 幾部分組成。

其中除了 wx 和 WeixinJSBridge 這兩個(gè)基礎(chǔ) API 集合, exparser , __virtualDOM__ , __appServiceEngine__ 這三部分作為框架的核心, __appServiceEngine__ 提供了框架最基本的接口如 App,Page,Component; exparser 提供了框架底層的能力,如實(shí)例化組件,數(shù)據(jù)變化監(jiān)聽(tīng),view 層與邏輯層的交互等;而 __virtualDOM__ 則起著鏈接 __appServiceEngine__ 和 exparser 的作用,如對(duì)開(kāi)發(fā)者傳入 Page 方法的對(duì)象進(jìn)行格式化再傳入 exparser 的對(duì)應(yīng)方法處理。

框架對(duì)外暴露了以下API:Behavior,App,Page,Component,getApp,getCurrentPages,definePlugin,requirePlugin,wx。

3、業(yè)務(wù)代碼的加載

在小程序中,開(kāi)發(fā)者的 JavaScript 代碼會(huì)被打包為

define('xxx.js', function(require, module, exports, window, document, frames, self, location, navigator, localStorage, history, Caches, screen, alert, confirm, prompt, fetch, XMLHttpRequest, WebSocket, webkit, WeixinJSCore, Reporter, print, WeixinJSBridge) {  
  'use strict';

  // your code
})

這里的 define 是在框架中定義的方法,在框架中提供了兩個(gè)方法:require 和 define 用來(lái)定義和使用業(yè)務(wù)代碼。其方式有些像 AMD 規(guī)范接口,通過(guò) define 定義一個(gè)模塊,使用 require 來(lái)應(yīng)用一個(gè)模塊。但是也有很大區(qū)別,首先 define 限制了模塊可使用的其他模塊,如 window,document;其次 require 在使用模塊時(shí)只會(huì)傳入 require 和 module,也就是說(shuō)參數(shù)中的其他模塊在定義的模塊中都是 undefined,這也是不能在開(kāi)發(fā)者工具中獲取一些瀏覽器環(huán)境對(duì)象的原因。

在小程序中,JavaScript 代碼的加載方式和在瀏覽器中也有些不同,其加載順序是首先加載項(xiàng)目中其他 js 文件(非注冊(cè)程序和注冊(cè)頁(yè)面的 js 文件),其次是注冊(cè)程序的 app.js,然后是自定義組件 js 文件,最后才是注冊(cè)頁(yè)面的 js 代碼。而且小程序?qū)τ谠?app.js 以及注冊(cè)頁(yè)面的 js 代碼都會(huì)加載完成后立即使用 require 方法執(zhí)行模塊中的程序。其他的代碼則需要在程序中使用 require 方法才會(huì)被執(zhí)行。

下面詳細(xì)介紹了 app.js,自定義組件,頁(yè)面 js 代碼的處理流程。

4、加載 app.js 與注冊(cè)程序

在 app.js 加載完成后,小程序會(huì)使用 require('app.js') 注冊(cè)程序,即對(duì) App 方法進(jìn)行調(diào)用,App 方法是對(duì) __appServiceEngine__.App 方法的引用。

下圖是框架對(duì)于 App 方法調(diào)用時(shí)的處理流程:

App 方法根據(jù)傳入的對(duì)象實(shí)例化一個(gè) app 實(shí)例,其生命周期函數(shù) onLaunch 和 onShow 因?yàn)槭褂貌煌姆绞将@取 options的參數(shù)。在有些需要根據(jù)場(chǎng)景值來(lái)實(shí)現(xiàn)需求的,或許使用 onShow 中的場(chǎng)景值更合適。

在實(shí)際開(kāi)發(fā)過(guò)程中發(fā)現(xiàn),在微信頂部喚起小程序和在小程序列表喚起的 options 也是不一樣的。在該案例中通過(guò)點(diǎn)擊分享的小程序進(jìn)入后,關(guān)閉小程序,再通過(guò)不同方式進(jìn)入小程序,通過(guò)頂部喚起的還是 options 的 path 屬性還是分享出來(lái)的 path,但是通過(guò)列表中打開(kāi)直接回到了首頁(yè),這里 App 中的 onShow 就會(huì)獲取到不同的 options。

5、加載自定義組件代碼以及注冊(cè)自定義組件

自定義組件在 app.js 之后被加載,小程序會(huì)在這個(gè)過(guò)程中加載完所有的自定義組件(分包中自定義組件沒(méi)有有測(cè)試過(guò)),并且是加載完成后自動(dòng)注冊(cè),只有注冊(cè)完成后才會(huì)加載下一個(gè)自定義組件的代碼。

下圖是框架對(duì)于 Component 方法處理流程:

圖中介紹了框架如何對(duì)傳入 Component 方法的對(duì)象的處理,其后面還有很多深入的對(duì)于組件實(shí)例化的步驟沒(méi)有在圖中表示出來(lái),具體可以在文章最后的附件中查看。

自定義組件在小程序中越來(lái)越完善,其擁有的能力也比 Page 更強(qiáng)大,而后面會(huì)提到在使用自定義組件的 Page 中,Page 實(shí)例也會(huì)使用和自定義組件一樣的實(shí)例化方式,也就是說(shuō),他擁有和自定義組件一樣的能力。

6、加載頁(yè)面代碼和注冊(cè)頁(yè)面

加載頁(yè)面代碼的處理流程和加載自定義組件一樣,都是加載完成后先注冊(cè)頁(yè)面,然后才會(huì)加載下一個(gè)頁(yè)面。

下圖是注冊(cè)一個(gè)頁(yè)面時(shí)框架對(duì)于 Page 方法的處理流程:

Page 方法會(huì)根據(jù)是否使用自定義組件做不同的處理。使用自定義組件的 page 對(duì)象會(huì)被處理為和自定義組件的結(jié)構(gòu),并在頁(yè)面實(shí)例化時(shí)使用不同的處理流程進(jìn)行實(shí)例化。當(dāng)然對(duì)于開(kāi)發(fā)而言沒(méi)任何不同。

從圖中可以發(fā)現(xiàn) Page 傳入的(生命周期)代碼并不會(huì)在這里被執(zhí)行,可以通過(guò)下面小節(jié)了解 Page 實(shí)例化的詳細(xì)過(guò)程。

7、等待頁(yè)面 Ready 和 Page 實(shí)例化

還記得上面介紹的啟動(dòng)流程中最后一步等待頁(yè)面 Ready?嚴(yán)格來(lái)講是等待瀏覽器 Ready,小程序雖然有部分原生的組件,不過(guò)本質(zhì)上還是一個(gè) web 程序。

在小程序中切換頁(yè)面或打開(kāi)頁(yè)面時(shí)會(huì)觸發(fā) onAppRoute 事件,小程序框架通過(guò) wx.onAppRoute 注冊(cè)頁(yè)面切換的處理程序,在所有程序就緒后,以 entryPagePath 作為入口使用 appLaunch 的方式進(jìn)入頁(yè)面。

下圖是處理導(dǎo)航的程序流程:

從圖中可以看出頁(yè)面的實(shí)例化是在進(jìn)入頁(yè)面時(shí)進(jìn)行,下圖是具體的實(shí)例化過(guò)程:

下圖是最終可得到 Page 實(shí)例:

可以發(fā)現(xiàn)其中多了 onRouteEnd API,實(shí)際該接口不會(huì)被調(diào)用。其中以 component 標(biāo)記的表示只有在使用了自定義組件時(shí)才會(huì)有的方法和屬性。在前面第 5 小節(jié)提到了對(duì)于使用自定義組件的頁(yè)面會(huì)按照自定義組件方式解析,這些屬性和方法與自定義組件表現(xiàn)一致。

8、關(guān)于 setData

小程序框架是一個(gè)以數(shù)據(jù)驅(qū)動(dòng)的框架,當(dāng)然不能少了對(duì)他如何實(shí)現(xiàn)數(shù)據(jù)綁定的探索,下圖是 Page 實(shí)例的 setData 執(zhí)行流程:

其中 component:setData 表示使用自定義組件的 Page 實(shí)例的 setData 方法。

三、寫在最后

這是一次不完全的小程序框架探索,是在微信開(kāi)發(fā)工具中 debug 的結(jié)果。雖然對(duì)于實(shí)際開(kāi)發(fā)沒(méi)有什么太大的幫助,但是對(duì)框架如何對(duì)開(kāi)發(fā)的 js 代碼進(jìn)行處理有了一個(gè)很明確的認(rèn)識(shí),在使用一些 js 特性時(shí)可以有明確的感知。如果你還疑惑“小程序框架對(duì)傳入的對(duì)象等到底做了什么”那一定是我表達(dá)能力太差,說(shuō)聲對(duì)不起。

通過(guò)這一次 debug ,也給我引入了新的問(wèn)題,還希望能夠有更多的討論:

  • 自定義組件太多啟動(dòng)時(shí)會(huì)耗時(shí)處理自定義組件
  • 文件太多會(huì)耗時(shí)讀文件
  • 合理的設(shè)計(jì)分包很重要

一份在調(diào)試過(guò)程中的筆記 小程序框架不完全分析.xmind ,如果看官有興趣可以下載看看。當(dāng)然最后對(duì)于框架中已有的能力,還是分層希望微信可以開(kāi)放更多穩(wěn)定的接口,并在文檔中告知開(kāi)發(fā)者,讓開(kāi)發(fā)變得簡(jiǎn)單一些。

 

來(lái)自:https://tech.youzan.com/weapp-booting/

 

標(biāo)簽: 代碼 開(kāi)發(fā)者

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:幾種開(kāi)源的媒體服務(wù)器對(duì)比

下一篇:3分鐘了解“關(guān)聯(lián)規(guī)則”推薦