default resolve
should not throw ERR_UNSUPPORTED_ESM_URL_SCHEME
#138
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.