-
-
Notifications
You must be signed in to change notification settings - Fork 47
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
[core] Add import extensions #812
Conversation
Netlify deploy preview |
8e36f30
to
aebc7ee
Compare
I would advise against this. I believe it will make your files impossible to execute without a build step, e.g. with |
I just checked that
We can add extensions pretty easily to the build output, however it's not the case with type declaration files. Since they are produced with TypeScript, we can't run any transforms during their generation AFAIK. We could theoretically take the built definition files and add extensions to their imports as an additional build step, but I haven't found a tool that does this reliably (the one I mentioned in the PR description required some manual steps). |
Why do we need extensions in declaration files? don't they just follow typescript resolution? The only tool that cares about them is the typescript compiler and unlike ESM hosts, it knows how to resolve bare imports correctly. |
There are issues related to this. I described them in #745. According to the TS team, a declaration file should be related to exactly one implementation file, so ESM output should have its own declarations. And, since it's ESM, it should have extensions. |
For the record, I'm not a fan of importing output files in the source code, to say the least, and I'm glad that Typescript will support rewriting relative import paths soon. I am considering using the .ts(x) extensions once https://devblogs.microsoft.com/typescript/announcing-typescript-5-7-beta/#path-rewriting-for-relative-paths lands. |
I don't think that's how resolution works with declaration files.
https://www.typescriptlang.org/docs/handbook/modules/theory.html#the-role-of-declaration-files |
|
exactly, if you generate your declaration files next to your esm files and both are under a folder with a package.json with type module, then all is fine, no? no need to change the imports in declaration files, as far as i understand. |
If they are in a directory with |
does that same restriction apply when you use the mjs extension instead? it has the added benefit of making life simpler for resolvers. they don't need to traverse up in the file tree looking for out of band esm configurations |
Yes, it doesn't matter. I authored the .d.mts files by hand and omitted the extension. I added both the .d.mts extension and |
Ok, I see. An alternative could be to run |
👍, yup, this seems to work at first glance (assuming the declaration files are identical when built for nodenext and esnext/bundler, but it seems to be the case). I can explore it further. Having extensionless imports in source would still require us to use a transform after building. If we go with extensions, we could potentially build the project using tsc at some point, saving some CI time. Is there an objective reason you're against having extensions in the source, or is it just your preference? |
Yes ofcourse, from the point of As from typescript point of view it makes sense to me that they don't want to be much more than a type checker for now. But from a user point of view it doesn't. We want access to transpiler and bundler features, and we want to reference files without their extension, or if we must at least with an extension that makes sense (.ts). That seems rather evident to me, from a user point of view, how would it ever make sense to reference a typescript file using a .js extension? In the meantime ofcourse we need a solution, I slightly lean towards avoiding .js extensions in all of our code bases if we can do it in a reasonable way, but not at any cost. Depends on where we envision our tooling to go, above is my opinion, but open for debate ofcourse. |
Not necessarily - they figured that rewriting extensions might cause issues and deliberately did not allow this:
This is a problem that even a bundler cannot solve, so in some cases, the .js extension has to be used. Now, this issue is very unlikely to affect us, as we don't use dynamic imports in library code. Having the .ts extension in static imports (assuming using TS 5.7) would actually make code even more universal (re your point about making files impossible to execute without a build step), as it could be runnable by tsx and plain Node (with I created a PR for outputting ESM+CJS without the need for extensions in import specifiers: #821. It seems to be working well, so if you don't mind, we can work on merging it and then continue discussing the import extensions separately. |
Used fix-esm-import-path to add extensions to all our relative imports and exports in the Base UI package.
It is needed to implement #745 correctly.