资讯专栏INFORMATION COLUMN

微信小程序开发实战——模块化

CoffeX / 2864人阅读

摘要:以微信小程序调试时代码为例兼容兼容微信小程序运行的代码与模块规范基本符合。使用第三方模块微信小程序运行环境没有定义,无法通过导入模块,需要对第三方模块强制导出后才能正常导入。

JavaScript模块规范

在任何一个大型应用中模块化是很常见的,与一些更传统的编程语言不同的是,JavaScript (ECMA-262版本)还不支持原生的模块化。

Javascript社区做了很多努力,在现有的运行环境中,实现"模块"的效果。通行的JavaScript模块规范主要有两种:CommonJS、AMD、UMD、CMD等

CommonJS

CommonJS规范是服务器端Javascript模块规范。

Node.js的模块系统,就是参照CommonJS规范实现的。NPM也遵循了commonJS定义的包规范,从而形成了一套完整的生态系统。

CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}。require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。

CommonJS规范 http://wiki.commonjs.org/wiki...

function MathClass() {
}
MathClass.PI = 3.14;
MathClass.E = 2.72;
MathClass.prototype.add = function(a, b) {
    return a+b;
};
module.exports = MathClass;
var MathClass = require("./mathCommonJS.js");
Page( {
    onLoad: function() {
        console.log( "PI: " +MathClass.PI );
        var mathClass = new MathClass();
        console.log( "3 + 4: " +mathClass.add(3, 4) );
    }
});
AMD

AMD是"Asynchronous Module Definition"的缩写,意思是"异步模块定义",是前端模块规范。

RequireJS就是实现了AMD规范的呢。

AMD规范定义了一个自由变量或者说是全局变量 define 的函数。

define( id?, dependencies?, factory ); 

id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层的或者一个绝对的标识。

dependencies ,是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。

factory,是一个需要进行实例化的函数或者一个对象。

AMD规范 https://github.com/amdjs/amdj...

define("mathAMD", [], function( i ) {
    function MathClass() {
    }
    MathClass.PI = 3.14;
    MathClass.E = 2.72;
    MathClass.prototype.add = function( a, b ) {
        return a + b;
    };
    return MathClass;
});
define( [ "mathAMD" ], function( require, exports, MathClass ) {
    Page( {
        onLoad: function() {
            console.log( "PI: " + MathClass.PI );
            var mathClass = new MathClass();
            console.log( "3 + 4: " + mathClass.add( 3, 4 ) );
        }
    });

});
UMD

CommonJS module以服务器端为第一的原则发展,选择同步加载模块。它的模块是无需包装的,但它仅支持对象类型(objects)模块。AMD以浏览器为第一(browser-first)的原则发展,选择异步加载模块。它的模块支持对象、函数、构造器、字符串、JSON等各种类型的模块,因此在浏览器中它非常灵活。这迫使人们想出另一种更通用格式 UMD(Universal Module Definition),希望提供一个前后端跨平台的解决方案。

(function (root, factory) {
    if (typeof define === "function" && define.amd) {       
        define(["jquery"], factory);
    } else if (typeof exports === "object") {      
        module.exports = factory(require("jquery"));
    } else {       
        root.returnExports = factory(root.jQuery);
    }
}(this, function ($) {    
    function myFunc(){};    
    return myFunc;
}));

UMD的实现很简单,先判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。再判断是否支持Node.js模块格式(exports是否存在),存在则使用Node.js模块格式。前两个都不存在,则将模块公开到全局(window或global)。

( function( global, factory ) {    
    if( typeof define === "function" && define.amd ) {
        define( factory );
    } else if( typeof exports === "object" ) {
        module.exports = factory();
    } else {
        root.returnExports = factory();
    }
    
} ( this, function() {
    function MathClass() {
    }
    MathClass.PI = 3.14;
    MathClass.E = 2.72;
    MathClass.prototype.add = function( a, b ) {
        return a + b;
    };
    return MathClass;
}) );
var MathClass = require( "./mathUMD.js" );
Page( {
    onLoad: function() {
        console.log( "PI: " + MathClass.PI );
        var mathClass = new MathClass();
        console.log( "3 + 4: " + mathClass.add( 3, 4 ) );
    }
});
CMD

CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个requireJS,CMD有个浏览器的实现SeaJS,SeaJS要解 决的问题和requireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同。

Sea.js 推崇一个模块一个文件,遵循统一的写法

define(id?, deps?, factory) 

因为CMD推崇一个文件一个模块,所以经常就用文件名作为模块id,CMD推崇依赖就近,所以一般不在define的参数中写依赖,在factory中写。

factory是一个函数,有三个参数,function(require, exports, module)

require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口

exports 是一个对象,用来向外提供模块接口

module 是一个对象,上面存储了与当前模块相关联的一些属性和方法

CMD模块规范 https://github.com/cmdjs/spec...

define( "pages/module/mathCMD.js", function( require, exports, module ) {
    function MathClass() {
    }
    MathClass.PI = 3.14;
    MathClass.E = 2.72;
    MathClass.prototype.add = function( a, b ) {
        return a + b;
    };
    module.exports = MathClass;
})
define( "pages/module/mathCMD.js", function( require, exports, module ) {
    function MathClass() {
    }
    MathClass.PI = 3.14;
    MathClass.E = 2.72;
    MathClass.prototype.add = function( a, b ) {
        return a + b;
    };
    module.exports = MathClass;
})
ECMAScript 6模块系统

ECMAScript 6,模块被作为重要组成部分加入其中。

ES6的模块提供了2个新的语法,分别是export和import。

export 模块导出

export let a = 1;
export class A {};
export let b = () => {};

import 模块导入

import {a} from "./a";
console.log(a);

import * as obj from "./a";
console.log(obj.a);  
微信小程序模块化机制

微信小程序秉承了JavaScript模块化的机制,通过module.exports暴露对象,通过require来获取对象。

模块开发

以微信小程序QuickStart为例,微信小程序模块采用CommonJS规范

utils/util.js

function formatTime(date) {
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()

  var hour = date.getHours()
  var minute = date.getMinutes()
  var second = date.getSeconds();


  return [year, month, day].map(formatNumber).join("/") + " " + [hour, minute, second].map(formatNumber).join(":")
}

function formatNumber(n) {
  n = n.toString()
  return n[1] ? n : "0" + n
}

module.exports = {
  formatTime: formatTime
}

pages/log/log.js

var util = require("../../utils/util.js")
Page({
  data: {
    logs: []
  },
  onLoad: function () {
    this.setData({
      logs: (wx.getStorageSync("logs") || []).map(function (log) {
        return util.formatTime(new Date(log))
      })
    })
  }
})
模块运行

微信小程序还是要以前端程序方式在微信浏览器中运行,由于CommonJS规范是服务器端模块规范,微信小程序运行时会自动转换为前端模块规范。

以微信小程序QuickStart调试时代码为例

utils/util.js

define("utils/util.js", function(require, module) {
    var window = {
        Math: Math
    }/*兼容babel*/
    , location, document, navigator, self, localStorage, history, Caches;
    function formatTime(date) {
        var year = date.getFullYear()
        var month = date.getMonth() + 1
        var day = date.getDate()
        var hour = date.getHours()
        var minute = date.getMinutes()
        var second = date.getSeconds();
        return [year, month, day].map(formatNumber).join("/") + " " + [hour, minute, second].map(formatNumber).join(":")
    }
    function formatNumber(n) {
        n = n.toString()
        return n[1] ? n : "0" + n
    }
    module.exports = {
        formatTime: formatTime
    }
})

pages/log/log.js

define("pages/logs/logs.js", function(require, module) {
    var window = {
        Math: Math
    }/*兼容babel*/
    , location, document, navigator, self, localStorage, history, Caches;
    var util = require("../../utils/util.js")
    Page({
        data: {
            logs: []
        },
        onLoad: function() {
            this.setData({
                logs: (wx.getStorageSync("logs") || []).map(function(log) {
                    return util.formatTime(new Date(log))
                })
            })
        }
    })
});
require("pages/logs/logs.js")

微信小程序运行的代码与CMD模块规范基本符合。

使用第三方模块

微信小程序运行环境exports、module没有定义,无法通过require导入模块,需要对第三方模块强制导出后才能正常导入。

微信小程序使用Immutable.js https://segmentfault.com/a/11...
微信小程序使用Underscore.js https://segmentfault.com/a/11...

其他

完整代码 https://github.com/guyoung/Gy...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80523.html

相关文章

  • 微信小程开发实战——使用Immutable.js

    摘要:是开发的不可变数据集合。微信小程序无法直接使用进行调用需要对下载的代码进行修改才能使用。原因分析使用了模块化规范的实现很简单,先判断是否支持模块规范,存在则使用方式加载模块。通过测试,微信小程序运行环境并没有定义。 Immutable 是 Facebook 开发的不可变数据集合。不可变数据一旦创建就不能被修改,是的应用开发更简单,允许使用函数式编程技术,比如惰性评估。Immutable...

    邱勇 评论0 收藏0
  • 微信小程开发实战——微信小程开发者工具0.10.101100

    摘要:微信小程序开发者工具发布最新版本,增加了控件,模块化中可使用对外暴露接口,模块化中可不写后缀等。 微信小程序开发者工具发布最新版本0.10.101100,增加了video控件,模块化中可使用 exports 对外暴露接口,模块化中 require 可不写 .js 后缀等。 更新日志 基础功能 A 增加 Android 添加了默认的控件 A 增加 模块化中可使用 exports 对外...

    JohnLui 评论0 收藏0
  • 微信小程开发实战——使用Underscore.js

    摘要:是一个工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何内置对象。微信小程序无法直接使用进行调用。通过测试,微信小程序运行环境并没有定义获取应用实例解决方法修改代码,注释原有模块导出语句,使用强制导出使用获取应用实例其他完整代码 Underscore.js 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对...

    Bowman_han 评论0 收藏0
  • 微信小程开发实战——使用UUID、Base64、Chance等

    摘要:微信是一个基于的随机数工具类。可以生成随机数字,名称,地址,域名,邮箱,时间等等,几乎网站中使用的任何形式的内容都能够生成。这个随机数工具可以帮助减少单调的测试数据编写工作,特别是编写自动化测试的时候。 UUID node-uuid模块,可以快速地生成符合 RFC4122 规范 version 1 或者 version 4 的 UUID。 var uuid = require(../....

    zhaot 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<