Appending .js extension on relative import statements during Typescript compilation (ES6 modules)

To fellow developers who are looking for a solution to this issue, the possible work-arounds we have come across are as follows:

  1. For new files, it is possible to simply add ".js" extension in the import statement in Typescript file while editing. Example: import {HelloWorld} from "./HelloWorld.js";

  2. If working with old projects, rather than going through each and every file and updating the import statements, we found it easier to simply batch rename and remove the ".js" extension from the generated Javascript via a simple automated script. Please note however that this might require a minor change in the server side code to serve these extension-less ".js" files with the proper MIME type to the clients. If you want to avoid this, you may instead want to use regular expression to batch find and replace the import statements recursively to add the .js extension.

Side note:

Regarding the TS team’s failure on resolving this issue, it appears that there is a tendency to try to blow up this issue out of context than what it really is and attach that to some design principles to defend.

However, factually this is nothing more than an issue with how the compiler deals asymmetrically with the extension. The Typescript compiler allows import statement without an extension. It then goes on to add “.js” extension to the corresponding output filename while the file is being translated, but for the corresponding import statements where this file is referenced it ignores the fact that it has added “.js” extension during translation. How can this asymmetricity be defended by the out of context URI rewriting principles?

There is a fixed one to one correspondence between the Typescript file and the generated Javascript output file during compilation. If the referenced import does not exists, the compiler would throw an error. The files wouldn’t even compile! So, out of context or non-compilable examples mentioning the possibility of other conflicting URIs invalidate such claims.

If the compiler simply generated extension-less output files it would also solve the issue. But, would that also somehow violate the design principle regarding URI rewrites? Certainly, in that case there could exist other design principles to defend the position! But wouldn’t such stubbornness only help to further validate the adamancy or ignorance of the TS team on this issue?

Leave a Comment