5

I have decided to migrate my js project into ts, however I am faced with the following problem: all imports in ts files are missing the .js extension in the compiled js files. This in turn raises the following error: Loading failed for the module with source “http://localhost:5500/build/test/first”. on my browser console. Here is the code

/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script src="/build/test/last.js" type="module"></script>
</html>

/src/test/first.ts

export class First {
    name: string;

    constructor(name: string) {
        this.name = name
    }
}

/src/test/last.ts

import {First} from "./first"
class Last {

    constructor() {
        let name = new First("this is my name").name;
        console.log(name)
    }
}

new Last();

/build/test/first.js

export class First {
    constructor(name) {
        this.name = name;
    }
}

/build/test/last.js

import { First } from "./first";
class Last {
    constructor() {
        let name = new First("this is my name").name;
        console.log(name);
    }
}

Notice that in last.js, the import is missing a .js extension and if I manually add the missing extension every thing works as expected. And finally here is my ts config

{
    "compilerOptions": {
        "target": "ESNext",
        "lib": ["DOM","ES2017", "DOM.Iterable", "ScriptHost"],
        "watch": true,
        "rootDir": "./src", 
        "outDir": "./build",
        "sourceMap": true,
        "removeComments": true,
        "noEmitOnError": true,
        "strict": true,
    }
}

Is there something I am missing that is not adding the right extension on the imports? If so, please tell me what I am doing wrong. Thanks.

Astonvish32
  • 179
  • 2
  • 11
  • 1
    Does this answer your question? [Appending .js extension on relative import statements during Typescript compilation (ES6 modules)](https://stackoverflow.com/questions/62619058/appending-js-extension-on-relative-import-statements-during-typescript-compilat) – Jörg W Mittag Sep 12 '20 at 06:56

1 Answers1

-6

Is there something I am missing that is not adding the right extension on the imports?

Why would TypeScript randomly change your imports? You told it to import a module named ./first and it correctly compiled that to a an import for a module named ./first.

If you want to import a different module, you need to tell TypeScript to import a different module.

So, if you don't want to import a module named ./first but instead want to import a module named ./first.js, you need to tell TypeScript to import a module named ./first.js, not a module named ./first:

import {First} from "./first.js"
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • Thank you for the explanation! And yes this solves the problem. I believe the confusion arose when I read the docs (https://www.typescriptlang.org/docs/handbook/modules.html) and it was not mentioned that the import must end with .js in the ts file. In fact all of their example on module does not have any extension on ts import. Many thanks! – Astonvish32 Jun 04 '20 at 09:15
  • 1
    "it was not mentioned that the import must end with .js in the ts file" – It is perfectly fine to have an import *not* end in `.js`. The import simply needs to be the thing that you want to import. It is really that simple. If you want to import the module named `./first`, then you write `from "./first"`, and if you want to import the module named `./first.js`, then you write `from "./first.js"`. TypeScript can't read your mind, it will simply import the module you tell it to import, no more, no less. – Jörg W Mittag Jun 04 '20 at 09:35
  • 2
    In my own project, I want to import a module named `./config`, so obviously, I am importing `./config` and not `./config.js`. In fact, in my project, there *is no* `./config.js`, so that wouldn't even work. – Jörg W Mittag Jun 04 '20 at 09:35
  • Thanks for the additional explanation. – Astonvish32 Jun 05 '20 at 11:30
  • This breaks things when using jest for testing. It doesn't let you use "./first.js" instead of "./first.ts" – Adam D Nov 25 '20 at 13:24
  • 8
    The OPs question is reasonable and does not deserve -1. They started with two linked TS modules (where .ts extension in import is implied) and compiled them to two JS modules. The TS compiler should preserve the link between the generated JS modules, which requires it to add the .js extension to the import. – Adam Gawne-Cain Mar 14 '22 at 06:41