微信小程序「官方示例代碼」剖析【下】:運(yùn)行機(jī)制

在上一篇《微信小程序「官方示例代碼」淺析【上】》中,我們只是簡單的羅列了一下代碼,這一篇,讓我們來玩點(diǎn)刺激的——就是看看IDE的代碼,了解它是怎么運(yùn)行的。

還好微信的開發(fā)團(tuán)隊(duì)在軟件工程的實(shí)踐還有待提高,我們才有機(jī)會可以深入了解他們的代碼——真想建議他們看看Growth的第二部分,構(gòu)建系統(tǒng)。

解壓應(yīng)用

首先你需要有下面的工具啦

  • Mac電腦
  • 微信web開發(fā)者工具.app
  • WebStorm / 其他編程器 或 IDE,最好可以支持重命名

首先,我們需要右鍵微信web開發(fā)者工具.app,然后顯示包的內(nèi)容,在 Contents/Resources/app.nw下面的內(nèi)容即是我們的代碼,拷貝出來啦:

drwxr-xr-x@   7 fdhuang  staff   238B Sep 22 19:43 app
drwxr-xr-x@   4 fdhuang  staff   136B Sep 21 13:12 modified_modules
drwxr-xr-x@ 194 fdhuang  staff   6.4K Sep 21 13:12 node_modules
-rw-r--r--    1 fdhuang  staff   900B Sep 22 21:09 package.json

簡單的說明一下:

  • app/ 目錄下放置了app的代碼
  • modified_modules/ 即一些修改后的模塊
  • node_modules/ 地球人都知道
  • package.json 呵呵,你一定是知道的,配置了NW相關(guān)的內(nèi)容

modified_modules目錄下有兩個(gè)子模塊:

  • anyproxy,從名字就可以看起來這是一個(gè)代理模塊
  • weinre,遠(yuǎn)程調(diào)試工具

IDE運(yùn)行順序

我們已經(jīng)知道了這是一個(gè)NodeWebkit封裝的Web應(yīng)用了。

在package.json中的"main": "app/html/index.html",,即定義了這個(gè)APP的入口是這個(gè)index.html,而不是別的文件。

很順利的我們看到了他們調(diào)用的文件了:

<script src="../dist/app.js"></script>

這里面有一個(gè)init方法,看來他就是NodeWebkit相關(guān)的入口了。用WebStorm的shift + f6 RENAME 這些變量好十幾次,終于看到了下面的代碼了:

var React = require("../dist/lib/react.js");
var reactDom = require("../dist/lib/react-dom.js");
var init = require("../dist/common/loadInit/init.js");
var controller = require("../dist/components/ContainController.js");
var proxy = require("../dist/common/proxy/startProxy.js");
var windowActions = require("../dist/actions/windowActions.js");
var webViewAction = require("../dist/actions/webviewActions.js");
var webViewStore = require("../dist/stroes/webviewStores.js");
var log = require("../dist/common/log/log.js");
var shortCut = require("../dist/common/shortCut/shortCut.js");
var isDev = global.appConfig.isDev;

這是一個(gè)React應(yīng)用,還好我一年多以前學(xué)得不錯(cuò)。掃視了一下代碼,終于看到了這一句:

reactDom.render(React.createElement(controller, null), document.querySelector("#container")

直接跳轉(zhuǎn)到ContainController.js,跳轉(zhuǎn)到render方法,找到了這個(gè):

React.createElement(Main, {
    project: this.state.project,
    appQuit: this.appQuit,
    appMax: this.appMax,
    appMin: this.appMin
})

果然Main里面就是大入口了

React.createElement("div", {className: "main"},
    React.createElement(menuBar, {
        appQuit: this.props.appQuit,
        appMin: this.props.appMin,
        appMax: this.props.appMax,
        showSetting: this.showSetting,
        project: this.props.project
    }),
    React.createElement(toolbar, {project: this.props.project}),
    React.createElement("div", {
            className: "body"
        },
        React.createElement(sidebar, {
            project: this.props.project,
            optProject: this.optProject
        }),
        React.createElement(develop, {
            show: this.state.show,
            optDebugger: this.optDebugger,
            project: this.props.project
        }),
        React.createElement(edit, {
            show: this.state.show,
            project: this.props.project
        }),
        React.createElement(detail, {
            project: this.props.project,
            show: this.state.show
        })),
    React.createElement(toast, null),
    React.createElement(setting, {
        show: this.state.showSetting,
        showSetting: this.showSetting
    }),
    React.createElement(dialog, null),
    React.createElement(popup, null),
    React.createElement(about, null))
}

對應(yīng)的就是下面這個(gè)界面了:

editor-face.jpg
  • edit 就是編輯器及其相關(guān)的事項(xiàng)
  • detail就是項(xiàng)目的配置

WeApp是如何運(yùn)行的

慢慢的就探索到了打包,其運(yùn)行時(shí)的過程。由于我并沒有拿到內(nèi)測資格,所以我只好邊看邊猜測一下。

在之前的文章中,我們提到了兩點(diǎn)很有意思的東西:wxmlwxss,這兩個(gè)文件會被分別轉(zhuǎn)換,即wxml -> html,wxss -> css。對應(yīng)的有幾個(gè)不同的transform:

  • transWxmlToJs
  • transWxssToCss
  • transConfigToPf
  • transWxmlToHtml
  • transManager

這里的PF指代的是PageFrame的意思,pageFrame有一個(gè)對應(yīng)的模板文件:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
 <link  rel="Shortcut Icon">
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
 <script>
   var __webviewId__;
 </script>
 <!-- percodes -->
 <!--{{WAWebview}}-->
 <!--{{reportSDK}}-->
 <!--{{webviewSDK}}-->
 <!--{{exparser}}-->
 <!--{{components_js}}-->
 <!--{{virtual_dom}}-->
 <!--{{components_css}}-->
 <!--{{allWXML}}-->
 <!--{{eruda}}-->
 <!--{{style}}-->
 <!--{{currentstyle}}-->
 <!--{{generateFunc}}-->
</head>
<body>
 <div></div>
</body>
</html>

這種風(fēng)格一看就是生成字符串Replace的,然后他們寫了一個(gè)名為wcc以及一個(gè)名為wcsc的工具。

  • wcc用于轉(zhuǎn)轉(zhuǎn)wxml中的自定義tag為virtual_dom
  • wcsc,我觀察到的現(xiàn)象是它為轉(zhuǎn)換wxss為css

這樣的話,我們就可以理解為微信小應(yīng)用有點(diǎn)類似于 Virtual Dom + WebView,畢竟上面有個(gè)WAWebView文件 ,還有一個(gè)webviewSDK文件 。

當(dāng)然無論是React + WebView,或者Vue + WebView都不重要,現(xiàn)在有了 WA + WebView了,哈哈。

WeApp采用的是如下圖所示的提交方式,所以:

commit.jpg

你在本地寫的WeApp都會被提交到微信服務(wù)器,然后打包,上傳到服務(wù)器,交給CDN——畢竟為了分發(fā)。

上傳的過程大致如下:

好了,瞎扯完了,睡覺準(zhǔn)備寫繼續(xù)寫新書了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容