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


Posted in Javascript onDecember 14, 2016

微信小程序 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模块化机制也是很有价值的.

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

Javascript 相关文章推荐
javascript 关于# 和 void的区别分析
Oct 26 Javascript
JavaScript.The.Good.Parts阅读笔记(二)作用域&amp;闭包&amp;减缓全局空间污染
Nov 16 Javascript
IE6、IE7中获取Button元素的值的bug说明
Aug 28 Javascript
jQuery输入城市查看地图使用介绍
May 08 Javascript
jQuery网页版打砖块小游戏源码分享
Aug 20 Javascript
jquery拼接ajax 的json和字符串拼接的方法
Mar 11 Javascript
angularjs中的$eval方法详解
Apr 24 Javascript
vue2+el-menu实现路由跳转及当前项的设置方法实例
Nov 07 Javascript
使用JavaScript生成罗马字符的实例代码
Jun 08 Javascript
mpvue+vant app搭建微信小程序的方法步骤
Feb 11 Javascript
一起写一个即插即用的Vue Loading插件实现
Oct 31 Javascript
有趣的JavaScript隐式类型转换操作实例分析
May 02 Javascript
js实现获取鼠标当前的位置
Dec 14 #Javascript
详解vue.js组件化开发实践
Dec 14 #Javascript
JavaScript Ajax实现异步通信
Dec 14 #Javascript
微信小程序 配置文件详细介绍
Dec 14 #Javascript
微信小程序 闭包写法详细介绍
Dec 14 #Javascript
微信小程序 wx.uploadFile无法上传解决办法
Dec 14 #Javascript
bootstrap日历插件datetimepicker使用方法
Dec 14 #Javascript
You might like
php生成略缩图代码
2012/07/16 PHP
大家须知简单的php性能优化注意点
2016/01/04 PHP
cument.execCommand()用法深入理解
2012/12/04 Javascript
js判断浏览器类型的方法
2013/08/07 Javascript
jQuery jcrop插件截图使用方法
2013/11/20 Javascript
js 获取input点选按钮的值的方法
2014/04/14 Javascript
Javascript字符串对象的常用方法简明版
2014/06/26 Javascript
JavaScript获取当前cpu使用率的方法
2015/12/15 Javascript
AngularJS基础 ng-click 指令示例代码
2016/08/01 Javascript
easyui-edatagrid.js实现回车键结束编辑功能的实例
2017/04/12 Javascript
package.json文件配置详解
2017/06/15 Javascript
Angular 2父子组件数据传递之@ViewChild获取子组件详解
2017/07/04 Javascript
JavaScript中关于class的调用方法
2017/11/28 Javascript
微信小程序实现导航栏选项卡效果
2020/06/19 Javascript
vue watch普通监听和深度监听实例详解(数组和对象)
2018/08/16 Javascript
vue发送ajax请求详解
2018/10/09 Javascript
在vue项目中优雅的使用SVG的方法实例详解
2018/12/03 Javascript
layer扩展打开/关闭动画的方法
2019/09/23 Javascript
js实现左右轮播图
2020/01/09 Javascript
python查看FTP是否能连接成功的方法
2015/07/30 Python
python 读取文本文件的行数据,文件.splitlines()的方法
2018/07/12 Python
python try except 捕获所有异常的实例
2018/10/18 Python
Windows10下 python3.7 安装 facenet的教程
2019/09/10 Python
基于Python爬取fofa网页端数据过程解析
2020/07/13 Python
Python plt 利用subplot 实现在一张画布同时画多张图
2021/02/26 Python
德国孕妇装和婴童服装网上商店:bellybutton
2018/04/12 全球购物
AJax面试题
2014/11/25 面试题
幼儿园教学随笔感言
2014/02/23 职场文书
优秀毕业生的求职信
2014/07/21 职场文书
信息与工商管理职业规划范文:为梦想而搏击
2014/09/11 职场文书
2014教师党员自我评议总结
2014/09/19 职场文书
幼儿园音乐教学反思
2016/02/18 职场文书
二年级作文之动物作文
2019/11/13 职场文书
用CSS3画一个爱心
2021/04/27 HTML / CSS
Python卷积神经网络图片分类框架详解分析
2021/11/07 Python
如何解决goland,idea全局搜索快捷键失效问题
2022/04/03 Golang