UNPKG

webpack-bundle-analyzer

Version:

Webpack plugin and CLI utility that represents bundle content as convenient interactive zoomable treemap

96 lines (91 loc) 2.4 kB
"use strict"; const { createWriteStream } = require("node:fs"); const { Readable } = require("node:stream"); const { pipeline } = require("node:stream/promises"); /** @typedef {import("./BundleAnalyzerPlugin").EXPECTED_ANY} EXPECTED_ANY */ /** @typedef {import("webpack").StatsCompilation} StatsCompilation */ class StatsSerializeStream extends Readable { /** * @param {StatsCompilation} stats stats */ constructor(stats) { super(); this._indentLevel = 0; this._stringifier = this._stringify(stats); } get _indent() { return " ".repeat(this._indentLevel); } _read() { let readMore = true; while (readMore) { const { value, done } = this._stringifier.next(); if (done) { this.push(null); readMore = false; } else { readMore = this.push(value); } } } /** * @param {EXPECTED_ANY} obj obj * @returns {Generator<string, undefined, unknown>} stringified result * @private */ *_stringify(obj) { if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean" || obj === null) { yield JSON.stringify(obj); } else if (Array.isArray(obj)) { yield "["; this._indentLevel++; let isFirst = true; for (let item of obj) { if (item === undefined) { item = null; } yield `${isFirst ? "" : ","}\n${this._indent}`; yield* this._stringify(item); isFirst = false; } this._indentLevel--; yield obj.length ? `\n${this._indent}]` : "]"; } else { yield "{"; this._indentLevel++; let isFirst = true; const entries = Object.entries(obj); for (const [itemKey, itemValue] of entries) { if (itemValue === undefined) { continue; } yield `${isFirst ? "" : ","}\n${this._indent}${JSON.stringify(itemKey)}: `; yield* this._stringify(itemValue); isFirst = false; } this._indentLevel--; yield entries.length ? `\n${this._indent}}` : "}"; } } } /** * @param {StatsCompilation} stats stats * @param {string} filepath filepath file path * @returns {Promise<void>} */ async function writeStats(stats, filepath) { await pipeline(new StatsSerializeStream(stats), createWriteStream(filepath)); } module.exports = { StatsSerializeStream, writeStats };