Home  >  Article  >  WeChat Applet  >  Mini program execution process analysis

Mini program execution process analysis

王林
王林forward
2021-02-03 10:31:113120browse

Mini program execution process analysis

Introduction:

WeChat mini program, a kind of mini program, the English name is Wechat Mini Program, is an application that does not require downloading and installation. It realizes the dream of having applications “at your fingertips”, allowing users to open applications by scanning or searching.

After the application is fully open, developers who are enterprises, governments, media, other organizations or individuals can apply to register mini programs. WeChat mini programs, WeChat subscription accounts, WeChat service accounts, and WeChat enterprise accounts are parallel systems.

We have been doing basic services recently, all of which are to improve the technical system. For the front end, we need to build a Hybrid system. If you are building an App, React Native is also a good choice. But there must be complete layering:

① The underlying framework solves the problem of development efficiency, turning the complex parts into a black box, and only showing three fixed tools for page development, and it can be developed in a fixed mode

② The engineering department encapsulates a minimal development environment for business developers. The best is a browser. If it is not possible, it will provide a browser-like debugging environment.

In this way, the business can Rapid iteration, because the codes written by business developers are similar, so the underlying framework and the engineering team (usually the same team) can solve many efficiency and performance problems at the bottom level.

A slightly larger company and a slightly more generous team will also do a lot of subsequent performance monitoring and error logging work simultaneously, thus forming a set of documents ->Development->Debugging->Build-> ;Release->Monitoring and analysis are a complete technical system

If such a system is formed, then even subsequent internal framework changes and technological innovations will be based on this system, but it is a pity , many teams will only do part of this path, but will not go deeper due to various reasons. They may feel that it is worthless, and the most terrifying behavior is to rashly change the basic framework before their own system is formed, so be careful!

In terms of third-party application access, WeChat should be the best. Baidu has direct accounts and other similar products, but its systematic feel still needs to be improved. Alibaba should also have similar products. When technical products are born, from our perspective, we don’t know much about them, so they are either poorly operated or poorly done.

Since the birth of mini programs, I have been paying attention to them. So far, the entire mini program system is very complete. Tencent mini programs and Tencent Cloud are deeply integrated. If you use the developer tools for internal testing, all It’s free. Pure JS can handle the front-end and back-end of the mini program. No servers, storage, CDN, or service codes are needed. It’s all free. After developing the back-end, you don’t need to operate and maintain it yourself. The rhythm of the big killer. I sometimes think about Tencent’s technical strength. It’s really strong!

Structure traceability of the mini program

The development documentation of the mini program is relatively complete. It is still the account application->demo process. Once you are familiar with it, you can start coding. The process of putting it on the shelves is ready. The front-end code is built with tools and then uploaded. The back-end service is maintained by itself and the address mapping is configured. We only focus on the development process here, and all can be done using its test account.

1 appid wx0c387cc8c19bdf78
2 appsecret acd6c02e2fdca183416df1269d2e3fb9

After more than a year of development, the documentation formed by the mini program has been relatively complete. We can make a rough judgment about the mini program from the documentation and demo:

Mini program execution process analysis

Here is the code of the mini program that business personnel can see. From this code and operation, we can basically guess the outline of the mini program. Here, first take a look at its global controller APP:

//app.js
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null
  }
})

An application will only have one APP instance, and the applet provides several basic event definitions for this single instance. The ones we use most should be onLaunch, onShow, and onHide (I haven’t written the applet yet, so I’m guessing ):

Mini program execution process analysis

Let’s trace the execution logic of the applet architecture layer and how to instantiate it from APP to a view. Here we first clarify a few points:

① In fact, the WeChat applet still provides a webview execution environment, so we can still access properties such as window and location in the js environment

② All the displays provided by the WeChat applet are Native Customized UI, so don’t think about DOM operations

You can imagine that there is a webview in the mini program interface that executes the real code logic, but this webview does nothing except load js programs. Do it, and all page rendering is Native communication performed by js through URL Schema or JSCore, which is called Native to complete the page rendering according to the set rules.

Global Controller App

这里我们重点关注全局控制器App这个类做了什么,因为拿不到源码,我们这里也只能猜测加单步调试了,首先微信容器会准备一个webview容器为我们的js代码提供宿主环境,容器与构建工具会配合产出以下页面:

Mini program execution process analysis

他在这里应该执行了实例化App的方法:

Mini program execution process analysis

这一坨代码,在这个环境下便相当晦涩了:

y = function() {
            function e(t) {
                var n = this;
                o(this, e),
                s.forEach(function(e) {
                    var o = function() {
                        var n = (t[e] || i.noop).bind(this);
                        Reporter.__route__ = "App",
                        Reporter.__method__ = e,
                        (0,
                        i.info)("App: " + e + " have been invoked");
                        try {
                            n.apply(this, arguments)
                        } catch (t) {
                            Reporter.thirdErrorReport({
                                error: t,
                                extend: "at App lifeCycleMethod " + e + " function"
                            })
                        }
                    };
                    n[e] = o.bind(n)
                });
                for (var r in t)
                    !function(e) {
                        g(e) ? (0,
                        i.warn)("关键字保护", "App's " + e + " is write-protected") : v(e) || ("[object Function]" === Object.prototype.toString.call(t[e]) ? n[e] = function() {
                            var n;
                            Reporter.__route__ = "App",
                            Reporter.__method__ = e;
                            try {
                                n = t[e].apply(this, arguments)
                            } catch (t) {
                                Reporter.thirdErrorReport({
                                    error: t,
                                    extend: "at App " + e + " function"
                                })
                            }
                            return n
                        }
                        .bind(n) : n[e] = t[e])
                    }(r);
                this.onError && Reporter.registerErrorListener(this.onError);
                var l = function() {
                    "hang" === (arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}).mode && (f = !0);
                    var e = (0,
                    a.getCurrentPages)();
                    e.length && (e[e.length - 1].onHide(),
                    (0,
                    u.triggerAnalytics)("leavePage", e[e.length - 1], !0)),
                    this.onHide(),
                    (0,
                    u.triggerAnalytics)("background")
                }
                  , h = function() {
                    var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
                    if (0 === e.scene || "0" === e.scene ? e.scene = c : c = e.scene,
                    e.query = e.query || {},
                    (0,
                    i.hasExitCondition)(e) && (p = !0),
                    this.onShow(e),
                    (0,
                    u.triggerAnalytics)("foreground"),
                    d || e.reLaunch)
                        d = !1;
                    else {
                        var t = (0,
                        a.getCurrentPages)();
                        t.length && (t[t.length - 1].onShow(),
                        (0,
                        u.triggerAnalytics)("enterPage", t[t.length - 1], !0))
                    }
                };
                if ("undefined" != typeof __wxConfig && __wxConfig) {
                    var y = __wxConfig.appLaunchInfo || {};
                    y.query = y.query || {},
                    c = y.scene,
                    (0,
                    i.hasExitCondition)(y) && (p = !0),
                    this.onLaunch(y),
                    (0,
                    u.triggerAnalytics)("launch"),
                    h.call(this, y)
                } else
                    (0,
                    i.error)("App Launch Error", "Can not find __wxConfig");
                wx.onAppEnterBackground(l.bind(this)),
                wx.onAppEnterForeground(h.bind(this)),
                _.call(this, "function" == typeof t.onPageNotFound)
            }
            return r(e, [{
                key: "getCurrentPage",
                value: function() {
                    (0,
                    i.warn)("将被废弃", "App.getCurrentPage is deprecated, please use getCurrentPages.");
                    var e = (0,
                    a.getCurrentPage)();
                    if (e)
                        return e.page
                }
            }]),
            e
        }();

Mini program execution process analysis

这里会往App中注册一个事件,我们这里注册的是onLaunch事件,这里对应的是当小程序初始化时候会执行这个回调,所以原则上应该是Native装在成功后会执行这个函数,这里再详细点说明下H5与Native的交互流程(这里是我之前做Hybrid框架时候跟Native同事的交互约定,小程序应该大同小异):

我们一般是在全局上会有一个对象,保存所有需要Native执行函数的对象,比如这里的onLaunch,Native在执行到一个状态时候会调用js全局环境该对象上的一个函数
因为我们js注册native执行是以字符串key作为标志,所以Native执行的时候可能是window.app['onLauch...']('参数')
而我们在window对象上会使用bind的方式将对应的作用域环境保留下来,这个时候执行的逻辑便是正确的

这里在小程序全局没有找到对应的标识,这里猜测是直接在app对象上,Native会直接执行APP对象上面的方法,但是我这里有个疑问是View级别如果想注册个全局事件该怎么做,这个留到后面来看看吧,这里是Native载入webview时,会执行对象定义的onLaunch事件,在下面的代码看得到:

Mini program execution process analysis

这里会结合app.json获取首先加载页面的信息,默认取pages数组第一个,但是具体哪里获取和设置的代码没有找到,也跟主流程无关,我们这里忽略......然后我们看到代码执行了onShow逻辑:

Mini program execution process analysis

然后流转到注册微信容器层面的事件,我觉得,无论如何,这里应该是像微信容器注册事件了吧,但是我找不到全局的key

Mini program execution process analysis

Page流程

如果有微信小程序的同学,麻烦这里指点一下,是不是猜测正确,顺便可以帮忙说明下这里,这里也是我觉得全局key,被Native调用的点,然后,逻辑上会获取默认view的类开始做实例化,我们这里来到view级别代码:

//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    motto: 'Hello Wor11ld',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  }
})

他首先一来便获取了当前app实例:

const app = getApp()

其次开始了view实例化流程,这个是Page的类入口,大家要注意view.js只是定义的类,但是其实例化应该在全局的控制器,其实例化在这里完成的:

Mini program execution process analysis

总结

我们这里一起瞎子摸象一般对微信小程序架构做了简单的摸索,这里发现事实上小程序流程与自己所想有一些出入,这里初步认为流程是这样的:

① 我们写好小程序代码后,提交代码

② 在发布流程中我们的代码经过构建流程,app.json以及入口的index.html(伪造页面),重新组装为一个只有js代码的空页面

③ 这里开始载入流程,用户点击一个微信按钮,进入小程序

④ 微信容器开启Hybrid容器,webview载入入口页面(我感觉应该有个规则可以通过url去打开固定一个小程序页面,这里后续碰到开发案例再说)

⑤ webview执行环境实例化App,其后自动装载默认Page(这里默认是index)

PS:这里我有个很疑惑的点,微信Native容器的各个事件点什么时候执行,由谁执行?

⑥ 进入页面渲染逻辑

⑦ ......

这里我还比较在意,执行事件后,对应Native页面是如何进行更新的,所以我们这里关注下这段代码:

1 debugger;
2 this.setData({
3   userInfo: app.globalData.userInfo,
4   hasUserInfo: true
5 })

Mini program execution process analysis

这里出现了一段非常关键的代码:

Mini program execution process analysis

Mini program execution process analysis

可以看到,我们这里往微信容器注册了一个appDataChange的异步事件,而这个时候就将所有的逻辑交给了Native本身,Native执行结束后会根据webviewIds找到后续要执行的回调继续执行。

Mini program execution process analysis

至于,容器如何使用webviewId找到对应函数的代码,我没有找到。至此,我们对小程序结构的初步探索便结束了,我们本周后面时间继续来对小程序进行深入学习。

相关推荐:小程序开发教程

The above is the detailed content of Mini program execution process analysis. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:cnblogs.com. If there is any infringement, please contact admin@php.cn delete