Skip to content

Instantly share code, notes, and snippets.

@shepherdwind
Created April 16, 2012 11:38
Show Gist options
  • Save shepherdwind/2397986 to your computer and use it in GitHub Desktop.
Save shepherdwind/2397986 to your computer and use it in GitHub Desktop.
kissy ui auto combine
(function(S){
var _use = S.use;
var _add = S.add;
var getMappedPath = S.__getMappedPath;
//url映射
var maps = {};
//依赖关系
var requires = {};
//记录加载过的模块
var _mods = {};
//允许被合并的包, *表示所有
var allowPackages = {'*': false, 'allPackageNumber': 0};
var kissyPath = S.Config.base;
/**
* 是否设置自动combine,是指方式通过S.Config.autoCombine来设置,
* @return {bool}
*/
function isAutoCombine(){
if (S.Config.autoCombine){
allowPackages['*'] = true;
return true;
} else {
allowPackages['*'] = false;
return false;
}
}
/**
* 是否允许combine
* @param packageVal {string} package名字
* @return {bool} 某个package是否允许被combine到一起
*/
function isAlowPackage(packageName){
return allowPackages['*'] || allowPackages[packageName];
}
/**
* 合并依赖关系, 把加载中的模块,找到他们所依赖的模块,然后合并到一起
* @param mods {array} 模块名,表示正在加载的模块
* @return {array} 模块数组,包括mods的所有模块,和他们所依赖的模块
*/
function mergeRequire(mods){
var ret = mods.concat();
S.each(mods, function(mod){
var requireArr = requires[mod];
if(requireArr && S.isArray(requireArr)){
ret = ret.concat(requireArr);
}
});
return ret;
}
/**
* 判断模块是否加载过
* @return {bool}
*/
function isLoaded(mod){
var mods = S.Env.mods;
return _mods[mod] || mod in mods;
}
/**
* 构建url映射
* @param mods {array} 模块名数组, 把mods中的所有模块合并成一个combine的url,
* 形如url??mod/a.js,mod/b.js,mod/c.js,构建的url映射贮存在maps变量中
*/
function buildPath(mods){
mods = mergeRequire(mods);
var pks = {};
var tags = {};
//默认为kissy package
pks[kissyPath] = [];
tags[kissyPath] = S.buildTime;
//获取所有的packages
var packages = S.Config.packages;
for (var i = 0; i < mods.length; i++) {
var mod = mods[i];
var modFind = false;
//是否加载过,如果加载过则不合并此模块
if (isLoaded(mod)) {
mods.splice(i, 1);
continue;
}
if (mod.indexOf('/') > 0) {
S.each(packages, function(packageVal, packageName){
//模块名以package名开头,为自定义package
if (mod.indexOf(packageName) === 0 && isAlowPackage(packageName)){
var path = packageVal.path;
pks[path] = pks[path] || [];
pks[path].push(mod);
if (packageVal.tag && !tags[packageName]){
tags[path] = packageVal.tag;
}
modFind = true;
}
});
}
if (isAlowPackage('*') && !modFind) pks[kissyPath].push(mod);
_mods[mod] = true;
}
S.each(pks, function(mods, path){
if (mods.length > 1){
var tag = tags[path] ? '?t=' + tags[path] : '';
var combine = path + '??' + mods.join('.js,') + '.js' + tag;
var combineMin = path + '??' + mods.join('-min.js,') + '-min.js' + tag;
S.each(mods, function(mod){
var fullpath = path + mod + '.js' + tag;
var fullpathMin = path + mod + '-min.js' + tag;
maps[fullpath] = combine;
maps[fullpathMin] = combineMin;
});
}
});
}
//重写use方法,捕获参数
S.use = function(modNames, callback, cfg){
//如果是自动combine或者存在某些包是需要自动combine
if (isAutoCombine() || allowPackages.allPackageNumber){
var _modNames = modNames.replace(/\s+/g, "").split(',');
buildPath(_modNames);
}
return _use.call(this, modNames, callback, cfg);
};
//重写add方法,捕获requires依赖关系
S.add = function(name, def, config){
if (isAutoCombine() || allowPackages.allPackageNumber){
if (config && config.requires){
if(config.requires.length > 1){
buildPath(config.requires);
}
}
}
return _add.call(this, name, def, config);
};
S.__getMappedPath = function(path){
return maps[path] || getMappedPath(path);
};
//合并指定包
function addPackage(pkg){
allowPackages[pkg] = true;
allowPackages.allPackageNumber++;
}
function removePackage(pkg){
delete allowPackages[pkg];
allowPackages.allPackageNumber--;
}
/**
* 增加依赖关系,对于通过requires来加载的模块,需要预定义依赖关系
* @param obj {object} {mod, [mod1, mod2]}表示mod依赖mod1和mod2,加载mod的时候,
* mod1和mod2会被自动combine到相对于的包中
*/
function addRequires(obj){
S.each(obj, function(val, key){
if (S.isArray(val)){
requires[key] = val;
}
});
}
S._Combo = S.Combo;
S.Combo = {
addPackage: addPackage,
removePackage: removePackage,
addRequires: addRequires
};
})(KISSY);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment