欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

微信小程序 require机制详解及实例代码

程序员文章站 2023-11-10 15:50:16
微信小程序 require机制详解 一, js模块加载:一次性加载全部js, 但并不一定立即执行. 先提一提微信小程序架构: 类浏览器 -> http本地服务...

微信小程序 require机制详解

一, js模块加载:一次性加载全部js, 但并不一定立即执行.

先提一提微信小程序架构: 类浏览器 -> http本地服务 -> 云端服务

微信小程序运行的架构,基本上是浏览器 -> http本地服务 -> 云端服务, http本地服务用来读取本地文件或者代理云端的文件资源。读取项目中js文件, 是由http本地服务取本地存储的脚本文件.

似乎比较简单,一个html 引用所有js文件

既然采用了这种架构,那微信小程序就类似浏览器那样,借助一个html页面来引用加载所有的js文件。(注:这同node.js的方式区别)

在小程序开发开具的http服务部分代码,可以看到这个服务干了这件事情:

微信小程序包目录下面所有.js文件, 会按<script src="../xxx.js"> 方式插入生成一个html文件,然后类似浏览器方式加载.

让http本地服务配合,对js文件作的包装手法

可是事情并未结束,这种方式一加载,所有js文件都会立即执行,乱糟糟生成一团,怎么可能..那require函数又拿来干什么呢?原来这儿,http服务在返回.js文件内容的,给脚本内容包装上了一层: define函数

代理服务部分代码:

(projectmanager.js)
function getscripts(projinfo, callback) {
 ...
  fs.readfile(fname, 'utf8', function(err, scripts) {
    ....  
    scripts = 'define("' + modulename + '", function(require, module, exports, ' + nobrowserstr +
    '){ ' + scripts + '\n});',
    needrequire && (scripts += 'require("' + modulename + '")'), //page页面js文件,会添加上require自己,加载后立即初始化。
    .....
    callback(null, scripts) //scripts串内容作为http get的返回

define函数非常简单,大致如下:

......
  var 
  ......
  modulelist = {}; 
  define = function(modulename, factory) { //define是全局函数,每个js文件都默认会调用. 
    modulelist[modulename] = { status: status1, factory: factory }
  };

从上面代码看出,,这样一来,每加载一个js文件,只是将其文件名与脚本内容串加入了内存中的一个变量保存,并未执行。 注意,这就与普通的html 脚本引用加载立即执行完全不同了.

接下来,就轮到微信小程序的require函数出场了。

二, js模块初始化:按需递归式require初始化

先看看微信小程序require函数的定义:

....
  require = function(modulename) {    
    ....
    var module = modulelist[modulename]; //define函数调用时为modulelist赋的值
    .....
    if (module.status === status1) { 
      //如果未初始化,则初始化
      var factory = module.factory, //这个factory就是这个js文件的脚本.
      obj = { exports: {} }, u = void 0;
      factory && (u = factory(o(modulename), obj, obj.exports)), module.exports = obj.exports || u, module.status = status2
    }
    return module.exports
  }

从上面可以看出, require函数只是通过模块名,从内存中获取脚本内容执行,并置标志以保证只执行一次.

再精简一下:

require --调用-> factory --->模块中可能再require另一个模块...

这样就是一个典型的递归结构。

三,补充一下:页面js 其实也是被require函数加载

所谓页面js,,就是在app.json中注册的page的js, 它们并没有被其它js require方式引用,

那么它们在什么时候初始化?

回到之前本地代理服务器的代码,留意下面一点:

代理服务部分代码:
(projectmanager.js)
function getscripts(projinfo, callback) {
 ...
  fs.readfile(fname, 'utf8', function(err, scripts) {
    ....  
    //page页面js文件,needrequire值为true,会添加上require自己
    needrequire && (scripts += 'require("' + modulename + '")'), 
    .....

原来它们还是使用require函数初始化,而且是加载后立即执行。

目前通常微信小程序代码结构不会太复杂,但随着产品的发展,需求的增加, 代码结构可能越来越复杂,越来越注意模块化.同时,如何将旧有js模块在微信小程序中重用,这也是个重要话题。 所以深入理解微信小程序的js模块化机制也是很有价值的.

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!