Typescript: cannot consume compiled js files targeted to browser

Created on 8 Oct 2019  路  7Comments  路  Source: microsoft/TypeScript

This has been reported here https://github.com/microsoft/TypeScript/issues/27287 but closed without being fixed.

Comment summarizing the issue:

I'm having the same problem, but succinctly, it's that when I compile

import {Foo} from "./module"

and target ES2015 or ESNext modules, it gets transpiled as:

import {Foo} from "./module"

Yes, exactly the same thing. Since I'm targeting javascript, it should be adding the .js on the end, but since it doesn't, any browser that supports modules gets a 404 back from the server, since the transpiled output is actually module.js.

Expected behavior:
Transpiled code should be
import {Foo} from "./module.js"

This prevents using TS packages in browsers (in modern development environment, without bundling and wepacking). Browsers expect import to point to the exact filename.

Working as Intended

Most helpful comment

Sorry to comment on a closed issue, but I have just encountered this problem myself.

The suggested solution to add the .js extension to imports in TS files does work but it's confusing and counter-intuitive.

Would it not be possible to add a moduleExtension option to the tsconfig.json file?

{
    "compilerOptions": {
        "module": "ES2020",
        "moduleExtension": "js" // or "mjs", or anything else a developer needs
    }
}

That seems like a sensible solution to this, and it would give developers the freedom they need on a per-project basis.

All 7 comments

This isn't ideal but I'll note for the record that you can add the .js manually and TS will recognize it, even if the source is actually .ts. The bigger issue is that automatically-added imports (added by the language service) don't include the extension, inevitably leading to this pain point.

TypeScript does not modify the module specifier. This is very intentional, because any modification would work for some, but not work for anyone, so TypeScript is avoiding getting into that fight.

I generally agree with that sentiment, too - however unlike with paths, there is currently no way to deal with differences in file extension handling at the compiler/tsconfig level.

If there were an option to have it so automatically-added imports included the .js extension (which TS already happily recognizes), I would be happy. Right now you can鈥檛 rely on auto-imports if you鈥檙e targeting ESM in the browser.

Probably we should have auto-import detect if the prevailing style of import in the file uses extensions or not, but rewriting the import path is not the correct solution.

rewriting the import path is not the correct solution.

Right, and I agree - I just think there should be an option to have auto-import add the.js extension, since there鈥檚 currently no way to deal with that mismatch today, on either side.

Sorry to comment on a closed issue, but I have just encountered this problem myself.

The suggested solution to add the .js extension to imports in TS files does work but it's confusing and counter-intuitive.

Would it not be possible to add a moduleExtension option to the tsconfig.json file?

{
    "compilerOptions": {
        "module": "ES2020",
        "moduleExtension": "js" // or "mjs", or anything else a developer needs
    }
}

That seems like a sensible solution to this, and it would give developers the freedom they need on a per-project basis.

I'm also running into this issue; I think it's plainly almost unimaginable that a simple .ts file using modules and targeting modern browsers and ES modules cannot be compiled to a working javascript file in the browser.

I'm using the workaround suggested above (using an explicit .js module reference in the typescript file, like "import {Foo} from './module.js' ", but this feels rather strange, although it works well in the browser.

Was this page helpful?
0 / 5 - 0 ratings