diff options
Diffstat (limited to 'node_modules/time-require/src/timeRequire.js')
-rw-r--r-- | node_modules/time-require/src/timeRequire.js | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/node_modules/time-require/src/timeRequire.js b/node_modules/time-require/src/timeRequire.js new file mode 100644 index 000000000..0ba556fab --- /dev/null +++ b/node_modules/time-require/src/timeRequire.js @@ -0,0 +1,140 @@ +/** + * timeRequire - measure the time to load all the subsequnt modules by hoocking require() calls + * + * @author Ciprian Popa (cyparu) + * @since 0.0.1 + * @version 0.0.1 + */ + +"use strict"; + +var // setup vars + requireData = [], + write = process.stdout.write.bind(process.stdout), + relative = require("path").relative, + cwd = process.cwd(), + // require hooker should be first module loaded so all the other requires should count as well + /* jshint -W003 */ + hook = require("./requireHook")(_hooker), + table = require("text-table"), + dateTime = require("date-time"), + prettyMs = require("pretty-ms"), + chalk = require("chalk"), + // extra locals + DEFAULT_COLUMNS = 80, + BAR_CHAR = process.platform === "win32" ? "■" : "▇", + sorted = hasArg("--sorted") || hasArg("--s"), + treshold = (hasArg("--verbose") || hasArg("--V")) ? 0.0: 0.01, // TODO - configure treshold using CLI ? + EXTRA_COLUMNS = sorted ? 24 : 20; + +function hasArg(arg) { + return process.argv.indexOf(arg) !== -1; +} + +function pad(count, seq) { + return (count > 1) ? new Array(count).join(seq) : ""; +} + +function log(str) { + write(str + "\n", "utf8"); +} + +/** + * Callback/listener used by requireHook hook to collect all the modules in their loading order + */ +function _hooker(data) { + var filename = relative(cwd, data.filename); + // use the shortest name + if (filename.length > data.filename) { + filename = data.filename; + } + requireData.push({ + order: requireData.length, // loading order + time: data.startedIn, // time + label: data.name + " (" + filename + ")" +// name: data.name, +// filename: filename + }); +} + +function formatTable(tableData, totalTime) { + var NAME_FILE_REX = /(.+)( \(.+\))/, + maxColumns = process.stdout.columns || DEFAULT_COLUMNS, + validCount = 0, + longestRequire = tableData.reduce(function(acc, data) { + var avg = data.time / totalTime; + if (avg < treshold) { + return acc; + } + validCount++; + return Math.max(acc, data.label.length); + }, 0), + maxBarWidth = (longestRequire > maxColumns / 2) ? ((maxColumns - EXTRA_COLUMNS) / 2) : (maxColumns - (longestRequire + EXTRA_COLUMNS)), + processedTableData = [], + counter, maxOrderChars; + + function shorten(name) { + var nameLength = name.length, + partLength, start, end; + if (name.length < maxBarWidth) { + return name; + } + partLength = Math.floor((maxBarWidth - 3) / 2); + start = name.substr(0, partLength + 1); + end = name.substr(nameLength - partLength); + return start.trim() + "..." + end.trim(); + } + + function createBar(percentage) { + var rounded = Math.round(percentage * 100); + return ((rounded === 0) ? "0" : (pad(Math.ceil(maxBarWidth * percentage) + 1, BAR_CHAR) + " " + rounded)) + "%"; + } + + // sort the data if needed + if (sorted) { + tableData.sort(function(e1, e2) { + return e2.time - e1.time; + }); + } + // initialize the counter + counter = 1; + // get num ber of chars for padding + maxOrderChars = tableData.length.toString().length; + // push the header + processedTableData.push(["#" + (sorted ? " [order]" : ""), "module", "time", "%"]); + tableData.forEach(function(data) { + var avg = data.time / totalTime, + counterLabel, label, match; + // slect just data over the threshold + if (avg >= treshold) { + counterLabel = counter++; + // for sorted collumns show the order loading with padding + if (sorted) { + counterLabel += pad(maxOrderChars - data.order.toString().length + 1, " ") + " [" + data.order + "]"; + } + label = shorten(data.label); + match = label.match(NAME_FILE_REX); + if (match) { + label = chalk.green(match[1]) + match[2]; + } + processedTableData.push([counterLabel, label, chalk.yellow(prettyMs(data.time)), chalk.blue(createBar(avg))]); + } + }); + + return table(processedTableData, { + align: ["r", "l", "r", "l"], + stringLength: function(str) { + return chalk.stripColor(str).length; + } + }); +} + +// hook process exit to display the report at the end +process.once("exit", function() { + var startTime = hook.hookedAt, + totalTime = Date.now() - startTime.getTime(); + log("\n\n" + chalk.underline("Start time: " + chalk.yellow("(" + dateTime(startTime) + ")") + " [treshold=" + (treshold * 100) + "%" + (sorted ? ",sorted" : "") + "]")); + log(formatTable(requireData, totalTime)); + log(chalk.bold.blue("Total require(): ") + chalk.yellow(requireData.length)); + log(chalk.bold.blue("Total time: ") + chalk.yellow(prettyMs(totalTime))); +}); |