微信小程序 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 相关文章推荐
提高代码性能技巧谈—以创建千行表格为例
Jul 01 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
Dec 22 Javascript
jQuery实现简单的抽奖游戏
May 05 jQuery
ajax请求data遇到的问题分析
Jan 18 Javascript
Vue 父子组件的数据传递、修改和更新方法
Mar 01 Javascript
详解React中setState回调函数
Jun 14 Javascript
微信小程序实现弹出菜单
Jul 19 Javascript
微信小程序点击图片实现长按预览、保存、识别带参数二维码、转发等功能
Jul 20 Javascript
layui文件上传控件带更改后数据传值的方法
Sep 23 Javascript
H5实现手机拍照和选择上传功能
Dec 18 Javascript
在react中使用vue的状态管理的方法示例
May 02 Javascript
Vue的v-model的几种修饰符.lazy,.number和.trim的用法说明
Aug 05 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中使用Sockets 从Usenet中获取文件
2008/01/10 PHP
PHP curl 并发最佳实践代码分享
2012/09/05 PHP
PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题
2016/08/12 PHP
脚本之家贴图转换+转贴工具用到的js代码超级推荐
2007/04/05 Javascript
javascript setAttribute, getAttribute 在不同浏览器上的不同表现
2010/08/05 Javascript
jquery命令汇总,方便使用jquery的朋友
2012/06/26 Javascript
判断输入是否为空,获得输入类型的JS代码
2013/10/30 Javascript
webapp框架AngularUI的demo改造之路
2014/12/21 Javascript
js钢琴按钮波浪式图片排列效果代码分享
2015/08/26 Javascript
jQuery操作动态生成的内容的方法
2016/05/28 Javascript
AngularJS ng-bind 指令简单实现
2016/07/30 Javascript
ES6概念 Symbol toString()方法
2016/12/25 Javascript
用director.js实现前端路由使用实例
2017/01/27 Javascript
微信小程序基于Taro的分享图片功能实践详解
2019/07/12 Javascript
[07:55]2014DOTA2 TI正赛第三日 VG上演推进荣耀DKEG告别
2014/07/21 DOTA
python获取糗百图片代码实例
2013/12/18 Python
python实现网页链接提取的方法分享
2014/02/25 Python
python局域网ip扫描示例分享
2014/04/03 Python
python多线程方式执行多个bat代码
2016/06/07 Python
关于Python中Inf与Nan的判断问题详解
2017/02/08 Python
利用Tkinter(python3.6)实现一个简单计算器
2017/12/21 Python
手把手教你如何安装Pycharm(详细图文教程)
2018/11/28 Python
python带参数打包exe及调用方式
2019/12/21 Python
python中的subprocess.Popen()使用详解
2019/12/25 Python
keras在构建LSTM模型时对变长序列的处理操作
2020/06/29 Python
scrapy头部修改的方法详解
2020/12/06 Python
用CSS3的box-reflect来制作倒影效果
2016/11/15 HTML / CSS
大学生个人推荐信范文
2013/11/25 职场文书
英文求职信写作小建议
2014/02/16 职场文书
酒店保安领班职务说明书
2014/03/04 职场文书
个人工作表现评语
2014/04/30 职场文书
投标诚信承诺书
2014/05/26 职场文书
新闻学专业职业生涯规划范文:我的人生我做主
2014/09/12 职场文书
详解Node.js如何处理ES6模块
2021/05/15 Javascript
Python 实现绘制子图及子图刻度的变换等问题
2021/05/31 Python
JAVA API 实用类 String详解
2021/10/05 Java/Android