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
5 changes: 5 additions & 0 deletions .changeset/calm-compilers-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"webpack-bundle-analyzer": patch
---

Resolve bundle assets and report files against the correct compiler output path when a plugin instance is shared by multiple compilers.
61 changes: 39 additions & 22 deletions src/BundleAnalyzerPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ class BundleAnalyzerPlugin {

if (this.opts.generateStatsFile) {
actions.push(() =>
this.generateStatsFile(stats.toJson(this.opts.statsOptions)),
this.generateStatsFile(
stats.toJson(this.opts.statsOptions),
compiler,
),
);
}

Expand All @@ -138,15 +141,21 @@ class BundleAnalyzerPlugin {

if (this.opts.analyzerMode === "server") {
actions.push(() =>
this.startAnalyzerServer(stats.toJson(analyzerStatsOptions)),
this.startAnalyzerServer(
stats.toJson(analyzerStatsOptions),
compiler,
),
);
} else if (this.opts.analyzerMode === "static") {
actions.push(() =>
this.generateStaticReport(stats.toJson(analyzerStatsOptions)),
this.generateStaticReport(
stats.toJson(analyzerStatsOptions),
compiler,
),
);
} else if (this.opts.analyzerMode === "json") {
actions.push(() =>
this.generateJSONReport(stats.toJson(analyzerStatsOptions)),
this.generateJSONReport(stats.toJson(analyzerStatsOptions), compiler),
);
}

Expand Down Expand Up @@ -175,12 +184,12 @@ class BundleAnalyzerPlugin {

/**
* @param {StatsCompilation} stats stats
* @param {Compiler} compiler compiler
* @returns {Promise<void>}
*/
async generateStatsFile(stats) {
async generateStatsFile(stats, compiler) {
const statsFilepath = path.resolve(
/** @type {Compiler} */
(this.compiler).outputPath,
compiler.outputPath,
this.opts.statsFilename,
);
await fs.promises.mkdir(path.dirname(statsFilepath), { recursive: true });
Expand All @@ -200,19 +209,23 @@ class BundleAnalyzerPlugin {

/**
* @param {StatsCompilation} stats stats
* @param {Compiler} compiler compiler
* @returns {Promise<void>}
*/
async startAnalyzerServer(stats) {
async startAnalyzerServer(stats, compiler) {
if (this.server) {
(await this.server).updateChartData(stats);
(await this.server).updateChartData(
stats,
this.getBundleDirFromCompiler(compiler),
);
} else {
this.server = viewer.startServer(stats, {
openBrowser: this.opts.openAnalyzer,
host: this.opts.analyzerHost,
port: this.opts.analyzerPort,
reportTitle: this.opts.reportTitle,
compressionAlgorithm: this.opts.compressionAlgorithm,
bundleDir: this.getBundleDirFromCompiler(),
bundleDir: this.getBundleDirFromCompiler(compiler),
logger: this.logger,
defaultSizes: this.opts.defaultSizes,
excludeAssets: this.opts.excludeAssets,
Expand All @@ -223,50 +236,54 @@ class BundleAnalyzerPlugin {

/**
* @param {StatsCompilation} stats stats
* @param {Compiler} compiler compiler
* @returns {Promise<void>}
*/
async generateJSONReport(stats) {
async generateJSONReport(stats, compiler) {
await viewer.generateJSONReport(stats, {
reportFilename: path.resolve(
/** @type {Compiler} */
(this.compiler).outputPath,
compiler.outputPath,
this.opts.reportFilename || "report.json",
),
compressionAlgorithm: this.opts.compressionAlgorithm,
bundleDir: this.getBundleDirFromCompiler(),
bundleDir: this.getBundleDirFromCompiler(compiler),
logger: this.logger,
excludeAssets: this.opts.excludeAssets,
});
}

/**
* @param {StatsCompilation} stats stats
* @param {Compiler} compiler compiler
* @returns {Promise<void>}
*/
async generateStaticReport(stats) {
async generateStaticReport(stats, compiler) {
await viewer.generateReport(stats, {
openBrowser: this.opts.openAnalyzer,
reportFilename: path.resolve(
/** @type {Compiler} */
(this.compiler).outputPath,
compiler.outputPath,
this.opts.reportFilename || "report.html",
),
reportTitle: this.opts.reportTitle,
compressionAlgorithm: this.opts.compressionAlgorithm,
bundleDir: this.getBundleDirFromCompiler(),
bundleDir: this.getBundleDirFromCompiler(compiler),
logger: this.logger,
defaultSizes: this.opts.defaultSizes,
excludeAssets: this.opts.excludeAssets,
});
}

getBundleDirFromCompiler() {
/**
* @param {Compiler} compiler compiler
* @returns {string | null} bundle directory
*/
getBundleDirFromCompiler(compiler) {
const outputFileSystemConstructor =
/** @type {OutputFileSystem} */
(/** @type {Compiler} */ (this.compiler).outputFileSystem).constructor;
(compiler.outputFileSystem).constructor;

if (typeof outputFileSystemConstructor === "undefined") {
return /** @type {Compiler} */ (this.compiler).outputPath;
return compiler.outputPath;
}
switch (outputFileSystemConstructor.name) {
case "MemoryFileSystem":
Expand All @@ -276,7 +293,7 @@ class BundleAnalyzerPlugin {
case "AsyncMFS":
return null;
default:
return /** @type {Compiler} */ (this.compiler).outputPath;
return compiler.outputPath;
}
}
}
Expand Down
11 changes: 8 additions & 3 deletions src/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function getChartData(analyzerOpts, bundleStats, bundleDir) {
* @property {AnalyzerUrl} analyzerUrl analyzer url
*/

/** @typedef {{ ws: WebSocketServer, http: Server, updateChartData: (bundleStats: StatsCompilation) => void }} ViewerServerObj */
/** @typedef {{ ws: WebSocketServer, http: Server, updateChartData: (bundleStats: StatsCompilation, bundleDir?: string | null) => void }} ViewerServerObj */

/**
* @param {StatsCompilation} bundleStats bundle stats
Expand Down Expand Up @@ -207,9 +207,14 @@ async function startServer(bundleStats, opts) {

/**
* @param {StatsCompilation} bundleStats bundle stats
* @param {string | null=} updatedBundleDir bundle directory
*/
function updateChartData(bundleStats) {
const newChartData = getChartData(analyzerOpts, bundleStats, bundleDir);
function updateChartData(bundleStats, updatedBundleDir = bundleDir) {
const newChartData = getChartData(
analyzerOpts,
bundleStats,
updatedBundleDir,
);

if (!newChartData) return;

Expand Down
25 changes: 25 additions & 0 deletions test/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,31 @@ describe("Plugin", () => {
expect(chartData).toBeDefined();
});

it("should use each compiler output path when a plugin instance is reused", async () => {
const plugin = new BundleAnalyzerPlugin({
analyzerMode: "json",
logLevel: "error",
});
const firstConfig = makeWebpackConfig();
const secondConfig = makeWebpackConfig();

firstConfig.output.path = path.resolve(__dirname, "./output/first");
firstConfig.plugins = [plugin];
secondConfig.output.path = path.resolve(__dirname, "./output/second");
secondConfig.plugins = [plugin];

await webpackCompile([firstConfig, secondConfig]);

for (const output of ["first", "second"]) {
const reportPath = path.resolve(
__dirname,
`./output/${output}/report.json`,
);
expect(fs.existsSync(reportPath)).toBe(true);
expect(JSON.parse(fs.readFileSync(reportPath, "utf8"))).not.toEqual([]);
}
});

it("should support webpack config with `multi` module", async () => {
const config = makeWebpackConfig();

Expand Down
Loading