JavaScript모듈 사양
모듈화는 일부 기존 프로그래밍 언어와 달리 기본 모듈화를 지원하지 않습니다.
Javascript 커뮤니티는 기존 운영 환경에서 "모듈" 효과를 얻기 위해 많은 노력을 기울여 왔습니다. 널리 사용되는 JavaScript 모듈 사양에는 CommonJS, AMD, UMD, CMD 등 두 가지 주요 유형이 있습니다.
CommonJS 사양은 서버 측 Javascript 모듈 사양입니다.
Node.js의 모듈 시스템은 CommonJS 사양을 참조하여 구현되었습니다. NPM도 commonJS에서 정의한 패키지 사양을 따르므로 완전한 생태계를 형성합니다.
CommonJS에서 정의한 모듈은 {모듈 참조(require)} {모듈 정의(내보내기)} {모듈 식별(모듈)}로 나뉩니다. require()는 외부 모듈을 소개하는 데 사용됩니다. 내보내기 개체는 현재 모듈의 메서드나 변수를 내보내는 데 사용됩니다. 유일한 내보내기 포트는 모듈 자체를 나타냅니다.
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"의 약자로 "Asynchronous Module Definition"을 뜻하며 프론트엔드 모듈 스펙입니다.
RequireJS는 AMD 사양을 구현합니다.
AMD 사양은 자유 변수 또는 전역 변수 정의 기능을 정의합니다.
define( id?, dependencies?, factory );
id는 모듈 ID를 나타내는 문자열 유형이며 선택적 매개변수입니다. 존재하지 않는 경우 모듈 ID는 로더에서 요청된 스크립트의 ID로 기본 설정되어야 합니다. 모듈 식별자가 있는 경우 최상위 식별자 또는 절대 식별자여야 합니다.
dependency는 현재 모듈이 의존하는 배열 리터럴이며 모듈에서 정의한 모듈로 식별됩니다.
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 모듈은 서버 측 우선 원칙을 기반으로 개발되어 모듈을 동기적으로 로드하도록 선택합니다. 해당 모듈에는 패키징이 필요하지 않지만 객체 유형(objects) 모듈만 지원합니다. AMD는 브라우저 우선 원칙에 따라 개발하고 모듈을 비동기식으로 로드하도록 선택합니다. 해당 모듈은 객체, 함수, 생성자, 문자열, 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가 지원되는지(정의가 존재하는지) 확인하고, 존재한다면 AMD 방식을 사용하여 모듈을 로드합니다. 그런 다음 Node.js 모듈 형식이 지원되는지 확인합니다(내보내기가 존재하는지 여부). Node.js 모듈 형식을 사용합니다. 처음 두 개가 존재하지 않으면 모듈은 세계(창 또는 전역)에 노출됩니다.
( 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. 微信开发之微信支付
위 내용은 WeChat 개발의 모듈화 세부 사례의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!