Skip to content

Commit

Permalink
feat: view for transform results (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio authored Sep 15, 2024
1 parent 1637dfd commit b611a5a
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 11 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"repository": "https://github.com/AriPerkkio/vite-plugin-source-map-visualizer",
"scripts": {
"build": "rm -rf ./dist && tsc --project tsconfig.build.json && cp src/*.css dist",
"test": "vitest --coverage",
"test": "vitest --coverage --coverage.include=src",
"typecheck": "tsc --noEmit",
"example": "node scripts/generate-example.mjs",
"deploy": "touch example/.nojekyll && gh-pages --dist example --dotfiles true"
Expand Down
23 changes: 18 additions & 5 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from "node:fs/promises";
import { join } from "node:path";
import type { Logger, Plugin } from "vite";
import type { TransformResult } from "vite";

import { toVisualizer } from "./generate-link.js";
import { script, style } from "./report.js";
Expand All @@ -25,6 +26,8 @@ interface Result {
filename: string;
hash: string;
ssr: boolean;
code: TransformResult["code"];
map: TransformResult["map"];
}

/**
Expand Down Expand Up @@ -76,8 +79,9 @@ export function sourcemapVisualizer(options?: Options): Plugin {
const map = this.getCombinedSourcemap();
const hash = toVisualizer({ code, map });
const filename = formatName(id);
const ssr = options?.ssr || false;

results.push({ filename, hash, ssr: options?.ssr || false });
results.push({ filename, hash, code, map, ssr });
},

async buildEnd() {
Expand Down Expand Up @@ -116,13 +120,21 @@ function generateHTML(results: Result[]) {
<a href="#">Vite Source Map Visualizer</a>
</h1>
<button id="json-view-toggle" title="View transform results" style="display: none;">
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><g><rect width="24" height="24" opacity="0"/><path d="M15 16H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2z"/><path d="M9 14h3a1 1 0 0 0 0-2H9a1 1 0 0 0 0 2z"/><path d="M19.74 8.33l-5.44-6a1 1 0 0 0-.74-.33h-7A2.53 2.53 0 0 0 4 4.5v15A2.53 2.53 0 0 0 6.56 22h10.88A2.53 2.53 0 0 0 20 19.5V9a1 1 0 0 0-.26-.67zM14 5l2.74 3h-2a.79.79 0 0 1-.74-.85zm3.44 15H6.56a.53.53 0 0 1-.56-.5v-15a.53.53 0 0 1 .56-.5H12v3.15A2.79 2.79 0 0 0 14.71 10H18v9.5a.53.53 0 0 1-.56.5z"/></g></g></svg>
</button>
<button id="visualizer-view-toggle" title="View visualizer" style="display: none;">
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><g><rect width="24" height="24" opacity="0"/><path d="M20.71 19.29l-3.4-3.39A7.92 7.92 0 0 0 19 11a8 8 0 1 0-8 8 7.92 7.92 0 0 0 4.9-1.69l3.39 3.4a1 1 0 0 0 1.42 0 1 1 0 0 0 0-1.42zM5 11a6 6 0 1 1 6 6 6 6 0 0 1-6-6z"/></g></g></svg>
</button>
<button id="menu" title="Toggle file list">
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g data-name="Layer 2"><g data-name="menu"><rect width="24" height="24" transform="rotate(180 12 12)" opacity="0"/><rect x="3" y="11" width="18" height="2" rx=".95" ry=".95"/><rect x="3" y="16" width="18" height="2" rx=".95" ry=".95"/><rect x="3" y="6" width="18" height="2" rx=".95" ry=".95"/></g></g></svg>
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><g><rect width="24" height="24" transform="rotate(180 12 12)" opacity="0"/><rect x="3" y="11" width="18" height="2" rx=".95" ry=".95"/><rect x="3" y="16" width="18" height="2" rx=".95" ry=".95"/><rect x="3" y="6" width="18" height="2" rx=".95" ry=".95"/></g></g></svg>
</button>
<button id="theme-toggle" title="Toggle theme">
<svg id="theme-icon-light" class="theme-light" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g data-name="Layer 2"><g data-name="sun"><rect width="24" height="24" transform="rotate(180 12 12)" opacity="0"/><path d="M12 6a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v2a1 1 0 0 0 1 1z"/><path d="M21 11h-2a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2z"/><path d="M6 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h2a1 1 0 0 0 1-1z"/><path d="M6.22 5a1 1 0 0 0-1.39 1.47l1.44 1.39a1 1 0 0 0 .73.28 1 1 0 0 0 .72-.31 1 1 0 0 0 0-1.41z"/><path d="M17 8.14a1 1 0 0 0 .69-.28l1.44-1.39A1 1 0 0 0 17.78 5l-1.44 1.42a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.31z"/><path d="M12 18a1 1 0 0 0-1 1v2a1 1 0 0 0 2 0v-2a1 1 0 0 0-1-1z"/><path d="M17.73 16.14a1 1 0 0 0-1.39 1.44L17.78 19a1 1 0 0 0 .69.28 1 1 0 0 0 .72-.3 1 1 0 0 0 0-1.42z"/><path d="M6.27 16.14l-1.44 1.39a1 1 0 0 0 0 1.42 1 1 0 0 0 .72.3 1 1 0 0 0 .67-.25l1.44-1.39a1 1 0 0 0-1.39-1.44z"/><path d="M12 8a4 4 0 1 0 4 4 4 4 0 0 0-4-4zm0 6a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></g></g></svg>
<svg id="theme-icon-dark" class="theme-dark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g data-name="Layer 2"><g data-name="moon"><rect width="24" height="24" opacity="0"/><path d="M12.3 22h-.1a10.31 10.31 0 0 1-7.34-3.15 10.46 10.46 0 0 1-.26-14 10.13 10.13 0 0 1 4-2.74 1 1 0 0 1 1.06.22 1 1 0 0 1 .24 1 8.4 8.4 0 0 0 1.94 8.81 8.47 8.47 0 0 0 8.83 1.94 1 1 0 0 1 1.27 1.29A10.16 10.16 0 0 1 19.6 19a10.28 10.28 0 0 1-7.3 3zM7.46 4.92a7.93 7.93 0 0 0-1.37 1.22 8.44 8.44 0 0 0 .2 11.32A8.29 8.29 0 0 0 12.22 20h.08a8.34 8.34 0 0 0 6.78-3.49A10.37 10.37 0 0 1 7.46 4.92z"/></g></g></svg>
<svg id="theme-icon-light" aria-hidden="true" class="theme-light" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><g><rect width="24" height="24" transform="rotate(180 12 12)" opacity="0"/><path d="M12 6a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v2a1 1 0 0 0 1 1z"/><path d="M21 11h-2a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2z"/><path d="M6 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h2a1 1 0 0 0 1-1z"/><path d="M6.22 5a1 1 0 0 0-1.39 1.47l1.44 1.39a1 1 0 0 0 .73.28 1 1 0 0 0 .72-.31 1 1 0 0 0 0-1.41z"/><path d="M17 8.14a1 1 0 0 0 .69-.28l1.44-1.39A1 1 0 0 0 17.78 5l-1.44 1.42a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.31z"/><path d="M12 18a1 1 0 0 0-1 1v2a1 1 0 0 0 2 0v-2a1 1 0 0 0-1-1z"/><path d="M17.73 16.14a1 1 0 0 0-1.39 1.44L17.78 19a1 1 0 0 0 .69.28 1 1 0 0 0 .72-.3 1 1 0 0 0 0-1.42z"/><path d="M6.27 16.14l-1.44 1.39a1 1 0 0 0 0 1.42 1 1 0 0 0 .72.3 1 1 0 0 0 .67-.25l1.44-1.39a1 1 0 0 0-1.39-1.44z"/><path d="M12 8a4 4 0 1 0 4 4 4 4 0 0 0-4-4zm0 6a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></g></g></svg>
<svg id="theme-icon-dark" aria-hidden="true" class="theme-dark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><g><rect width="24" height="24" opacity="0"/><path d="M12.3 22h-.1a10.31 10.31 0 0 1-7.34-3.15 10.46 10.46 0 0 1-.26-14 10.13 10.13 0 0 1 4-2.74 1 1 0 0 1 1.06.22 1 1 0 0 1 .24 1 8.4 8.4 0 0 0 1.94 8.81 8.47 8.47 0 0 0 8.83 1.94 1 1 0 0 1 1.27 1.29A10.16 10.16 0 0 1 19.6 19a10.28 10.28 0 0 1-7.3 3zM7.46 4.92a7.93 7.93 0 0 0-1.37 1.22 8.44 8.44 0 0 0 .2 11.32A8.29 8.29 0 0 0 12.22 20h.08a8.34 8.34 0 0 0 6.78-3.49A10.37 10.37 0 0 1 7.46 4.92z"/></g></g></svg>
</button>
<details id="files" open>
Expand Down Expand Up @@ -150,7 +162,7 @@ function generateHTML(results: Result[]) {
</td>
<td class="center">
<a title="Open in source-map-visualization" target="_blank" href="https://evanw.github.io/source-map-visualization#${result.hash}">
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g data-name="Layer 2"><g data-name="external-link"><rect width="24" height="24" opacity="0"/><path d="M20 11a1 1 0 0 0-1 1v6a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h6a1 1 0 0 0 0-2H6a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3v-6a1 1 0 0 0-1-1z"/><path d="M16 5h1.58l-6.29 6.28a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0L19 6.42V8a1 1 0 0 0 1 1 1 1 0 0 0 1-1V4a1 1 0 0 0-1-1h-4a1 1 0 0 0 0 2z"/></g></g></svg>
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><g><rect width="24" height="24" opacity="0"/><path d="M20 11a1 1 0 0 0-1 1v6a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h6a1 1 0 0 0 0-2H6a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3v-6a1 1 0 0 0-1-1z"/><path d="M16 5h1.58l-6.29 6.28a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0L19 6.42V8a1 1 0 0 0 1 1 1 1 0 0 0 1-1V4a1 1 0 0 0-1-1h-4a1 1 0 0 0 0 2z"/></g></g></svg>
</a>
</td>
</tr>
Expand All @@ -160,6 +172,7 @@ function generateHTML(results: Result[]) {
</details>
<div id="json-visualizer" style="display: none;"></div>
<iframe id="source-map-visualizer" style="display: none;"></iframe>
</main>
<script>
Expand Down
63 changes: 63 additions & 0 deletions src/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,34 @@ export function script() {
fileList.open = !fileList.open;
});

const jsonView = document.getElementById("json-visualizer")!;
const visualizerView = document.getElementById("source-map-visualizer")!;
const jsonViewToggle = document.querySelector(
"button#json-view-toggle" as "button"
)!;
const visualizerViewToggle = document.querySelector(
"button#visualizer-view-toggle" as "button"
)!;

function setView(view: "json-view" | "visualizer-view") {
if (view === "json-view") {
visualizerView.style.display = "none";
jsonViewToggle.style.display = "none";
visualizerViewToggle.style.display = "block";
jsonView.style.display = "block";
} else {
jsonView.style.display = "none";
visualizerViewToggle.style.display = "none";
visualizerView.style.display = "block";
jsonViewToggle.style.display = "block";
}
}

jsonViewToggle.addEventListener("click", () => setView("json-view"));
visualizerViewToggle.addEventListener("click", () =>
setView("visualizer-view")
);

initializePage();
addEventListener("hashchange", initializePage);

Expand All @@ -32,14 +60,49 @@ export function script() {
"iframe#source-map-visualizer" as "iframe"
)!;

Array.from(jsonView.children).map((child) => jsonView.removeChild(child));

if (window.location.hash) {
iframe.src = `https://evanw.github.io/source-map-visualization${window.location.hash}`;
iframe.style.display = "block";
fileList.open = false;
setView("visualizer-view");

const result = convertHash(window.location.hash.slice(1));
const code = document.createElement("pre");
code.textContent = result.code;
jsonView.appendChild(code);

const map = document.createElement("pre");
map.textContent = JSON.stringify(result.map, null, 2);
jsonView.appendChild(map);
} else {
iframe.src = "";
iframe.style.display = "none";
fileList.open = true;

visualizerView.style.display = "none";
visualizerViewToggle.style.display = "none";
jsonView.style.display = "none";
jsonViewToggle.style.display = "none";
}
}

function convertHash(hash: string) {
let bin = atob(hash);
const code = readBuffer();
const map = readBuffer();

return { code, map: JSON.parse(map) };

function readBuffer() {
const zero = bin.indexOf("\0");
const start = zero + 1;
const end = start + (0 | parseInt(bin.slice(0, zero)));
const buffer = decodeURIComponent(bin.slice(start, end));

bin = bin.slice(end);
return buffer;
}
}
}
Expand Down
28 changes: 23 additions & 5 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ h1 {
}

button#theme-toggle,
button#menu {
button#menu,
button#json-view-toggle,
button#visualizer-view-toggle {
width: 3rem;
height: 3rem;
border: 0;
Expand All @@ -63,18 +65,23 @@ button#menu {
}

button#theme-toggle {
right: 1rem;
right: 2rem;
}

button#menu {
right: 5rem;
right: 6rem;
}

button#json-view-toggle,
button#visualizer-view-toggle {
right: 10rem;
}

a {
color: var(--text-accent);
}

details#files {
details#files[open] {
margin: 2rem;
}

Expand Down Expand Up @@ -105,5 +112,16 @@ svg.icon {

iframe {
height: 100%;
margin: 1rem;
margin: 2rem;
}

#json-visualizer {
margin: 2rem;
}

#json-visualizer pre {
overflow: auto;
border: 0.1rem solid var(--border);
margin-bottom: 2rem;
padding: 2rem;
}

0 comments on commit b611a5a

Please sign in to comment.