fd-gulp-jsconcat
Version:
concat js files according to those rules listed on this page(http://wd.alibaba-inc.com/doc/page/work/cbu-regulations/merge)
141 lines (116 loc) • 4.47 kB
JavaScript
;
var through = require('through2');
var fs = require('fs');
var path = require('path');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var async = require('async');
var request = require('request');
var iconv = require('iconv-lite');
var constants = require('./assets/constants');
var helper = require('./assets/helper');
module.exports = function(srcDir, opt) {
if (!opt) opt = {};
if (!srcDir) throw new PluginError(constants.PLUGIN_NAME, 'STYLE_BUILD_ERR: Missing srcDir option for ' + constants.PLUGIN_NAME);
var domain = helper.getDomain(opt), localCommonDir = opt.localCommonDir;
function transformFunc(file, encoding, transCallback) {
var that = this;
if (file.isNull()) return; // ignore
if (file.isStream()) return this.emit('error', new PluginError(constants.PLUGIN_NAME, 'STYLE_BUILD_ERR: Streaming not supported'));
parseCSSFile(file, function(fileContent) {
file.contents = iconv.encode(fileContent, 'GBK');
that.push(file);
transCallback();
});
}
function parseCSSFile(file, parseJSCallback) {
var decodedContent = iconv.decode(file.contents, 'GBK'),
originalContent = decodedContent, lines, singleLine,
importMatches, importFile, fileName,
fileMap = {}, FCTasks = [], fileContent = '';
// 如没有匹配到@import语句,可直接返回文件内容
// 如没有匹配到merge start/end语句,可直接返回文件内容
if (!constants.JS_MERGE_COMMENT_RE.test(originalContent)) {
parseJSCallback(originalContent);
return;
}
if (constants.COMPRESS_FLAG_RE.test(originalContent)) {
fileContent += '/*cmd:compress=true*/\n';
}
if (constants.COMPRESS_OPT.test(originalContent)) {
fileContent += '/*cmd:jsCompressOpt=[' + constants.COMPRESS_OPT.exec(originalContent)[1] + ']*/\n';
}
if (constants.CONV_TO_UNICODE_RE.test(originalContent)) {
fileContent += '/*cmd:conv2unicode=true*/\n';
}
lines = originalContent.split(constants.NEWLINE_RE);
for (var i=0,leni=lines.length; i<leni; i++) {
singleLine = lines[i];
importMatches = constants.JS_IMPORT_RE.exec(singleLine);
if (importMatches === null) {
// 匹配到compress=true标识,去掉感叹号,
// 以便之后的css minify过程能将这个注释去除
if (constants.COMPRESS_FLAG_RE.test(singleLine)) {
fileContent += '/*cmd:compress=true*/\n';
} else {
fileContent += singleLine + '\n';
}
} else if(singleLine.trim() !== '') {
fileName = helper.getFileName(srcDir, importMatches[2], file, domain, localCommonDir);
// 如果在fileMap中已有当前处理文件名的key值,
// 则说明当前文件在之前已有引入过。
if (fileMap[fileName]) {
continue;
}
fileMap[fileName] = {
localName: fileName,
url: importMatches[2]
}
FCTasks.push(async.apply(createGetFCFunc, fileMap[fileName]));
}
}
async.series(FCTasks, function(err, results) {
if (err) {
throw err;
}
fileContent += results.join('\n');
parseJSCallback(fileContent);
});
}
// 创建获取文件内容的异步task函数(async风格)
function createGetFCFunc(fileObj, callback) {
var content = '';
var localName = fileObj.localName;
if (fs.existsSync(localName)) {
var buffer = fs.readFileSync(localName);
content = iconv.decode(buffer, 'GBK');
callback(null, content);
} else {
getFileContentFromUrl(fileObj , function(err, results){
if(err) {
callback(err, 'failed');
}
content = results;
callback(null, content);
});
}
}
function getFileContentFromUrl( fileObj, cb ) {
var localName = fileObj.localName, url = fileObj.url;
if (url.indexOf(domain) !== -1) {
request({
url: url,
encoding: null
}, function(err, response, body) {
if (!err && response.statusCode == 200) {
cb(null, iconv.decode(body, 'GBK'));
} else {
cb(new PluginError(constants.PLUGIN_NAME, 'STYLE_BUILD_ERR: Failed to get ' + localName + '.\n'));
}
});
} else {
cb(new PluginError(constants.PLUGIN_NAME, 'STYLE_BUILD_ERR: Failed to get ' + localName + '.\n'));
}
}
return through.obj(transformFunc);
};