微信小程序 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 相关文章推荐
一个用js实现的页内搜索代码
May 23 Javascript
JS 对输入框进行限制(常用的都有)
Jul 30 Javascript
js控制浏览器全屏示例代码
Feb 20 Javascript
jQuery子属性过滤选择器用法分析
Feb 10 Javascript
javascript制作游戏开发碰撞检测的封装代码
Mar 31 Javascript
javascript中Function类型详解
Apr 28 Javascript
vue.js利用defineProperty实现数据的双向绑定
Apr 28 Javascript
微信小程序如何利用getCurrentPages进行页面传值
Jul 01 Javascript
jquery 回调操作实例分析【回调成功与回调失败的情况】
Sep 27 jQuery
详解Vue后台管理系统开发日常总结(组件PageHeader)
Nov 01 Javascript
jquery实现弹窗(系统提示框)效果
Dec 10 jQuery
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
May 18 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
做个自己站内搜索引擎
2006/10/09 PHP
PHP操作MongoDB GridFS 存储文件的详解
2013/06/20 PHP
PHP使用Pear发送邮件(Windows环境)
2016/01/05 PHP
【消息提示组件】,兼容IE6/7&amp;&amp;FF2
2007/09/04 Javascript
兼容ie和firefox js关闭代码
2008/12/11 Javascript
百度 popup.js 完美修正版非常的不错 脚本之家推荐
2009/04/17 Javascript
node.js中的http.response.end方法使用说明
2014/12/14 Javascript
node.js中的fs.readlinkSync方法使用说明
2014/12/17 Javascript
详谈js使用in和hasOwnProperty获取对象属性的区别
2017/04/25 Javascript
layer子层给父层页面元素赋值,以达到向父层页面传值的效果实例
2017/09/22 Javascript
webpack构建的详细流程探底
2018/01/08 Javascript
详解vue的diff算法原理
2018/05/20 Javascript
关于node-bindings无法在Electron中使用的解决办法
2018/12/18 Javascript
微信小程序模板消息限制实现无限制主动推送的示例代码
2019/08/27 Javascript
Vue事件处理原理及过程详解
2020/03/11 Javascript
vue路由权限校验功能的实现代码
2020/06/07 Javascript
vue插件--仿微信小程序showModel实现模态提示窗功能
2020/08/19 Javascript
swiperjs实现导航与tab页的联动
2020/12/13 Javascript
python类型强制转换long to int的代码
2013/02/10 Python
Python中turtle作图示例
2017/11/15 Python
python 将print输出的内容保存到txt文件中
2018/07/17 Python
python操作日志的封装方法(两种方法)
2019/05/23 Python
selenium2.0中常用的python函数汇总
2019/08/05 Python
Python使用pymysql模块操作mysql增删改查实例分析
2019/12/19 Python
在HTML5中如何使用CSS建立不可选的文字
2014/10/17 HTML / CSS
MADE法国:提供原创设计师家具
2018/09/18 全球购物
异常和异常类的概念
2014/09/12 面试题
Linux上比较文件的命令都有哪些
2012/02/24 面试题
如果重写了对象的equals()方法,需要考虑什么
2014/11/02 面试题
外贸员简历中的自我评价
2014/03/04 职场文书
机关中层领导干部群众路线教育实践活动个人对照检查材料
2014/09/24 职场文书
大学生入党积极分子党校学习思想汇报
2014/10/25 职场文书
2015毕业设计工作总结
2015/07/24 职场文书
2016年教师新年寄语
2015/08/18 职场文书
什么是css原子化,有什么用?
2022/04/24 HTML / CSS
Windows server 2012搭建FTP服务器
2022/04/29 Servers