UNPKG

jspacker

Version:

支持commonjs类模块化开发项目的静态打包

131 lines (119 loc) 4.52 kB
/** * @date 12-12-12 * @describe: 简单实现 CommonJS 的 Modules/1.1.1 * * 定义模块 * math.js * define('math', function(require, exports, module) { * exports.add = function(a, b){ * return a+b; * } * }); * * 调用模块 * init.js * define('init',function(require, exports, module) { * console.log(require('math').add(1,2,)); * }); * @author: KnightWu * @version: 0.0.1 */ (function (window, undefined) { var STATUS = { "DEFINED": "The module is just DEFINED", "INITIALIZED": "The module is compiled and module.exports is available." }; if (window.define) { return; } function isFunction(obj) { return Object.prototype.toString.call(obj) === '[object Function]'; } var moduleCache = {}; //所有模块的集合 var parent; //记录当前运行模块 var entryModuleIdentifier = null; //初始化模块的名称 var scripts = document.getElementsByTagName('script'); //获取script节点 for (var i = 0, l = scripts.length; i < l && !entryModuleIdentifier; i++) { entryModuleIdentifier = scripts[i].getAttribute('data-mainentry'); //获取初始化模块的名称 即程序入口 } if (!entryModuleIdentifier) { //入口不存在则抛出异常 throw new Error('No data-mainentry attribute in script tag.'); } /** * require 的实现 * @param identifier * @return {*} */ function require(identifier) { if (!moduleCache[identifier]) { //不存在该模块,则抛出异常 throw new Error('Module ' + identifier + ' is not defined.'); } var foreign = moduleCache[identifier]; //否则,取出该模块 if (foreign.module.status !== STATUS.INITIALIZED) { //未初始化 initializeModule(identifier); //初始化该模块 } return foreign.module.exports; //返回模块的exports或其他 } /** * 初始化模块 * @param identifier 模块名 */ function initializeModule(identifier) { var current = moduleCache[identifier], //获取模块 module = current.module, exports = module.exports, factory = module.factory; module.parent = parent;//指向初始化时调用当前模块的模块。根据该属性,可以得到模块初始化时的 Call Stack. parent = current; if (isFunction(factory)) { //检测模块的工厂方法是否函数 var ret = factory( require, exports, //定义模块的exports module ); if (ret !== undefined) { module.exports = ret; } } else { //不是函数 直接返回factory 可以是对象 module.exports = moduleCache[identifier].factory; } module.status = STATUS.INITIALIZED; } /** * define ,用来定义模块 * @param identifier 模块名 * @param dependencies 依赖模块名 * @param factory 模块的实现 */ function define(identifier, dependencies, factory) { if (moduleCache[identifier]) { //存在相同名称,抛出错误 throw new Error('Module ' + identifier + ' has been defined already.'); } if (typeof factory === 'undefined') { factory = dependencies; } if (isFunction(factory) || factory === Object(factory)) { //factory不是函数或者对象,抛出异常 /** * * @type {{factory: *, module: {id: *, exports: {}}, uri: string, dependencies: Array, parent: {}, factory: *, status: null}} */ moduleCache[identifier] = { //模块的module属性,记录本模块的重要属性和方法 module: { id: identifier, exports: {}, uri: '', dependencies: [], parent: undefined, factory: factory, status: STATUS.DEFINED } }; if (identifier === entryModuleIdentifier) { //如果此模块名称和初始化名称相同,表明是入口函数,直接执行 initializeModule(identifier); } } else { throw new Error('factory of module ' + identifier + ' must be an object or a function.'); } } window.define = define; })(window);