Skip to content

default resolve should not throw ERR_UNSUPPORTED_ESM_URL_SCHEME #138

Closed
nodejs/node
#47824
@giltayar

Description

While working on my ESM loaders talk for JSNation and NodeTLV conferences (repo here and draft slides here), I wrote a toy loader that supports HTTP[S]. This is the (obviously) simplistic code:

export async function load(url, context, nextLoad) {
  if (url.startsWith('http://') || url.startsWith('https://')) {
    const response = await fetch(url, {redirect: 'follow'})
    const source = await response.text()

    return {shortCircuit: true, format: 'module',source}
  }
  return await nextLoad(url, context)
}

Unfortunately, this won't work. If you use it, you will get an ERR_UNSUPPORTED_ESM_URL_SCHEME because the default Node.js resolver doesn't support HTTPS. So, unfortunately, I had to write (and demonstrate in my talk) that this loader needs a resolver, even though the only thing it does is support loading HTTPS:

export async function resolve(specifier, context, nextResolve) {
  if (isBareSpecifier(specifier))
    return await nextResolve(specifier, context)

  const url = new URL(specifier, context.parentURL).href

  if (url.startsWith('http://') || url.startsWith('https://'))
    return {url, shortCircuit: true}

  return await nextResolve(specifier, context)
}

Thinking about it more, I realized that the only reason I need to write this resolver is that Node.js doesn't recognize the HTTP scheme in its resolver. But if Node.js would have not recognized the scheme in the loader, then I wouldn't have needed to write this resolver at all.

The same logic goes for ERR_UNKNOWN_FILE_EXTENSION and writing, for example, a TypeScript loader.

So my point is this: both checks for unknown scheme and unknown file extension should move from the default Node.js resolver to the default Node.js loader. This will obviate the need for some loaders to implement a resolve which mostly replicates the Node.js logic, just for the sake of avoiding these exceptions.

I would gladly implement the change myself, but I wanted to check with the loaders team before tackling this task.

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