Skip to content

Commit

Permalink
feat: inspect sourcemaps button (#79)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
remorses and antfu committed Jun 28, 2023
1 parent 3d4a0c3 commit 5efcd75
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 6 deletions.
56 changes: 56 additions & 0 deletions src/client/logic/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,59 @@ export function guessMode(code: string) {
return 'css'
return 'javascript'
}

export function inspectSourcemaps({ code, sourcemaps }: {
code: string
sourcemaps?: string
}) {
// easier debugging of sourcemaps
// eslint-disable-next-line no-console
console.info('sourcemaps', JSON.stringify(sourcemaps, null, 2))

const serialized = serializeForSourcemapsVisualizer(code, sourcemaps!)
// open link in new tab
window.open(`https://evanw.github.io/source-map-visualization#${serialized}`, '_blank')
}

export function safeJsonParse(str: string) {
try {
return JSON.parse(str)
}
catch (e) {
console.error('Failed to parse JSON', str)
return null
}
}

// serialize to base64 and delimited by null characters and code length
// parser code: https://github.com/evanw/source-map-visualization/blob/5c08ef62f3eff597796f1b5c73ae822d9f467d00/code.js#L1794
function serializeForSourcemapsVisualizer(code: string, map: string) {
const encoder = new TextEncoder()

// Convert the strings to Uint8Array
const codeArray = encoder.encode(code)
const mapArray = encoder.encode(map)

// Create Uint8Array for the lengths
const codeLengthArray = encoder.encode(codeArray.length.toString())
const mapLengthArray = encoder.encode(mapArray.length.toString())

// Combine the lengths and the data
const combinedArray = new Uint8Array(codeLengthArray.length + 1 + codeArray.length + mapLengthArray.length + 1 + mapArray.length)

combinedArray.set(codeLengthArray)
combinedArray.set([0], codeLengthArray.length)
combinedArray.set(codeArray, codeLengthArray.length + 1)
combinedArray.set(mapLengthArray, codeLengthArray.length + 1 + codeArray.length)
combinedArray.set([0], codeLengthArray.length + 1 + codeArray.length + mapLengthArray.length)
combinedArray.set(mapArray, codeLengthArray.length + 1 + codeArray.length + mapLengthArray.length + 1)

// Convert the Uint8Array to a binary string
let binary = ''
const len = combinedArray.byteLength
for (let i = 0; i < len; i++)
binary += String.fromCharCode(combinedArray[i])

// Convert the binary string to a base64 string and return it
return btoa(binary)
}
22 changes: 20 additions & 2 deletions src/client/pages/index/module.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useRouteQuery } from '@vueuse/router'
import { Pane, Splitpanes } from 'splitpanes'
import { msToTime } from '../../logic/utils'
import { enableDiff, inspectSSR, lineWrapping, onRefetch, showOneColumn } from '../../logic'
import { enableDiff, inspectSSR, inspectSourcemaps, lineWrapping, onRefetch, safeJsonParse, showOneColumn } from '../../logic'
import { rpc } from '../../logic/rpc'
import type { HMRData } from '../../../types'
import { getHot } from '../../logic/hot'
Expand All @@ -26,6 +26,21 @@ watch([id, inspectSSR], refetch)
const from = computed(() => data.value?.transforms[currentIndex.value - 1]?.result || '')
const to = computed(() => data.value?.transforms[currentIndex.value]?.result || '')
const sourcemaps = computed(() => {
let sourcemaps = data.value?.transforms[currentIndex.value]?.sourcemaps
if (!sourcemaps)
return undefined
if (typeof sourcemaps === 'string')
sourcemaps = safeJsonParse(sourcemaps)
if (!sourcemaps?.mappings)
return
if (sourcemaps && !sourcemaps.sourcesContent) {
sourcemaps.sourcesContent = []
sourcemaps.sourcesContent[0] = from.value
}
return JSON.stringify(sourcemaps)
})
getHot().then((hot) => {
if (hot) {
Expand Down Expand Up @@ -54,6 +69,9 @@ getHot().then((hot) => {
<button text-lg icon-btn title="Inspect SSR" @click="inspectSSR = !inspectSSR">
<div i-carbon-cloud-services :class="inspectSSR ? 'opacity-100' : 'opacity-25'" />
</button>
<button text-lg icon-btn :title="sourcemaps ? 'Inspect sourcemaps' : 'Sourcemap is not available'" :disabled="!sourcemaps" @click="inspectSourcemaps({ code: to, sourcemaps })">
<div i-carbon-choropleth-map :class="sourcemaps ? 'opacity-100' : 'opacity-25'" />
</button>
<button text-lg icon-btn title="Line Wrapping" @click="lineWrapping = !lineWrapping">
<div i-carbon-text-wrap :class="lineWrapping ? 'opacity-100' : 'opacity-25'" />
</button>
Expand Down Expand Up @@ -83,7 +101,7 @@ getHot().then((hot) => {
<button
border="b main"
flex="~ gap-1 wrap"
items-center px-2 py-2 text-left font-mono text-xs
items-center px-2 py-2 text-left text-xs font-mono
:class="
currentIndex === idx
? 'bg-active'
Expand Down
9 changes: 5 additions & 4 deletions src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,14 @@ export default function PluginInspect(options: Options = {}): Plugin {
const end = Date.now()

const result = typeof _result === 'string' ? _result : _result?.code

const sourcemaps = typeof _result === 'string' ? null : _result?.map
const map = ssr ? transformMapSSR : transformMap
if (filter(id) && result != null) {
// initial tranform (load from fs), add a dummy
if (!map[id])
map[id] = [{ name: dummyLoadPluginName, result: code, start, end: start }]
map[id] = [{ name: dummyLoadPluginName, result: code, start, end: start, sourcemaps }]
// record transform
map[id].push({ name: plugin.name, result, start, end, order })
map[id].push({ name: plugin.name, result, start, end, order, sourcemaps })
}

return _result
Expand All @@ -276,10 +276,11 @@ export default function PluginInspect(options: Options = {}): Plugin {
const end = Date.now()

const result = typeof _result === 'string' ? _result : _result?.code
const sourcemaps = typeof _result === 'string' ? null : _result?.map

const map = ssr ? transformMapSSR : transformMap
if (filter(id) && result != null)
map[id] = [{ name: plugin.name, result, start, end }]
map[id] = [{ name: plugin.name, result, start, end, sourcemaps }]

return _result
})
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface TransformInfo {
start: number
end: number
order?: string
sourcemaps?: any
}

export interface ResolveIdInfo {
Expand Down

0 comments on commit 5efcd75

Please sign in to comment.