JavaScript模組規格
在任何一個大型應用程式中模組化是很常見的,與一些更傳統的程式語言不同的是,JavaScript (ECMA-262版本)還不支援原生的模組化。
Javascript社群做了很多努力,在現有的運作環境中,實現"模組"的效果。通行的JavaScript模組規格主要有兩種:CommonJS、AMD、UMD、CMD等
CommonJS規格是伺服器端Javascript模組規格。
Node.js的模組系統,就是參考CommonJS規格實現的。 NPM也遵循了commonJS定義的包規範,從而形成了一套完整的生態系統。
CommonJS定義的模組分為:{模組引用(require)} {模組定義(exports)} {模組識別(module)}。 require()用來引入外部模組;exports物件用於導出當前模組的方法或變量,唯一的導出口;module物件代表模組本身。
CommonJS規格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是"Asynchronous Module Definition"的縮寫,意思是"非同步模組定義",是前端模組規範。
RequireJS就是實作了AMD規範的呢。
AMD規格定義了一個自由變數或全域變數 define 的函數。
define( id?, dependencies?, factory );
id 為字串類型,表示了模組標識,為可選參數。若不存在則模組標識應該預設定義為在載入器中被請求腳本的標識。如果存在,那麼模組標識必須為頂層的或一個絕對的標識。
dependencies ,是一個目前模組依賴的,已被模組定義的模組標識的陣列字面量。
factory,是一個需要進行實例化的函數或一個物件。
AMD規格 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 ) ); } }); });
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 即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; })
微信小程序秉承了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 segmentfault.com/a/11...
微信小程序使用Underscore.js segmentfault.com/a/11...
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);
微信小程序还没实现ECMAScript 6。
【相关推荐】
1. 微信公众号平台源码下载
3. 微信开发之微信支付
以上是微信開發實戰之模組化的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!