Comparing version 1.0.3 to 1.0.4
@@ -0,1 +1,7 @@ | ||
## 2013.04.12, Version 1.0.4(Stable) | ||
### enhancement | ||
- ✔ 增加exclude、ignoreFiles功能支持,添加相应测试用例 | ||
## 2013.04.12, Version 1.0.3(Stable) | ||
@@ -2,0 +8,0 @@ |
@@ -20,3 +20,2 @@ /** | ||
this.modules = {}; | ||
// this.dependencyTree = {}; | ||
this.fileList = []; | ||
@@ -62,4 +61,8 @@ this.analyzedModules = []; | ||
}; | ||
// TODO | ||
Compiler.prototype._isFileIgnored = function(filePath){}; | ||
Compiler.prototype._isFileIgnored = function(filePath){ | ||
return utils.isExcluded(filePath, this.config.ignoreFiles); | ||
}; | ||
Compiler.prototype._isModuleExcluded = function(modName){ | ||
return utils.isExcluded(modName, this.config.exclude); | ||
}; | ||
Compiler.prototype._getModuleRealPathByParent = function(requiredModule, parentModule){ | ||
@@ -226,40 +229,43 @@ var self = this; | ||
modRealPath = self._getModuleRealPathByPkg(inputFilePath, modPkg); | ||
modName = self._moduleName(modRealPath, modPkg); | ||
// map module names if user configured map rules. | ||
modName = self._mapModuleName(modName); | ||
if(_.indexOf(self.fileList, modRealPath) === -1){ | ||
// to avoid recursive analyze. | ||
self.fileList.push(modRealPath); | ||
// get this file's dependencies. | ||
modRequires = dependencies(modRealPath); | ||
// if user named module himself, use his name. map rules will not work then. | ||
if(_.isPlainObject(modRequires) && modRequires.name){ | ||
modName = modRequires.name; | ||
modRequires = modRequires.deps; | ||
} | ||
// add this module to list. | ||
mod = { | ||
name: modName, | ||
pkg: modPkg, | ||
status: 'ok', | ||
path: modRealPath, | ||
requires: modRequires, | ||
dependencies: [], | ||
dependencyTree: {}, | ||
charset: modPkg.charset | ||
}; | ||
self.modules[modName] = mod; | ||
// analyze sub modules' dependencies recursively. | ||
_.forEach(modRequires, function(subModPath){ | ||
var subMod = self.analyze(self._getModuleRealPathByParent(subModPath, mod)); | ||
if(subMod){ | ||
mod.dependencies.push(subMod); | ||
mod.dependencyTree[subMod.name] = subMod.dependencyTree; | ||
if(!self._isFileIgnored(modRealPath)){ | ||
modName = self._moduleName(modRealPath, modPkg); | ||
// map module names if user configured map rules. | ||
modName = self._mapModuleName(modName); | ||
if(_.indexOf(self.fileList, modRealPath) === -1){ | ||
// to avoid recursive analyze. | ||
self.fileList.push(modRealPath); | ||
// get this file's dependencies. | ||
modRequires = dependencies(modRealPath); | ||
// if user named module himself, use his name. map rules will not work then. | ||
if(_.isPlainObject(modRequires) && modRequires.name){ | ||
modName = modRequires.name; | ||
modRequires = modRequires.deps; | ||
} | ||
}); | ||
var isModExcluded = self._isModuleExcluded(modName); | ||
// add this module to list. | ||
mod = { | ||
name: modName, | ||
pkg: modPkg, | ||
status: isModExcluded ? 'excluded' : 'ok', | ||
path: modRealPath, | ||
requires: modRequires, | ||
dependencies: [], | ||
dependencyTree: {}, | ||
charset: modPkg.charset | ||
}; | ||
self.modules[modName] = mod; | ||
self.analyzedModules.push(modName); | ||
}else{ | ||
mod = self.modules[modName]; | ||
// analyze sub modules' dependencies recursively. | ||
_.forEach(modRequires, function(subModPath){ | ||
var subMod = self.analyze(self._getModuleRealPathByParent(subModPath, mod)); | ||
if(subMod){ | ||
mod.dependencies.push(subMod); | ||
mod.dependencyTree[subMod.name] = subMod.dependencyTree; | ||
} | ||
}); | ||
!isModExcluded && self.analyzedModules.push(modName); | ||
}else{ | ||
mod = self.modules[modName]; | ||
} | ||
} | ||
@@ -266,0 +272,0 @@ break; |
@@ -94,3 +94,15 @@ var fs = require('fs'), | ||
return result.length ? "KISSY.config('modules', {" + os.EOL + " " + result.join(", " + os.EOL) + " " + os.EOL + "});" : ""; | ||
}, | ||
isExcluded: function(str, rules){ | ||
var isExcluded = false; | ||
if(str && _.isArray(rules)){ | ||
_.forEach(rules, function(rule){ | ||
if(new RegExp(rule).test(str)){ | ||
isExcluded = true; | ||
return true; | ||
} | ||
}); | ||
} | ||
return isExcluded; | ||
} | ||
}; |
{ | ||
"name":"kmc", | ||
"version":"1.0.3", | ||
"version":"1.0.4", | ||
"description":"KISSY Module Compiler", | ||
@@ -5,0 +5,0 @@ "author":"daxingplay <daxingplay@gmail.com>", |
112
README.md
@@ -9,6 +9,7 @@ # ModuleCompiler | ||
Module Compiler是一个基于NodeJS的KISSY模块打包工具,目前适用于KISSY 1.2+ | ||
KISSY Module Compiler(kmc)是一个基于NodeJS的KISSY模块打包工具,目前适用于KISSY 1.2+的代码打包 | ||
## 特点 | ||
- 支持GruntJS,参见[grunt-kmc](https://github.com/daxingplay/grunt-kmc). | ||
- 基于NodeJS,相比于KISSY自带的Java工具,打包快速 | ||
@@ -20,2 +21,3 @@ - 参照浏览器端的KISSY的config进行配置,无需额外知识,只需要改一下包路径即能快速打包 | ||
- 提供底层依赖分析接口,方便集成到其他工具当中 | ||
- 支持map功能,可以使用正则自由替换输出的模块名 | ||
@@ -25,3 +27,3 @@ ## 版本说明 | ||
- 0.0.7版本适用于KISSY 1.2、1.3的打包,目前已经在淘宝多个业务广泛使用,单纯打包没有任何问题,但是不具备依赖分析生成功能,此版本已经不再维护,推荐使用新版本。 | ||
- 1.0.0版本开始支持KISSY 1.3的自动combo功能 | ||
- 1.0.0版本开始支持KISSY 1.3的自动combo功能,推荐使用 | ||
@@ -41,60 +43,65 @@ ## 使用 | ||
var ModuleCompiler = require('module-compiler'); | ||
```js | ||
var ModuleCompiler = require('module-compiler'); | ||
// 这里和KISSY.config一样,先配置包 | ||
ModuleCompiler.config({ | ||
packages: [{ | ||
'name': 'sh', | ||
'path': '这里建议写绝对路径,即sh这个包所在的目录', | ||
'charset': 'gbk' | ||
}] | ||
}); | ||
// 这里和KISSY.config一样,先配置包 | ||
ModuleCompiler.config({ | ||
packages: [{ | ||
'name': 'sh', | ||
'path': '这里建议写绝对路径,即sh这个包所在的目录', | ||
'charset': 'gbk' | ||
}] | ||
}); | ||
// 将xxx.js打包为xxx.combine.js,输出编码为GBK | ||
ModuleCompiler.build('xxx.js', 'xxx.combine.js', 'gbk'); | ||
// 将xxx.js打包为xxx.combine.js,输出编码为GBK | ||
ModuleCompiler.build('xxx.js', 'xxx.combine.js', 'gbk'); | ||
// 用node执行你这个打包脚本就ok啦~ | ||
// 用node执行你这个打包脚本就ok啦~ | ||
``` | ||
### 高级使用指南 | ||
var ModuleCompiler = require('module-compiler'); | ||
```js | ||
var ModuleCompiler = require('module-compiler'); | ||
ModuleCompiler.config({ | ||
// 和KISSY一样,可以配置多个包 | ||
packages: [{ | ||
'name': 'app1', | ||
'path': 'app1这个包所在目录的绝对路径', | ||
// 这里是指app1这个包中的文件的编码,同一个包内的编码请保持一致 | ||
'charset': 'gbk' | ||
}, { | ||
'name': 'app2', | ||
'path': 'app2这个包所在目录的绝对路径', | ||
// 这里是指app2这个包源码的编码 | ||
'charset': 'utf-8' | ||
}], | ||
// 可以设置哪些模块不打包进来。注意,这里exclude的是具体的模块名,支持正则 | ||
exclude: ['base', 'event'], | ||
// 如果是对一个目录下的所有文件进行打包,可以设置哪些文件不打包进来,支持正则。注意和上面的exclude的配置的区别。 | ||
ignoreFiles: ['.combo.js', '-min.js'], | ||
// 输出的文件名后缀,不带.js,比如打包后你想输出为xxx.combine.js,那么这里就配置为:.combine | ||
suffix: '', | ||
// 类似于KISSY的map方法,可以自己定义把模块名中的路径进行替换 | ||
map: [ | ||
// 这样配置的话,那么,如果原先输出的app1的模块名中含有app1/2.0/字样的话,就会被替换成app1/19891014/ | ||
['app1/2.0/', 'app1/19891014/'] | ||
], | ||
// 这里设置的是最后打包出来的文件的编码,默认UTF-8,这里的设置相当于是全局设置,下面build中的设置是针对单一打包实例的 | ||
charset: 'gbk' | ||
}); | ||
ModuleCompiler.config({ | ||
// 和KISSY一样,可以配置多个包 | ||
packages: [{ | ||
'name': 'app1', | ||
'path': 'app1这个包所在目录的绝对路径', | ||
// 这里是指app1这个包中的文件的编码,同一个包内的编码请保持一致 | ||
'charset': 'gbk' | ||
}, { | ||
'name': 'app2', | ||
'path': 'app2这个包所在目录的绝对路径', | ||
// 这里是指app2这个包源码的编码 | ||
'charset': 'utf-8' | ||
}], | ||
// 可以设置哪些模块不打包进来。注意,这里exclude的是具体的模块名,支持正则 | ||
exclude: ['base', 'event'], | ||
// 如果是对一个目录下的所有文件进行打包,可以设置哪些文件不打包进来,支持正则。注意和上面的exclude的配置的区别。 | ||
ignoreFiles: ['.combo.js', '-min.js'], | ||
// 输出的文件名后缀,不带.js,比如打包后你想输出为xxx.combine.js,那么这里就配置为:.combine | ||
suffix: '', | ||
// 类似于KISSY的map方法,可以自己定义把模块名中的路径进行替换 | ||
map: [ | ||
// 这样配置的话,那么,如果原先输出的app1的模块名中含有app1/2.0/字样的话,就会被替换成app1/19891014/ | ||
['app1/2.0/', 'app1/19891014/'] | ||
], | ||
// 这里设置的是最后打包出来的文件的编码,默认UTF-8,这里的设置相当于是全局设置,下面build中的设置是针对单一打包实例的 | ||
charset: 'gbk' | ||
}); | ||
/** | ||
* 打包一个文件/目录 | ||
* @param inputPath {String} 源文件/目录的绝对路径. | ||
* @param outputPath {String} 打包出来的文件/目录的路径. | ||
* @param outputCharset {String} 输出编码,这里的设置会覆盖config.charset中的设置,默认UTF-8 | ||
* @return {Object} 打包出来的文件信息 | ||
*/ | ||
ModuleCompiler.build('xxx.js', 'xxx.combine.js', 'gbk'); | ||
/** | ||
* 打包一个文件/目录 | ||
* @param inputPath {String} 源文件/目录的绝对路径. | ||
* @param outputPath {String} 打包出来的文件/目录的路径. | ||
* @param outputCharset {String} 输出编码,这里的设置会覆盖config.charset中的设置,默认UTF-8 | ||
* @return {Object} 打包出来的文件信息 | ||
*/ | ||
ModuleCompiler.build('xxx.js', 'xxx.combine.js', 'gbk'); | ||
``` | ||
更详细的文档,请参见[wiki](https://github.com/daxingplay/ModuleCompiler/wiki)。 | ||
### API汇总 | ||
@@ -104,3 +111,4 @@ | ||
* ModuleCompiler.analyze(inputPath):只分析该文件依赖,不打包。 | ||
* ModuleCompiler.build(inputPath, outputPath, outputCharset):打包函数,具体见上面的说明 | ||
* ModuleCompiler.build(inputPath, outputPath, outputCharset, depFilePath):打包函数,具体见wiki | ||
* ModuleCompiler.combo(inputPath, depFilePath, depFileCharset): 不打包,只生成KISSY 1.3的自动combo依赖文件 | ||
* ModuleCompiler.clean(): 可以清空config中的设置。因为ModuleCompiler是单例运行,所以如果出现一些特别情况,可以在config前执行clean方法清空之前的配置。 | ||
@@ -107,0 +115,0 @@ |
@@ -333,62 +333,53 @@ /** | ||
//describe('When exclude', function(){ | ||
// | ||
// var result; | ||
// | ||
// var inputFile = path.resolve(srcPath, 'package1/two-package-simple.js'), | ||
// outputFile = path.resolve(distPath, 'package1/two-package-with-exclude.js'); | ||
// | ||
// before(function(){ | ||
// ModuleCompiler.config({ | ||
// packages: [{ | ||
// name: 'package1', | ||
// path: srcPath, | ||
// charset: 'gbk' | ||
// }, { | ||
// name: 'package2', | ||
// path: srcPath, | ||
// charset: 'utf-8' | ||
// }], | ||
// exclude: ['mod2'], | ||
// silent: true, | ||
// charset: 'gbk' | ||
// }); | ||
// result = ModuleCompiler.build(inputFile, outputFile); | ||
// }); | ||
// | ||
// after(function(){ | ||
// ModuleCompiler.clean(); | ||
// }); | ||
// | ||
// it('should have file generated.', function(){ | ||
// var exists = false; | ||
// if(fs.existsSync(outputFile)){ | ||
// exists = true; | ||
// } | ||
// exists.should.equal(true); | ||
// result.should.have.property('success', true); | ||
// result.should.have.property('files').with.lengthOf('1'); | ||
// }); | ||
// | ||
// it('should have proper main module.', function(){ | ||
// var file = result.files[0]; | ||
// file.name.should.equal('package1/two-package-simple'); | ||
// file.should.have.property('submods').with.lengthOf('4'); | ||
// file.should.have.property('combined').with.lengthOf('3'); | ||
// }); | ||
// | ||
// it('should have some excluded modules in submods', function(){ | ||
// var submods = result.files[0].submods; | ||
// submods[0].name.should.equal('package1/mods/mod1'); | ||
// submods[0].status.should.equal('ok'); | ||
// submods[1].name.should.equal('package1/mods/mod2'); | ||
// submods[1].status.should.equal('excluded'); | ||
// submods[2].name.should.equal('package2/mods/mod1'); | ||
// submods[2].status.should.equal('ok'); | ||
// submods[3].name.should.equal('package2/mods/mod2'); | ||
// submods[3].status.should.equal('excluded'); | ||
// }); | ||
// | ||
//}); | ||
describe('When exclude', function(){ | ||
var result; | ||
var inputFile = path.resolve(srcPath, 'package1/two-package-simple.js'), | ||
outputFile = path.resolve(distPath, 'package1/two-package-with-exclude.js'); | ||
before(function(){ | ||
ModuleCompiler.config({ | ||
packages: [{ | ||
name: 'package1', | ||
path: srcPath, | ||
charset: 'gbk' | ||
}, { | ||
name: 'package2', | ||
path: srcPath, | ||
charset: 'utf-8' | ||
}], | ||
exclude: ['mod2'], | ||
silent: true, | ||
charset: 'gbk' | ||
}); | ||
result = ModuleCompiler.build(inputFile, outputFile); | ||
}); | ||
after(function(){ | ||
ModuleCompiler.clean(); | ||
}); | ||
it('should have file generated.', function(){ | ||
var exists = false; | ||
if(fs.existsSync(outputFile)){ | ||
exists = true; | ||
} | ||
exists.should.equal(true); | ||
result.should.have.property('success', true); | ||
result.should.have.property('files').with.lengthOf('1'); | ||
}); | ||
it('should have proper main module.', function(){ | ||
var file = result.files[0]; | ||
file.should.have.property('name', 'package1/two-package-simple'); | ||
}); | ||
it('should have some excluded modules in submods', function(){ | ||
var file = result.files[0]; | ||
file.modules['package2/mods/mod2'].should.have.property('status', 'excluded'); | ||
}); | ||
}); | ||
describe('When specify a charset in config', function(){ | ||
@@ -395,0 +386,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
86345
2242
116