微信小程序 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在IE和FireFox中的不同表现简析
Dec 03 Javascript
js实现汉字排序的方法
Jul 23 Javascript
javascript与Python快速排序实例对比
Aug 10 Javascript
jQuery EasyUI之DataGrid使用实例详解
Jan 04 Javascript
Bootstrap编写导航栏和登陆框
May 30 Javascript
微信小程序 教程之模板
Oct 18 Javascript
分享十三个最佳JavaScript数据网格库
Apr 07 Javascript
bootstrap daterangepicker双日历时间段选择控件详解
Jun 15 Javascript
javascript 判断用户有没有操作页面
Oct 17 Javascript
JavaScript new对象的四个过程实例浅析
Jul 31 Javascript
vue实现移动端H5数字键盘组件使用详解
Aug 25 Javascript
Vue中引入svg图标的两种方式
Jan 14 Vue.js
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
各种战术和打法的原创者
2020/03/04 星际争霸
PHP中文URL编解码(urlencode()rawurlencode()
2010/07/03 PHP
php安全之直接用$获取值而不$_GET 字符转义
2012/06/03 PHP
解析PHP正则提取或替换img标记属性
2013/06/26 PHP
php结合js实现点击超链接执行删除确认操作
2014/10/31 PHP
表单提交错误后返回内容消失问题的解决方法(PHP网站)
2015/10/20 PHP
Mac下快速搭建PHP开发环境步骤详解
2019/05/05 PHP
点击文章内容处弹出页面代码
2009/10/01 Javascript
javascript 计算两个整数的百分比值
2009/12/26 Javascript
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
2010/09/14 Javascript
js时间日期和毫秒的相互转换
2013/02/22 Javascript
jQuery建立一个按字母顺序排列的友好页面索引(兼容IE6/7/8)
2013/02/26 Javascript
js实现文章文字大小字号功能完整实例
2014/11/01 Javascript
在JavaScript应用中使用RequireJS来实现延迟加载
2015/07/01 Javascript
详解vue-cli脚手架中webpack配置方法
2018/08/22 Javascript
详解vscode中vue代码颜色插件
2018/10/11 Javascript
jQuery - AJAX load() 实例用法详解
2019/08/27 jQuery
jquery实现手风琴案例
2020/05/04 jQuery
微信小程序开发之获取用户手机号码(php接口解密)
2020/05/17 Javascript
JavaScript/TypeScript 实现并发请求控制的示例代码
2021/01/18 Javascript
[04:29]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/02/01 DOTA
python 文件与目录操作
2008/12/24 Python
Python从ZabbixAPI获取信息及实现Zabbix-API 监控的方法
2018/09/17 Python
介绍一款python类型检查工具pyright(推荐)
2019/07/03 Python
Python无头爬虫下载文件的实现
2020/04/02 Python
夏威夷灵感服装及配饰:Reyn Spooner
2018/09/18 全球购物
Lululemon加拿大官网:加拿大知名体育服装零售商
2019/04/12 全球购物
什么是Web Service?
2012/07/25 面试题
铣床操作工岗位职责
2014/06/13 职场文书
语文教育专业求职信
2014/06/28 职场文书
幼儿园重阳节活动总结
2015/05/05 职场文书
运动会闭幕式通讯稿
2015/07/18 职场文书
遗嘱范文
2015/08/07 职场文书
《一面五星红旗》教学反思
2016/02/23 职场文书
pycharm代码删除恢复的方法
2021/06/26 Python
Jackson 反序列化时实现大小写不敏感设置
2021/06/29 Java/Android