微信小程序 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 + ‘“)’),
…..

更多相关文章

  1. Android读写XML(下)——创建XML文档
  2. Android(安卓)APK开发 Drawable文件夹下的自定义Drawable文件
  3. Android跨进程bindService与callback
  4. Android系统权限和root权限
  5. Android(安卓)解决65535的限制 使用android-support-multidex解
  6. 全面认识Android中Gradle相关配置文件
  7. Android(安卓)中Ninja 简介
  8. android中SharedPreferences用法详解
  9. Android深入浅出之Zygote

随机推荐

  1. Android系统结构
  2. 限制EditText输入文字的数目
  3. Android 接口定义语言 (AIDL)
  4. ViewPager用法(一)图片+原点+循环播放
  5. 使用最新版AndroidStudio2.0进行NDK开发
  6. android 导入新工程或是编译没了android.
  7. Android远程服务编写和调用教程
  8. 谈谈关于Android视频编码的那些坑
  9. android中color的值
  10. Android手机操作系统中实现图片浏览