nyx_server
Version:
Node内容发布
152 lines (131 loc) • 5.89 kB
JavaScript
/* global process */
var path = require('path');
var fs = require("fs");
var Optimist = require("../optimist/optimist");
var help = require("../optimist/help");
var log4js = require("log4js");
var glob = require("glob");
var BuildCommand = require("./lib/build");
var utils = require("./lib/build/utils");
var log = log4js.getLogger("nyx build");
var fstream = require("fstream");
var rimraf = require("rimraf");
var mkdirp = require("mkdirp");
var ResFetch = require("./lib/resfetch");
var copy = require("../core/utils/copy");
var config = require("../config/default-config");
var Promise = require("bluebird");
var optimist = new Optimist();
optimist
.info('build项目,完成项目打包、合并、替换资源等相关过程')
.usage('nyx build [--target subproject]')
.define('target').describe('指定需要build的目录,可以不填,默认build所有子项目')
var argv = optimist.getArgv();
var cleanFlag = function(content){
return content.replace(/[\r|\n|\s]*<!--\s*((end)?build|(end)?bower)[^>]*-->/gi , '');
}
var Build = function(){}
Build.prototype.execute = function(){
var argvAnalysis = optimist.analysis;
if (argvAnalysis.options.hasOwnProperty('help') || argvAnalysis.shortKeys.hasOwnProperty('h')) {
help.detailed(optimist);
process.exit(1);
}
var targetDir = argv.target || "*"; //如果没有目标目录,查询所有目录下的子项目
return this.execute1(targetDir);
}
Build.prototype.execute1 = function(targetDir){
var templateConfigPath = path.join(process.cwd() , targetDir , "package.json");
return new Promise(function(resolve , reject){
glob(templateConfigPath , function(err , files){
if(err){
log.error("路径匹配错误 , 模板配置路径 : "+templateConfigPath);
throw new Error(err)
}
log.debug('match files : '+files);
var allPromise = [];
files.forEach(function(filePath){
var packageInfo = require(filePath);
var templateFile = packageInfo.template;
var baseDir = path.dirname(filePath);
log.info("构建模板开始,模板名称 :"+packageInfo.name);
var p = buildTemplate(templateFile , baseDir).then(function(){
log.info("构建模板结束,模板名称 :"+packageInfo.name);
});
allPromise.push(p);
});
resolve(Promise.all(allPromise));
});
})
}
Build.prototype.showhelp = function(){
help.detailed(optimist);
};
Build.prototype.optimist = function() {
return optimist;
}
module.exports = new Build();
/**
* 删除目录
*/
function clean(dirpath){
rimraf.sync(dirpath);
}
function buildTemplate(filePath , baseDir){
var distDir = path.join(baseDir , config.DIST_DIR);
var fetchtemp = path.join(baseDir , ".fetchTemp");
var templateFile = path.join(baseDir , filePath);
return new Promise(function(resolve , reject){
fs.exists(templateFile , function(exists){
if(exists){
//1、清除build目录
clean(distDir);
mkdirp.sync(distDir);
//2、抽取资源到临时目录
new ResFetch({'filePaths':[templateFile] , 'distPath':fetchtemp});
//3、copy资源到build目录
var p = copy.copyDir(fetchtemp, distDir , {/*ignore:[".ignore", ".gitignore"]*/}).then(function(){
//4、build资源
var options = {'distPath' : distDir , 'appDir':fetchtemp};
var tempTemplate = path.join(distDir , filePath);
var blockFile = new BuildCommand.BlockFile(tempTemplate , options);
blockFile.blocks.forEach(function(block){
var Blockprocessor = BuildCommand.getBlockProcessor(block.blockType); //得到当前块的处理器
(new Blockprocessor()).processRun(block , options);
})
var htmlContent = blockFile.content;
blockFile.blocks.forEach(function(block){
var replaceBlock = block.blockOuterContent;
var changedBlock = block.changedContent;
var blockType = block.blockType; //块类型、js/css/requirejs
var deviceType = block.blockDevice; //设备类型
if(typeof changedBlock === 'undefined'){
changedBlock = replaceBlock;
}
htmlContent = htmlContent.replace(replaceBlock , utils.wrapScript(changedBlock , blockType , deviceType));
});
var distPath = options.distPath; //目标发布的地址
var distFileName = path.join(distPath , path.basename(templateFile));
return new Promise(function(resolve , reject){
try{
htmlContent = cleanFlag(htmlContent);
fs.writeFile(distFileName , htmlContent , function(err){
if(err){
reject(err);
}else{
resolve(true);
}
})
}catch(error){
reject(error);
}
});
}).then(function(){
clean(fetchtemp);
return true;
});
resolve(p);
}
})
})
}