UNPKG

time-analytics-webpack-plugin

Version:
143 lines 6.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.analyzer = exports.WebpackMetaEventType = exports.PluginEventType = exports.TapType = exports.LoaderEventType = exports.LoaderType = exports.AnalyzeInfoKind = void 0; const ramda_1 = require("ramda"); const utils_1 = require("./utils"); const writer_1 = require("./writer"); var AnalyzeInfoKind; (function (AnalyzeInfoKind) { AnalyzeInfoKind[AnalyzeInfoKind["loader"] = 0] = "loader"; AnalyzeInfoKind[AnalyzeInfoKind["plugin"] = 1] = "plugin"; AnalyzeInfoKind[AnalyzeInfoKind["webpackMeta"] = 2] = "webpackMeta"; })(AnalyzeInfoKind = exports.AnalyzeInfoKind || (exports.AnalyzeInfoKind = {})); var LoaderType; (function (LoaderType) { LoaderType[LoaderType["pitch"] = 0] = "pitch"; LoaderType[LoaderType["normal"] = 1] = "normal"; })(LoaderType = exports.LoaderType || (exports.LoaderType = {})); var LoaderEventType; (function (LoaderEventType) { LoaderEventType[LoaderEventType["start"] = 0] = "start"; LoaderEventType[LoaderEventType["end"] = 1] = "end"; })(LoaderEventType = exports.LoaderEventType || (exports.LoaderEventType = {})); var TapType; (function (TapType) { TapType[TapType["normal"] = 0] = "normal"; TapType[TapType["async"] = 1] = "async"; TapType[TapType["promise"] = 2] = "promise"; })(TapType = exports.TapType || (exports.TapType = {})); var PluginEventType; (function (PluginEventType) { PluginEventType[PluginEventType["start"] = 0] = "start"; PluginEventType[PluginEventType["end"] = 1] = "end"; })(PluginEventType = exports.PluginEventType || (exports.PluginEventType = {})); /** * The exact one hook of webpack * * Name format is `${hooks container name}_${hook name}` */ var WebpackMetaEventType; (function (WebpackMetaEventType) { WebpackMetaEventType[WebpackMetaEventType["Compiler_compile"] = 0] = "Compiler_compile"; WebpackMetaEventType[WebpackMetaEventType["Compiler_done"] = 1] = "Compiler_done"; })(WebpackMetaEventType = exports.WebpackMetaEventType || (exports.WebpackMetaEventType = {})); class WebpackTimeAnalyzer { constructor() { this._isInitilized = false; this.loaderData = []; this.pluginData = []; this.metaData = []; } initilize() { (0, utils_1.assert)(this._isInitilized === false, '${PACKAGE_NAME} is initialized twice. This should be a bug if it is not intentional. Please submit an issue.'); this._isInitilized = true; } clear() { (0, utils_1.assert)(this._isInitilized === true, 'Time Analyzer must be initialized when clearing.'); this._isInitilized = false; this.loaderData = []; this.pluginData = []; this.metaData = []; } collectLoaderInfo(loaderInfo) { this.loaderData.push(loaderInfo); } collectPluginInfo(pluginInfo) { this.pluginData.push(pluginInfo); } collectWebpackInfo(metaInfo) { this.metaData.push(metaInfo); } output(option) { (0, utils_1.assert)(this._isInitilized === true, 'Time Analyzer must be initialized when outputing.'); const tmp1 = analyticsOutputMetaInfo(this.metaData); const tmp2 = analyticsPluginInfos(this.pluginData); const tmp3 = analyticsOutputLoaderInfos(this.loaderData, { ignoredLoaders: option.ignoredLoaders }); writer_1.Writer.writeResult(tmp1, tmp2, tmp3, option); this.clear(); } } function isArraySortBy(paths, arr) { let prevValue = 0; for (const item of arr) { const curValue = (0, ramda_1.path)(paths, item); (0, utils_1.assert)(typeof curValue === 'number'); if (curValue < prevValue) { return false; } prevValue = curValue; } return true; } function analyticsOutputMetaInfo(data) { // validate (0, utils_1.assert)(isArraySortBy(['time'], data), 'webpack meta event info should be sorted by time.'); const compilerCompileEvents = data.filter(info => info.hookType === WebpackMetaEventType.Compiler_compile); (0, utils_1.assert)(compilerCompileEvents.length === 1, 'webpack must start only once'); const compilerDoneEvents = data.filter(info => info.hookType === WebpackMetaEventType.Compiler_done); (0, utils_1.assert)(compilerDoneEvents.length === 1, 'webpack must done only once'); const compileTotalTime = compilerDoneEvents[0].time - compilerCompileEvents[0].time; return { totalTime: compileTotalTime, }; } function analyticsPluginInfos(data) { (0, utils_1.assert)(isArraySortBy(['time'], data), 'plugin event info should be sorted by time.'); const res = { pluginsInfo: [] }; const nameGrouppedPlugin = (0, ramda_1.groupBy)((0, ramda_1.prop)('pluginName'), data); Object.entries(nameGrouppedPlugin).forEach(([pluginName, dataA]) => { let currentPluginTotalTime = 0; const idGroupedPlugin = (0, ramda_1.groupBy)((0, ramda_1.prop)('tapCallId'), dataA); Object.entries(idGroupedPlugin).forEach(([tapCallId, dataB]) => { (0, utils_1.assert)(dataB.length === 2 && dataB[0].eventType === PluginEventType.start && dataB[1].eventType === PluginEventType.end, 'each tap execution should be collected info for start and end, once and only once.'); const tapTime = dataB[1].time - dataB[0].time; currentPluginTotalTime += tapTime; }); res.pluginsInfo.push({ name: pluginName, time: currentPluginTotalTime }); }); return res; } function analyticsOutputLoaderInfos(data, options) { (0, utils_1.assert)(isArraySortBy(['time'], data), 'loader event info should be sorted by time.'); const res = { loadersInfo: [] }; const nameGrouppedLoader = (0, ramda_1.groupBy)((0, ramda_1.prop)('loaderPath'), data); Object.entries(nameGrouppedLoader).forEach(([loaderPath, dataA]) => { let currentLoaderTotalTime = 0; if (!options.ignoredLoaders.some(ignoredLoader => loaderPath.includes(ignoredLoader))) { const idGroupedPlugin = (0, ramda_1.groupBy)((0, ramda_1.prop)('callId'), dataA); Object.entries(idGroupedPlugin).forEach(([callId, dataB]) => { (0, utils_1.assert)(dataB.length === 2 && dataB[0].eventType === LoaderEventType.start && dataB[1].eventType === LoaderEventType.end, `each laoder execution should be collected info for start and end, once and only once. But for ${loaderPath}, there is an error, why?`); const tapTime = dataB[1].time - dataB[0].time; currentLoaderTotalTime += tapTime; }); } res.loadersInfo.push({ path: loaderPath, time: currentLoaderTotalTime }); }); return res; } exports.analyzer = new WebpackTimeAnalyzer(); //# sourceMappingURL=analyzer.js.map