微信小程序 require机制详解及实例代码_JavaScript

微信小程序 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模块化机制也是很有价值的.

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索require
, 微信小程序
require机制详解
微信小程序 实例详解、微信小程序 require、小程序 require、javascript require、javascript中require,以便于您获取更多的相关知识。

时间: 2024-11-01 08:40:02

微信小程序 require机制详解及实例代码_JavaScript的相关文章

微信小程序 scroll-view组件实现列表页实例代码_JavaScript

scroll-view组件介绍 scroll-view是微信小程序提供的可滚动视图组件,其主要作用是可以用来做手机端经常会看到的上拉加载下拉刷新列表页!下面就以<摇出微笑>为例来讲解一下这个组件的使用吧! 为app导入新page页面 首先需要为我们的小程序导入新的page页面,项目根目录打开app.json这个项目配置文件在里面的pages数组添加"pages/allJoke/allJoke"然后设置底部导航在"tabBar"的列表项("lis

JavaScript 闭包机制详解及实例代码_javascript技巧

首先要区分两个概念,一是匿名函数,一是闭包. 所谓匿名函数,就是创建函数没有给定函数名.经常出现的包括函数表达式,就是定义一个匿名函数,然后将函数赋值给某个变量,而此时这个变量就相当于该函数的函数名,例如: var sayHi = function(){ alert("Hi"); }; //注意这个分号 sayHi(); //调用函数 还有一种常用匿名函数的情况是回调函数,如 JQuery 中常用到的: $("p").click(function(){ alert(

Java 反射机制详解及实例代码_java

Java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 package Reflect; /** * 通过一个对象获得完整的包名和类名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args) {

Javascript 数组去重的方法(四种)详解及实例代码_javascript技巧

 Javascript 数组去重的四种方法 四种算法来实现这个目的: 第一种方法: Array.prototype.unique1 = function () { var n = []; //一个新的临时数组 for (var i = 0; i < this.length; i++) //遍历当前数组 { //如果当前数组的第i已经保存进了临时数组,那么跳过, //否则把当前项push到临时数组里面 if (n.indexOf(this[i]) == -1) n.push(this[i]); }

JavaScript 身份证号有效验证详解及实例代码_javascript技巧

最近需要对身份证合法性进行验证,实名验证是不指望了,不过原来的验证规则太过简单,只是简单的验证了身份证长度,现在业务需要加强下身份证验证规则,网上找到了不少资料,不过都不合偶的心意,无奈只好直接写一个,代码还是用自己的舒服哈 JavaScript验证身份证号 <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%>

Canvas 制作动态进度加载水球详解及实例代码_javascript技巧

Canvas 动态进度加载水球 前言 之前看到一些球型的动态加载的效果,一直想自己动手做一个,正好这段时间重温了一个Canvas,所以就尝试了一下. 实现思路 关于水波的实现,使用了sin()函数,通过每一帧不断的移动sin()函数曲线,实现水波动态效果.然后,通过绘制圆形路径,进行clip(),实现球型效果. sin()函数相关 这里说一下sin()函数的相关基础,对于绘制水波的影响. 看一下图,回顾一下中学sin()函数的基础. 从图中可以看出,当函数为sin(x)时,值域为[-1, 1],

Android 消息机制详解及实例代码

Android 消息机制 1.概述 Android应用启动时,会默认有一个主线程(UI线程),在这个线程中会关联一个消息队列(MessageQueue),所有的操作都会被封装成消息队列然后交给主线程处理.为了保证主线程不会退出,会将消息队列的操作放在一个死循环中,程序就相当于一直执行死循环,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数(handlerMessage),执行完成一个消息后则继续循环,若消息队列为空,线程则会阻塞等待.因此不会退出.如下图所示: Handl

javascript replace()用法详解附实例代码_javascript技巧

replace()最简单的算是能力就是简单的字符替换.示例代码如下: [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 我想大家运行后可以看到结果,它只替换了首字母.但如果加上正则表达式结果就不一样了!呵呵,没错.replace()支持正则表达式,它可以按照正则表达式的规则匹配字符或字符串,然后给予替换! [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 呵呵,您一定发现了.这样还是只替换了第一个字母a.如果您熟悉正则,那这就难不住您.稍加修改就OK了. [Ctrl+A 全选

php mysql insert into 结合详解及实例代码_Mysql

php mysql insert into 结合详解 ySQL INSERT INTO语句在实际应用中是经常使用到的语句,所以对其相关的内容还是多多掌握为好. 向数据库表插入数据 INSERT INTO 语句用于向数据库表添加新记录. 语法 INSERT INTO table_name VALUES (value1, value2,....) 您还可以规定希望在其中插入数据的列: INSERT INTO table_name (column1, column2,...) VALUES (valu