esbuild
esbuild copied to clipboard
Issue with import { default as Blabla} .. export default async ()...
First of all thank you for you wonderful work!
everything is in the title but more explanation just here. Consider this example.js file
import { default as getUserById, list} from "../service/users.js";
export const listUsers = async ()=> {
const users = await list()
return users
}
export default async (id)=> {
const user = getUserById(id)
return user.data
}
importing example.js after it was bundled by esbuild we will have the following result
const exampleProps = await import("example.js")
console.log(exampleProps)
// =>
[Module: null prototype] {
default: { default: [Getter], list: [Getter] },
listUsers: [AsyncFunction: list2]
}
We except from default to have the content of "export default .." (a function) not the content of "import {default ..." (which is an object)
This causes an issue with imports with dynamic paths and dynamic function names when we need to access the "default" export function an easy workaround is to check if required function name is "default" then check if imported "default" is an object to access the 'real' export default from default.default
const handler = await import(esOutputPath);
let handlerName = "someName"
let eventHandler
// workaround
if (handlerName == "default" && typeof handler.default == "object" && typeof handler.default.default == "function") {
eventHandler = handler.default.default;
} else {
eventHandler = handler[handlerName];
}
I don't know if this is a bug or an excepted behaviour, just wanted to let you know!
Sorry but I'm unable to reproduce this given your description. Please provide instructions for how to reproduce the problematic behavior (including all source files, the esbuild command used for bundling, and the command used to run the code that imports the bundle afterward).
esbuildIssue.zip Here's an example project to reproduce the issue yarn install yarn build yarn start:bundled yarn start:original
I do not view this as a problem with esbuild. You are running import()
on a CommonJS file (the files in dist
are considered to be CommonJS because of the echo '{}' > ./dist/package.json
command). Node has decided to make import()
of a CommonJS file in node always return module.exports
regardless of whether or not that CommonJS file was originally an ES module (despite the rest of the JS ecosystem working the other way).
Your options:
-
Just avoid the
default
export- I recommend avoiding
default
in new code due to compatibility problems like this. There's unfortunately no way to fix this in 100% of cases. Changing something to make one case work will just make other cases break. More info here: https://esbuild.github.io/content-types/#default-interop
- I recommend avoiding
-
Use ESM instead of CommonJS:
- Pass
--format=esm
to esbuild - Change
echo '{}' > ./dist/package.json
toecho '{"type":"module"}' > ./dist/package.json
- Pass
Closing this issue as I do not consider it to be a problem with esbuild.