Skip to content

Unable to parse webpack source URLs, how to work around around? #500

Open
@lancejpollard

Description

@lancejpollard

It looks like it's failing right here:

const url = new URL(input, base);

I have this code for parsing the string sourcemap from a JS file, but it's not working:

const CACHE: Record<string, SourceMapConsumer> = {}

async function loadFile(
  line: string,
): Promise<SourceMapConsumer | void> {
  const link = CACHE[`${line}`]
  if (link) {
    return link
  }

  const res = await fetch(line)
  const text = await res.text()
  const last = text.trim().split('\n').pop() ?? ''
  console.log(text)
  console.log(last)
  if (
    last.match(
      /(\/\/# sourceMappingURL=data:application\/json;charset=utf-8;base64,)/,
    )
  ) {
    console.log(last.slice(RegExp.$1.length))
    const json = JSON.parse(
      atob(last.slice(RegExp.$1.length)),
    ) as RawSourceMap
    json.sources.forEach((source, i) => {
      json.sources[i] = source.replace(/^webpack:\/\//g, 'http://')
    })
    console.log(json)

    const sm = await new SourceMapConsumer(json)
    CACHE[`${line}`] = sm
    return sm
  }
}

async function readFileLocation(
  file: string,
  line: number,
  rise: number,
): Promise<[string, number | undefined, number | undefined]> {
  const link = await loadFile(file)

  const trace = {
    column: rise,
    filename: file,
    line: line,
  }

  if (link) {
    const token = link.originalPositionFor(trace)
    if (token.source) {
      return [
        token.source,
        token.line == null ? undefined : token.line,
        token.column == null ? undefined : token.column,
      ]
    } else {
      return [file, line, rise]
    }
  } else {
    return [file, line, rise]
  }
}

export async function testSourceMaps(error: Error): Promise<string> {
  const stack = getFileLineColumn(error.stack?.split('\n') ?? [])
  const list: Array<string> = []

  for (const data of stack) {
    const [file, line, column] = await readFileLocation(
      data.file,
      data.line ?? 0,
      data.column ?? 0,
    )

    console.log(file, line, column)
  }
}

As you can see in the example, I tried to replace webpack:// with http:// but it didn't seem to help:

json.sources[i] = source.replace(/^webpack:\/\//g, 'http://')

How do I get this working, any suggestions? The error I'm getting is:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'decode')
    at new URLStateMachine (url-state-machine.js:546:1)
    at module.exports.basicURLParse (url-state-machine.js:1264:1)
    at new URLImpl (URL-impl.js:13:1)
    at Object.setup (URL.js:317:1)
    at new URL (URL.js:26:1)
    at util.js:179:1
    at Object.computeSourceURL (util.js:431:1)
    at source-map-consumer.js:207:1
    at Array.map (<anonymous>)
    at source-map-consumer.js:206:1

The JSON looks liek this when I parse the sourcemap in this fashion:

Screenshot 2024-02-20 at 11 58 14 AM

Any help would be greatly appreciated. Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions