Skip to content

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

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions