lucacasonato / esbuild_deno_loader

Deno module resolution for `esbuild`
https://deno.land/x/esbuild_deno_loader
MIT License
156 stars 41 forks source link

Loader doesn't work with esbuild's stdio option #125

Open MariusVatasoiu opened 3 months ago

MariusVatasoiu commented 3 months ago

If I use the stdin option to set the entrypoint, I get the following error:

[ERROR] [assert] namespace is empty [plugin deno-resolver]

    <stdin>:1:7:
      1 │ import "https://deno.land/std@0.185.0/bytes/mod.ts";
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is the code snippet used:

import * as esbuild from "npm:esbuild@0.20.2";
import { denoPlugins } from "jsr:@luca/esbuild-deno-loader@^0.10.3";

const result = await esbuild.build({
  stdin: {
    contents: `
    import "https://deno.land/std@0.185.0/bytes/mod.ts";
    import "./main.ts";       
    `,
    resolveDir: Deno.cwd(),
  },
  plugins: [...denoPlugins()],
  outfile: "./test.bundle.js",
  bundle: true,
  format: "esm",
});

console.log(result.outputFiles);

esbuild.stop();

Esbuild doesn't set the namespace for stdin entrypoint. The object received by the plugin looks like this:

{
  path: "https://deno.land/std@0.185.0/bytes/mod.ts",
  importer: "<stdin>",
  namespace: "",
  resolveDir: "/Users/...",
  kind: "import-statement",
  pluginData: undefined
}
{
  path: "./main.ts",
  importer: "<stdin>",
  namespace: "",
  resolveDir: "/Users/...",
  kind: "import-statement",
  pluginData: undefined
}

Might be as well an esbuild bug, but not sure if the loader can handle this case.

lucacasonato commented 3 months ago

I just have to special case importer == "<stdin>" && namespace == "" to instead use $resolveDir/__stdin.ts as the importer with a namespace of file.

MariusVatasoiu commented 3 months ago

I also opened an issue on esbuild: https://github.com/evanw/esbuild/issues/3726

MariusVatasoiu commented 3 months ago

I think one extra check would be args.resolveDir !== "". If you're omitting the resolveDir: Deno.cwd() option, args.resolveDir will be an empty string.