微信小程序 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 操作css实现代码
Jun 11 Javascript
jQuery 遍历- 关于closest() 的方法介绍以及与parents()的方法区别分析
Apr 26 Javascript
javascript操作html控件实例(javascript添加html)
Dec 02 Javascript
js处理表格对table进行修饰
May 26 Javascript
禁止iframe页面的所有js脚本如alert及弹出窗口等
Sep 03 Javascript
JavaScript通过字典进行字符串翻译转换的方法
Mar 19 Javascript
JavaScript实现Java中Map容器的方法
Oct 09 Javascript
javascript 单例模式详解及简单实例
Feb 14 Javascript
vue 2.x 中axios 封装的get 和post方法
Feb 28 Javascript
详解Vue源码学习之callHook钩子函数
Jul 25 Javascript
Vue-cli3项目配置Vue.config.js实战记录
Jul 29 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
Oct 11 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 获取远程网页内容的函数
2009/09/08 PHP
php Smarty date_format [格式化时间日期]
2010/03/15 PHP
php表单提交实例讲解
2015/11/12 PHP
php实现当前页面点击下载文件的简单方法
2016/09/22 PHP
体验js中splice()的强大(插入、删除或替换数组的元素)
2013/01/16 Javascript
解析Javascript中中括号“[]”的多义性
2013/12/03 Javascript
JS运动基础框架实例分析
2015/03/03 Javascript
js获取当前日期时间及其它日期操作汇总
2016/03/08 Javascript
浅谈JavaScript 浏览器对象
2016/06/03 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
2016/10/09 Javascript
利用jQuery来动态为属性添加或者删除属性的简单方法
2016/12/02 Javascript
Javascript Event(事件)的传播与冒泡
2017/01/23 Javascript
微信小程序 引用其他js文件实现代码
2017/02/22 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
2017/06/16 jQuery
vue2组件之select2调用的示例代码
2017/10/12 Javascript
在vue项目中使用Nprogress.js进度条的方法
2018/01/31 Javascript
细说Vue组件的服务器端渲染的过程
2019/05/30 Javascript
微信小程序使用车牌号输入法的示例代码
2019/08/20 Javascript
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
javascript实现前端分页效果
2020/06/24 Javascript
[03:55]2016国际邀请赛中国区预选赛首日TOP10精彩集锦
2016/06/27 DOTA
Python使用Socket(Https)Post登录百度的实现代码
2012/05/18 Python
Python实现的计数排序算法示例
2017/11/29 Python
Flask框架WTForm表单用法示例
2018/07/20 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
Python装饰器结合递归原理解析
2020/07/02 Python
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
娇韵诗俄罗斯官方网站:Clarins俄罗斯
2020/10/03 全球购物
AJAX都有哪些有点和缺点
2012/11/03 面试题
参观监狱心得体会
2014/01/02 职场文书
公司担保书格式范文
2014/05/12 职场文书
机械专业毕业生自我鉴定2014
2014/10/04 职场文书
2014年客房部工作总结
2014/11/22 职场文书
2015年大学生村官工作总结
2015/04/21 职场文书
2015年保洁员工作总结
2015/05/04 职场文书
Jupyter notebook 更改文件打开的默认路径操作
2021/05/21 Python