From ab98b4f10d9f33e6d51d48000064d81baf9d0992 Mon Sep 17 00:00:00 2001
From: Abdelrahman Awad
Date: Mon, 5 Jan 2026 18:42:45 +0200
Subject: [PATCH 1/5] test: added testing fixtures
---
.../build-vite-with-plugin.ts | 29 ++++
.../build-vite-without-plugin.ts | 23 ++++
.../vite-mpa-extra-modules/input/index.html | 12 ++
.../vite-mpa-extra-modules/input/page1.html | 12 ++
.../vite-mpa-extra-modules/input/page2.html | 12 ++
.../input/shared-module.js | 10 ++
.../vite-mpa-extra-modules.test.ts | 125 ++++++++++++++++++
7 files changed, 223 insertions(+)
create mode 100644 packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-with-plugin.ts
create mode 100644 packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-without-plugin.ts
create mode 100644 packages/integration-tests/fixtures/vite-mpa-extra-modules/input/index.html
create mode 100644 packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page1.html
create mode 100644 packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page2.html
create mode 100644 packages/integration-tests/fixtures/vite-mpa-extra-modules/input/shared-module.js
create mode 100644 packages/integration-tests/fixtures/vite-mpa-extra-modules/vite-mpa-extra-modules.test.ts
diff --git a/packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-with-plugin.ts b/packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-with-plugin.ts
new file mode 100644
index 00000000..b6ffede0
--- /dev/null
+++ b/packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-with-plugin.ts
@@ -0,0 +1,29 @@
+import { sentryVitePlugin } from "@sentry/vite-plugin";
+import * as path from "path";
+import * as vite from "vite";
+
+const inputDir = path.join(__dirname, "input");
+
+void vite.build({
+ clearScreen: false,
+ root: inputDir,
+ build: {
+ sourcemap: true,
+ outDir: path.join(__dirname, "out", "with-plugin"),
+ emptyOutDir: true,
+ rollupOptions: {
+ input: {
+ index: path.join(inputDir, "index.html"),
+ page1: path.join(inputDir, "page1.html"),
+ page2: path.join(inputDir, "page2.html"),
+ },
+ },
+ },
+ plugins: [
+ sentryVitePlugin({
+ telemetry: false,
+ // Empty options - the issue says options don't affect the results
+ }),
+ ],
+});
+
diff --git a/packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-without-plugin.ts b/packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-without-plugin.ts
new file mode 100644
index 00000000..bc0333fb
--- /dev/null
+++ b/packages/integration-tests/fixtures/vite-mpa-extra-modules/build-vite-without-plugin.ts
@@ -0,0 +1,23 @@
+import * as path from "path";
+import * as vite from "vite";
+
+const inputDir = path.join(__dirname, "input");
+
+void vite.build({
+ clearScreen: false,
+ root: inputDir,
+ build: {
+ sourcemap: true,
+ outDir: path.join(__dirname, "out", "without-plugin"),
+ emptyOutDir: true,
+ rollupOptions: {
+ input: {
+ index: path.join(inputDir, "index.html"),
+ page1: path.join(inputDir, "page1.html"),
+ page2: path.join(inputDir, "page2.html"),
+ },
+ },
+ },
+ plugins: [],
+});
+
diff --git a/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/index.html b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/index.html
new file mode 100644
index 00000000..96bf2899
--- /dev/null
+++ b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Index Page
+
+
+ Index Page - No Scripts
+
+
+
+
diff --git a/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page1.html b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page1.html
new file mode 100644
index 00000000..502c2306
--- /dev/null
+++ b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page1.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Page 1
+
+
+ Page 1 - With Shared Module
+
+
+
+
diff --git a/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page2.html b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page2.html
new file mode 100644
index 00000000..a9aab7c4
--- /dev/null
+++ b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/page2.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Page 2
+
+
+ Page 2 - With Shared Module
+
+
+
+
diff --git a/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/shared-module.js b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/shared-module.js
new file mode 100644
index 00000000..07182654
--- /dev/null
+++ b/packages/integration-tests/fixtures/vite-mpa-extra-modules/input/shared-module.js
@@ -0,0 +1,10 @@
+// This is a shared module that is used by multiple HTML pages
+export function greet(name) {
+ // eslint-disable-next-line no-console
+ console.log(`Hello, ${String(name)}!`);
+}
+
+export const VERSION = "1.0.0";
+
+// Side effect: greet on load
+greet("World");
diff --git a/packages/integration-tests/fixtures/vite-mpa-extra-modules/vite-mpa-extra-modules.test.ts b/packages/integration-tests/fixtures/vite-mpa-extra-modules/vite-mpa-extra-modules.test.ts
new file mode 100644
index 00000000..b46c36ef
--- /dev/null
+++ b/packages/integration-tests/fixtures/vite-mpa-extra-modules/vite-mpa-extra-modules.test.ts
@@ -0,0 +1,125 @@
+/**
+ * Test for GitHub Issue #829:
+ * sentryVitePlugin creates unnecessary JS modules for each index page
+ *
+ * In a Vite multi-page app (MPA), sentryVitePlugin causes "vite build" to emit
+ * a separate, unique, unexpected JS module for each index page.
+ *
+ * Expected: The plugin should add metadata to generated modules but should NOT
+ * rework the import graph, create new modules, or add script tags to pages
+ * that didn't have them in the first place.
+ *
+ * Actual: A unique module is generated for every HTML page in rollup.options.input.
+ * Pages that had been sharing modules will instead load a page-specific module
+ * that imports the shared code. Pages that didn't contain ANY scripts will now have one.
+ */
+import childProcess from "child_process";
+import fs from "fs";
+import path from "path";
+
+function getAssetFiles(outDir: string): string[] {
+ const assetsDir = path.join(outDir, "assets");
+ if (!fs.existsSync(assetsDir)) {
+ return [];
+ }
+ return fs.readdirSync(assetsDir).filter((file) => file.endsWith(".js"));
+}
+
+function getScriptTagsFromHtml(htmlPath: string): string[] {
+ if (!fs.existsSync(htmlPath)) {
+ return [];
+ }
+ const content = fs.readFileSync(htmlPath, "utf-8");
+ const scriptMatches = content.match(/
-
+ Page 1 - With Shared Module
+
+