Loader cannot be determined if url doesn't contain filename or filename isn't a loader
The current implementation determines the loader by the file extensions. This works well when importing from urls that contain a file extension like deno.land:
import { parse } from "https://deno.land/x/xml/mod.ts";
But it causes problems when the url doesn't contain a filename like esm.sh:
import {mainSymbols} from 'https://esm.sh/[email protected]';
Or when the file has an extension but the loaders name isn't exactly the same as the file extension, e.g. the 'js' loader can load files ending in .js, .cjs or .mjs, which happens with the deno node compatibility layer:
https://deno.land/[email protected]/node/internal/buffer.mjs
How could we fix this problem? I thought about checking the determined loader against a list of officially supported esbuild loaders and if it's not any of them just default to 'ts' because that would work for js and ts files. It still won't work if I one wants to import a json file that way, but that doesn't work now anyway so it won't make things worse.
I could also think of something like an import map option for the plugin that lets you override a loader for a url, that would be suitable for cases where it's absolute not possible to determine the correct loader from the url, but I think defaulting to the ts loader would be enough.
This is the workaround I'm currently using, If you think this is a suitable solution I'd be happy to submit a PR
const allowedLoaders = ['js','ts','tsx','jsx','json','css','text','binary','base64','dataurl','file','copy']
let {pathname} = new URL(source.url)
let loader = pathname.match(/[^.]+$/)[0]
if(!allowedLoaders.includes(loader)){
loader = 'ts'
}
Came here to report the same thing. Thanks for the workaround, @danielr1996 I was thinking of doing something similar! :)
Would one way to be to check the media type of the resource like Deno does?
https://deno.land/[email protected]/advanced/typescript/overview#supported-media-types