Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._

## UNRELEASED

* **Bug Fix**
* Fix a race condition in `writeStats` that could lead to incorrect content in `stats.json` ([#711](https://github.com/webpack/webpack-bundle-analyzer/pull/711) by [@colinaaa](https://github.com/colinaaa))

## 5.2.0

* **New Feature**
Expand Down
8 changes: 2 additions & 6 deletions src/statsUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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 */
Expand Down Expand Up @@ -91,12 +92,7 @@ class StatsSerializeStream extends Readable {
* @returns {Promise<void>}
*/
async function writeStats(stats, filepath) {
return new Promise((resolve, reject) => {
new StatsSerializeStream(stats)
.on("end", resolve)
.on("error", reject)
.pipe(createWriteStream(filepath));
});
await pipeline(new StatsSerializeStream(stats), createWriteStream(filepath));
}

module.exports = { StatsSerializeStream, writeStats };
15 changes: 14 additions & 1 deletion test/statsUtils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { readFileSync } = require("node:fs");
const path = require("node:path");
const { globSync } = require("tinyglobby");
const { StatsSerializeStream } = require("../src/statsUtils");
const { StatsSerializeStream, writeStats } = require("../src/statsUtils");

async function stringify(json) {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -78,3 +78,16 @@ describe("StatsSerializeStream", () => {
});
}
});

describe("writeStats", () => {
it("should fail gracefully if writing to a non-existent directory", async () => {
const nonExistentPath = path.join(
__dirname,
"non-existent-dir",
"stats.json",
);
await expect(
writeStats({ foo: "bar" }, nonExistentPath),
).rejects.toMatchObject({ code: "ENOENT" });
});
});