grunt-yyfrontmonitor-util
Version:
167 lines (110 loc) • 4.87 kB
JavaScript
/*
* grunt-yyfrontMonitor-util
* https://github.com/qbright/grunt-yyfrontMonitor-util
*
* Copyright (c) 2015 zqbright
* Licensed under the MIT license.
*/
;
var path = require('path'),
fs = require('fs'),
cheerio = require('cheerio'),
http = require("http"),
async = require("async");
var loadFunMap = {
"onerror": "__FEQUALITY__.lostCallBack(this)"
};
var baseClass = "__fequality__base",
emptyClass = "__fequality_empty",
loadClass = "__fequality_load",
loadId = "__FEQUALITY__QID";
var loadScriptSrc = "http://szhuodong.duowan.com/s/rp/fequality/yy-loadScript.min.js";
var baseTpl = '<script class="' + baseClass + '">\n window.__FEQUALITY__ = {}; \n window.__FEQUALITY__.errorQueue = [];\n window.__FEQUALITY__.lostSrcQueue = [];\n window.__FEQUALITY__.lostCallBack = function(el){\n el.onerror = null; \n window.__FEQUALITY__.lostSrcQueue.push(el.src);\n }\n window.onerror = function(){\n window.__FEQUALITY__.errorQueue.push(arguments);\n return "yyF2E_ErrorRerport";\n }\n \n</script>',
emptyTime = '<script class="' + emptyClass + '">\n !window.__FEQUALITY__ &&( window.__FEQUALITY__ = {});\n window.__FEQUALITY__.yy_reportEmptyTimeEnd = new Date().getTime();\n</script>';
module.exports = function (grunt) {
// Please see the Grunt documentation for more information regarding task
// creation: http://gruntjs.com/creating-tasks
var processFile = function (f, dest, options, $, loadScript) {
grunt.log.subhead('Processing ' + f.cyan);
var srcDestMap = grunt.file.expandMapping(f, dest)[0];
initDoc($, loadScript, options);
if (options.lostSrcReport) {
lostSrcReport($);
}
var updatedContents = $.html();
grunt.file.write(srcDestMap.dest, updatedContents);
grunt.log.writeln("File " + (srcDestMap.dest).cyan + " created/updated");
};
function initDoc($, loadScript, options) {
$("." + baseClass).remove();
$("." + emptyClass).remove();
$("." + loadClass).remove();
var headTag = $("head"),
firstScriptTag = headTag.find("script").first(),
bodyTag = $("body"),
loadScriptTag = "\n<script id='" + loadId + "' qid=" + options.qid + " class='" + loadClass + "'>\n\n" + loadScript + "\n\n</script>\n";
if (firstScriptTag.length) {
firstScriptTag.before(baseTpl);
} else {
headTag.append(baseTpl);
}
headTag.append(emptyTime);
bodyTag.append(loadScriptTag);
}
function lostSrcReport($) {
var $scriptTagSet = $("script");
if ($scriptTagSet.length) {
$scriptTagSet.each(function (index, item) {
var $t = $(item);
if ($t.attr("src")) {
$t.attr(loadFunMap);
}
});
}
}
grunt.registerMultiTask('yyFrontMonitor_util', 'yy前端监控系统 页面组件', function () {
// Merge task-specific and/or target-specific options with these defaults.
var done = this.async();
var options = this.options({}),
destDir = this.data.destDir;
if (options.qid === null || options.qid === void 0) {
grunt.log.error("you must spectified with the qid");
done(false);
return false;
}
async.series([function (cb) {
http.get(loadScriptSrc, function (res) {
var size = 0;
var chunks = [];
res.on('data', function (chunk) {
size += chunk.length;
chunks.push(chunk);
});
res.on('end', function () {
var data = Buffer.concat(chunks, size);
cb(null, data.toString());
});
});
}], function (err, results) {
var loadScript = results[0];
if (!this.filesSrc.length || !this.data.destDir) {
grunt.log.error("you must specified with src files and the destDir ");
done(false);
return false;
}
this.filesSrc.filter(function (f) {
if (!grunt.file.exists(f)) {
grunt.log.warn("Source file " + f + " not found");
return false;
} else {
return true;
}
}).forEach(function (f) {
var srcContents = grunt.file.read(f);
var $ = cheerio.load(srcContents, {lowerCaseAttributeNames: false});
processFile(f, destDir, options, $, loadScript);
}.bind(this));
done();
}.bind(this));
});
};