This seems to be a trivial problem, but it is not very obvious what settings/configurations need to be used to solve this issue.
Here are the Hello World program directory structure and the source code:
Directory Structure:
| -- HelloWorldProgram
| -- HelloWorld.ts
| -- index.ts
| -- package.json
| -- tsconfig.json
index.ts:
import {HelloWorld} from "./HelloWorld";
let world = new HelloWorld();
HelloWorld.ts:
export class HelloWorld {
constructor(){
console.log("Hello World!");
}
}
package.json:
{
"type": "module",
"scripts": {
"start": "tsc && node index.js"
}
}
Now, execution of the command tsc && node index.js
results in the following error:
internal/modules/run_main.js:54
internalBinding('errors').triggerUncaughtException(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'HelloWorld' imported from HelloWorld\index.js
Did you mean to import ../HelloWorld.js?
at finalizeResolution (internal/modules/esm/resolve.js:284:11)
at moduleResolve (internal/modules/esm/resolve.js:662:10)
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:752:11)
at Loader.resolve (internal/modules/esm/loader.js:97:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:50:40)
at link (internal/modules/esm/module_job.js:49:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
It is obvious that the problem seems to have been originated from the fact that in index.ts
Typescript file there is no .js
extension in the import statement (import {HelloWorld} from "./HelloWorld";
). Typescript didn't throw any error during compilation. However, during runtime Node (v14.4.0) wants the .js
extension.
Hope the context is clear.
Now, how to change the compiler output setting (tsconfig.json or any flags) so that local relative path imports such as import {HelloWorld} from ./Helloworld;
will get replaced by import {HelloWorld} from ./Helloworld.js;
during Typescript to Javascript compilation in the index.js
file?
Note:
It is possible to directly use the .js extension while importing inside typescript file. However, it doesn't help much while working with hundreds of old typescript modules, because then we have to go back and manually add .js extension. Rather than that for us better solution is to batch rename and remove all the .js extension from all the generated .js filenames at last.
import {HelloWorld} from "./HelloWorld.js";
TypeScript is clever enough to figure out what you want isHelloWorld.ts
during compilation. – Milieu.js
files but not clever enough to use the correct extension on compilation.. Okay then – Predigest