Skip to content

Commit dbc5465

Browse files
committed
Add vite-mpa-extra-modules tests
1 parent 597aa6e commit dbc5465

21 files changed

Lines changed: 546 additions & 49 deletions
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import type { SentryRollupPluginOptions } from "@sentry/rollup-plugin";
2+
export declare const sentryConfig: SentryRollupPluginOptions;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const sentryConfig = {
2+
telemetry: false,
3+
};

packages/integration-tests-next/fixtures/utils.ts

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,61 +26,70 @@ export function readAllFiles(
2626
customReplacer?: (content: string) => string
2727
): Record<string, string> {
2828
const files: Record<string, string> = {};
29-
const entries = readdirSync(directory);
30-
31-
for (const entry of entries) {
32-
const fullPath = join(directory, entry);
33-
const stat = statSync(fullPath);
34-
35-
if (stat.isFile()) {
36-
let contents = readFileSync(fullPath, "utf-8");
37-
// We replace the current SHA with a placeholder to make snapshots deterministic
38-
contents = contents
39-
.replaceAll(CURRENT_SHA, "CURRENT_SHA")
40-
.replaceAll(/"nodeVersion":\d+/g, `"nodeVersion":"NODE_VERSION"`)
41-
.replaceAll(/"nodeVersion": \d+/g, `"nodeVersion":"NODE_VERSION"`)
42-
.replaceAll(/nodeVersion:\d+/g, `nodeVersion:"NODE_VERSION"`)
43-
.replaceAll(/nodeVersion: \d+/g, `nodeVersion:"NODE_VERSION"`);
44-
45-
if (customReplacer) {
46-
contents = customReplacer(contents);
47-
}
4829

49-
// Normalize Windows stuff in .map paths
50-
if (entry.endsWith(".map")) {
51-
const map = JSON.parse(contents) as SourceMap;
52-
map.sources = map.sources.map((c) => c.replace(/\\/g, "/"));
53-
map.sourcesContent = map.sourcesContent.map((c) => c.replace(/\r\n/g, "\n"));
54-
contents = JSON.stringify(map);
55-
} else if (entry === "sentry-cli-mock.json") {
56-
// Remove the temporary directory path too
57-
contents = contents.replace(
58-
/"[^"]+sentry-bundler-plugin-upload.+?",/g,
59-
'"sentry-bundler-plugin-upload-path",'
60-
);
61-
} else if (entry === "sentry-telemetry.json") {
62-
// Remove the temporary directory path too
30+
function readDirRecursive(currentDir: string, relativePath: string = ""): void {
31+
const entries = readdirSync(currentDir);
32+
33+
for (const entry of entries) {
34+
const fullPath = join(currentDir, entry);
35+
const stat = statSync(fullPath);
36+
const relativeFilePath = relativePath ? join(relativePath, entry) : entry;
37+
38+
if (stat.isDirectory()) {
39+
// Recursively read subdirectories
40+
readDirRecursive(fullPath, relativeFilePath);
41+
} else if (stat.isFile()) {
42+
let contents = readFileSync(fullPath, "utf-8");
43+
// We replace the current SHA with a placeholder to make snapshots deterministic
6344
contents = contents
64-
.replace(
65-
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/g,
66-
"TIMESTAMP"
67-
)
68-
.replace(/[a-f0-9]{32}/g, "UUID")
69-
.replace(/"duration":[\d.]+/g, '"duration":DURATION')
70-
.replace(/"release":"[\d.]+"/g, '"release":"PLUGIN_VERSION"');
71-
} else {
72-
// Normalize Windows line endings for cross-platform snapshots
73-
contents = contents.replace(/\r\n/g, "\n");
74-
// Normalize debug IDs to make snapshots deterministic across environments
75-
contents = contents.replace(
76-
/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,
77-
"00000000-0000-0000-0000-000000000000"
78-
);
45+
.replaceAll(CURRENT_SHA, "CURRENT_SHA")
46+
.replaceAll(/"nodeVersion":\d+/g, `"nodeVersion":"NODE_VERSION"`)
47+
.replaceAll(/"nodeVersion": \d+/g, `"nodeVersion":"NODE_VERSION"`)
48+
.replaceAll(/nodeVersion:\d+/g, `nodeVersion:"NODE_VERSION"`)
49+
.replaceAll(/nodeVersion: \d+/g, `nodeVersion:"NODE_VERSION"`);
50+
51+
if (customReplacer) {
52+
contents = customReplacer(contents);
53+
}
54+
55+
// Normalize Windows stuff in .map paths
56+
if (entry.endsWith(".map")) {
57+
const map = JSON.parse(contents) as SourceMap;
58+
map.sources = map.sources.map((c) => c.replace(/\\/g, "/"));
59+
map.sourcesContent = map.sourcesContent.map((c) => c.replace(/\r\n/g, "\n"));
60+
contents = JSON.stringify(map);
61+
} else if (entry === "sentry-cli-mock.json") {
62+
// Remove the temporary directory path too
63+
contents = contents.replace(
64+
/"[^"]+sentry-bundler-plugin-upload.+?",/g,
65+
'"sentry-bundler-plugin-upload-path",'
66+
);
67+
} else if (entry === "sentry-telemetry.json") {
68+
// Remove the temporary directory path too
69+
contents = contents
70+
.replace(
71+
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/g,
72+
"TIMESTAMP"
73+
)
74+
.replace(/[a-f0-9]{32}/g, "UUID")
75+
.replace(/"duration":[\d.]+/g, '"duration":DURATION')
76+
.replace(/"release":"[\d.]+"/g, '"release":"PLUGIN_VERSION"');
77+
} else {
78+
// Normalize Windows line endings for cross-platform snapshots
79+
contents = contents.replace(/\r\n/g, "\n");
80+
// Normalize debug IDs to make snapshots deterministic across environments
81+
contents = contents.replace(
82+
/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,
83+
"00000000-0000-0000-0000-000000000000"
84+
);
85+
}
86+
// Use forward slashes for consistent cross-platform keys
87+
files[relativeFilePath.replace(/\\/g, "/")] = contents;
7988
}
80-
files[entry] = contents;
8189
}
8290
}
8391

92+
readDirRecursive(directory);
8493
return files;
8594
}
8695

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This is a shared module that is used by multiple HTML pages
2+
export function greet(name) {
3+
// eslint-disable-next-line no-console
4+
console.log(`Hello, ${String(name)}!`);
5+
}
6+
7+
export const VERSION = "1.0.0";
8+
9+
// Side effect: greet on load
10+
greet("World");
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Index Page</title>
6+
</head>
7+
<body>
8+
<h1>Index Page - No Scripts</h1>
9+
<!-- This page has no scripts -->
10+
</body>
11+
</html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Page 1</title>
6+
</head>
7+
<body>
8+
<h1>Page 1 - With Shared Module</h1>
9+
<script type="module" src="./shared-module.js"></script>
10+
</body>
11+
</html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Page 2</title>
6+
</head>
7+
<body>
8+
<h1>Page 2 - With Shared Module</h1>
9+
<script type="module" src="./shared-module.js"></script>
10+
</body>
11+
</html>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { defineConfig } from "vite";
2+
import { sentryVitePlugin } from "@sentry/vite-plugin";
3+
import { sentryConfig } from "../configs/vite-mpa-extra-modules.config.js";
4+
import { resolve } from "node:path";
5+
6+
export default defineConfig({
7+
build: {
8+
minify: false,
9+
sourcemap: true,
10+
outDir: "./out/vite-mpa-extra-modules",
11+
rollupOptions: {
12+
input: {
13+
index: resolve("./src/vite-mpa-index.html"),
14+
page1: resolve("./src/vite-mpa-page1.html"),
15+
page2: resolve("./src/vite-mpa-page2.html"),
16+
},
17+
output: {
18+
chunkFileNames: "[name].js",
19+
entryFileNames: "[name].js",
20+
},
21+
},
22+
},
23+
plugins: [sentryVitePlugin(sentryConfig)],
24+
});
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { expect } from "vitest";
2+
import { test } from "./utils";
3+
4+
test(import.meta.url, ({ runBundler, readOutputFiles }) => {
5+
runBundler();
6+
expect(readOutputFiles()).toMatchInlineSnapshot(`
7+
{
8+
"index.js.map": "{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}",
9+
"page1.js.map": "{"version":3,"file":"page1.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}",
10+
"page2.js.map": "{"version":3,"file":"page2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}",
11+
"shared-module.js": "!(function() {
12+
try {
13+
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
14+
e.SENTRY_RELEASE = { id: "CURRENT_SHA" };
15+
var n = new e.Error().stack;
16+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "00000000-0000-0000-0000-000000000000", e._sentryDebugIdIdentifier = "sentry-dbid-00000000-0000-0000-0000-000000000000");
17+
} catch (e2) {
18+
}
19+
})();
20+
(function polyfill() {
21+
const relList = document.createElement("link").relList;
22+
if (relList && relList.supports && relList.supports("modulepreload")) return;
23+
for (const link of document.querySelectorAll('link[rel="modulepreload"]')) processPreload(link);
24+
new MutationObserver((mutations) => {
25+
for (const mutation of mutations) {
26+
if (mutation.type !== "childList") continue;
27+
for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node);
28+
}
29+
}).observe(document, {
30+
childList: true,
31+
subtree: true
32+
});
33+
function getFetchOpts(link) {
34+
const fetchOpts = {};
35+
if (link.integrity) fetchOpts.integrity = link.integrity;
36+
if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
37+
if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include";
38+
else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
39+
else fetchOpts.credentials = "same-origin";
40+
return fetchOpts;
41+
}
42+
function processPreload(link) {
43+
if (link.ep) return;
44+
link.ep = true;
45+
const fetchOpts = getFetchOpts(link);
46+
fetch(link.href, fetchOpts);
47+
}
48+
})();
49+
function greet(name) {
50+
console.log(\`Hello, \${String(name)}!\`);
51+
}
52+
greet("World");
53+
//# sourceMappingURL=shared-module.js.map
54+
",
55+
"shared-module.js.map": "{"version":3,"file":"shared-module.js","sources":["../../src/shared-module.js"],"sourcesContent":["// This is a shared module that is used by multiple HTML pages\\nexport function greet(name) {\\n // eslint-disable-next-line no-console\\n console.log(\`Hello, \${String(name)}!\`);\\n}\\n\\nexport const VERSION = \\"1.0.0\\";\\n\\n// Side effect: greet on load\\ngreet(\\"World\\");\\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACO,SAAS,MAAM,MAAM;AAE1B,UAAQ,IAAI,UAAU,OAAO,IAAI,CAAC,GAAG;AACvC;AAKA,MAAM,OAAO;"}",
56+
"src/vite-mpa-index.html": "<!doctype html>
57+
<html lang="en">
58+
<head>
59+
<meta charset="UTF-8" />
60+
<title>Index Page</title>
61+
</head>
62+
<body>
63+
<h1>Index Page - No Scripts</h1>
64+
<!-- This page has no scripts -->
65+
</body>
66+
</html>
67+
",
68+
"src/vite-mpa-page1.html": "<!doctype html>
69+
<html lang="en">
70+
<head>
71+
<meta charset="UTF-8" />
72+
<title>Page 1</title>
73+
<script type="module" crossorigin src="/shared-module.js"></script>
74+
</head>
75+
<body>
76+
<h1>Page 1 - With Shared Module</h1>
77+
</body>
78+
</html>
79+
",
80+
"src/vite-mpa-page2.html": "<!doctype html>
81+
<html lang="en">
82+
<head>
83+
<meta charset="UTF-8" />
84+
<title>Page 2</title>
85+
<script type="module" crossorigin src="/shared-module.js"></script>
86+
</head>
87+
<body>
88+
<h1>Page 2 - With Shared Module</h1>
89+
</body>
90+
</html>
91+
",
92+
}
93+
`);
94+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This is a shared module that is used by multiple HTML pages
2+
export function greet(name) {
3+
// eslint-disable-next-line no-console
4+
console.log(`Hello, ${String(name)}!`);
5+
}
6+
7+
export const VERSION = "1.0.0";
8+
9+
// Side effect: greet on load
10+
greet("World");

0 commit comments

Comments
 (0)