Skip to content

Commit b3f44b0

Browse files
authored
fix: race condition in writeStats (#711)
* fix: race condition in `writeStats` * docs: add changelog entry for #711
1 parent 3710653 commit b3f44b0

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
1212

1313
## UNRELEASED
1414

15+
* **Bug Fix**
16+
* 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))
17+
1518
## 5.2.0
1619

1720
* **New Feature**

src/statsUtils.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const { createWriteStream } = require("node:fs");
22
const { Readable } = require("node:stream");
3+
const { pipeline } = require("node:stream/promises");
34

45
/** @typedef {import("./BundleAnalyzerPlugin").EXPECTED_ANY} EXPECTED_ANY */
56
/** @typedef {import("webpack").StatsCompilation} StatsCompilation */
@@ -91,12 +92,7 @@ class StatsSerializeStream extends Readable {
9192
* @returns {Promise<void>}
9293
*/
9394
async function writeStats(stats, filepath) {
94-
return new Promise((resolve, reject) => {
95-
new StatsSerializeStream(stats)
96-
.on("end", resolve)
97-
.on("error", reject)
98-
.pipe(createWriteStream(filepath));
99-
});
95+
await pipeline(new StatsSerializeStream(stats), createWriteStream(filepath));
10096
}
10197

10298
module.exports = { StatsSerializeStream, writeStats };

test/statsUtils.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { readFileSync } = require("node:fs");
22
const path = require("node:path");
33
const { globSync } = require("tinyglobby");
4-
const { StatsSerializeStream } = require("../src/statsUtils");
4+
const { StatsSerializeStream, writeStats } = require("../src/statsUtils");
55

66
async function stringify(json) {
77
return new Promise((resolve, reject) => {
@@ -78,3 +78,16 @@ describe("StatsSerializeStream", () => {
7878
});
7979
}
8080
});
81+
82+
describe("writeStats", () => {
83+
it("should fail gracefully if writing to a non-existent directory", async () => {
84+
const nonExistentPath = path.join(
85+
__dirname,
86+
"non-existent-dir",
87+
"stats.json",
88+
);
89+
await expect(
90+
writeStats({ foo: "bar" }, nonExistentPath),
91+
).rejects.toMatchObject({ code: "ENOENT" });
92+
});
93+
});

0 commit comments

Comments
 (0)