微信小程序 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 相关文章推荐
许愿墙中用到的函数
Oct 07 Javascript
IE与Firefox下javascript getyear年份的兼容性写法
Dec 20 Javascript
javascript 获取select下拉列表值的代码
Sep 07 Javascript
js实时监听文本框状态的方法
Apr 26 Javascript
只需五句话搞定JavaScript作用域(经典)
Jul 26 Javascript
Angularjs验证用户输入的字符串是否为日期时间
Jun 01 Javascript
iscroll.js滚动加载实例详解
Jul 18 Javascript
webpack4与babel配合使es6代码可运行于低版本浏览器的方法
Oct 12 Javascript
vue v-for 使用问题整理小结
Aug 04 Javascript
vue实现element表格里表头信息提示功能(推荐)
Nov 20 Javascript
js this 绑定机制深入详解
Apr 30 Javascript
ES6函数和数组用法实例分析
May 23 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的ob_start();控制您的浏览器cache!
2007/02/14 PHP
让PHP开发者事半功倍的十大技巧小结
2010/04/20 PHP
windows下开发并编译PHP扩展的方法
2011/03/18 PHP
windows环境下使用Composer安装ThinkPHP5
2018/05/18 PHP
laravel框架邮箱认证实现方法详解
2019/11/22 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
2020/02/27 PHP
JS异常处理的一个想法(sofish)
2013/03/14 Javascript
获取鼠标在div中的相对位置的实现代码
2013/12/30 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
2014/08/11 Javascript
显示今天的日期js代码(阳历和农历)
2014/09/30 Javascript
极易被忽视的javascript面试题七问七答
2016/02/15 Javascript
JavaScript ES6的新特性使用新方法定义Class
2016/06/28 Javascript
canvas实现环形进度条效果
2017/03/23 Javascript
详解webpack2+React 实例demo
2017/09/11 Javascript
fetch 使用及如何接收JS传值
2017/11/11 Javascript
看看“疫苗查询”小程序有温度的代码
2018/07/31 Javascript
Python 数据处理库 pandas 入门教程基本操作
2018/04/19 Python
python:print格式化输出到文件的实例
2018/05/14 Python
pytorch 加载(.pth)格式的模型实例
2019/08/20 Python
python处理excel绘制雷达图
2019/10/18 Python
opencv python图像梯度实例详解
2020/02/04 Python
Python使用shutil模块实现文件拷贝
2020/07/31 Python
HTML5拍照和摄像机功能实战详解
2019/01/24 HTML / CSS
使用Html5中的cavas画一面国旗
2019/09/25 HTML / CSS
加拿大著名的奢侈品购物网站:SSENSE(支持中文)
2020/06/25 全球购物
Java基础面试题
2014/07/19 面试题
自考毕业生自我鉴定
2013/11/04 职场文书
工程管理专业毕业生自荐信
2014/01/24 职场文书
实习老师离校感言
2014/02/03 职场文书
《中彩那天》教学反思
2014/02/22 职场文书
辞职信怎么写
2015/02/27 职场文书
生产车间主任岗位职责
2015/04/08 职场文书
Python基础之数据结构详解
2021/04/28 Python
Python基础知识学习之类的继承
2021/05/31 Python
Python pandas求方差和标准差的方法实例
2021/08/04 Python
Tomcat执行startup.bat出现闪退的原因及解决办法
2022/04/20 Servers