-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
--platform=node --format=esm should output explicit ".js" imports #1343
Comments
The solution that TypeScript has designed for this scenario is that you actually write the So you should just change your source code to get this to work. Getting this to work shouldn’t be done by changing esbuild itself. The TypeScript compiler doesn’t do this so esbuild shouldn’t either. Closing as “by design.” |
Hi Evan, thank you for your quick response. I've read the link you've shared, also I've been reading up on TypeScript teams decisions on allowing or changing explicit extensions. I have to say I'm deeply disappointed by their decision and justifications, I think they are doing a great disservice to the web development community as a whole by insisting extensionless imports or not allowing explicit TS imports or not rewriting them on output. As you suggested moving the references to '.js' works for esbuild and tools that utilize it internally(like the test runner I built called qunitx), however the same code gives errors when I run with webpack, it says it cant resolve the modules. I tried to disable resolving with bunch of options still couldnt get it to work in webpack. In other words, TS teams stubbornness on this issue contradicts with principle of least surprise and causes unintuitive workarounds for developers. They should simply "change JS semantics" by rewrite or add extensions and I think esbuild should do as well because this also contradicts principle of least surprise:
I expect this command to transform/build to code to be runnable in node.js esm mode. Although I know esbuild doesnt do typechecks or runs the code, it should still build the code that passes typescript checks in accordance to node.js esm environment which expects relative imports to be explicit with its extension, in addition to deno runtime. |
I agree that the situation is unfortunate. Arguably the root of the problem is that node.js allowed implicit extensions to begin with, which is a decision they have come to regret because of the complexity and performance issues it causes. Anyway, I believe esbuild should follow the TypeScript team’s decision here. The TypeScript team owns the decisions about how their language works, not me. If this is to be changed the change would have to come from them. If your TypeScript setup for Webpack can’t compile certain TypeScript code that the official TypeScript compiler can then that’s a limitation with that Webpack setup, not a problem with esbuild. I assume you’re hitting this: TypeStrong/ts-loader#465. According to the Webpack team, If you want to use esbuild for your code but don’t want to change your source code, you can add the require('esbuild').build({
entryPoints: ['packages/@memserver/model/test/index.ts'],
bundle: true,
platform: 'node',
format: 'esm',
plugins: [{
name: 'resolve-ts',
setup(build) {
build.onResolve({ filter: /.*/ }, args => {
if (args.kind === 'entry-point') return
let path = args.path
if (!path.endsWith('.js')) path += '.js'
return { path, external: true }
})
},
}],
}) Note that you need to include |
Hi Evan thank you for your detailed answer! I agree that its fair to not allow .ts if typescript doesnt allow it. However esbuild should still transpile relative imports without extensions to explicit extensions when --mode=esm --platform=node selected because node wont execute the transpiled output and crash since it always expects explicit paths. Since this is also the default browser behavior when script executed without --bundle on esbuild I still thing esbuild should implement the transpiled explicit extension output when received input has non explicit/implicit relative paths. You've mentioned the topic of ts explicit resolved code as input during transpilation, which is another additional topic I think and I agree addons/plugins are probably a better place for this i.e a deno addon etc. |
@izelnakri (and others who may encounter this) in case you didn't see it in the linked issue, the plugin for webpack that handles this is here: https://github.com/softwareventures/resolve-typescript-plugin Sorry to hijack the thread. Hopefully this helps someone. |
Node.js doesnt support relative imports without extension when used on esm mode("type": "module") Thus I can't transpile my typescript files to node esm runtime with esbuild. Commonjs format is not an option since my test runner code expects files to be esm modules.
outputs:
It should output:
The text was updated successfully, but these errors were encountered: