20
votes

I am trying to compile a Typescript project to JS with ES6 module resolution, but something seems not right.

My tsconfig.json looks like this:

{
    "compilerOptions": {
    "module": "es6",
    "target": "es6",
    "sourceMap": true,
    "lib": ["es6"]
  }
}

I build a simple test case with just two modules. The first module (module1.ts) just exports a constant:

export const testText = "It works!";

The second module (main.ts) just imports the export from the first module:

import { testText } from 'module1';
alert(testText);

The output file of the second module (main.js) is included in my index.html with the type="module"-Attribute:

<script src="main.js" type="module"></script>

When I test this with either Firefox (dom.moduleScripts.enabled is set in about:config) and Chrome Canary (Experimental Web Platform flag is set). In both cases it doesn't work.

The Typescript compiler seems to transpile the TS import { testText } from 'module1';-statement to the JS statement import { testText } from 'module1';. (Note: both are exactly the same)

The correct ES6 import-statement would be: import { testText } from 'module1.js'; (Note the .js file extension) If I manually add the file extension to the generated code, it works.

Did I do something wrong or does the Typescript "module": "es6" setting just not work correctly? Is there a way to configure the tsc in such a way that .js file extensions are added to the generated import statements?

2
I am solving same issue. Importing *.js file is nice work around, but then I had issues with refactoring in IDE (using CLion) and going to declaration, definition etc. So I switched back to importing without *.js extension and actually I am using SystemJS to transpile ES6 JavaScript (as temporary solution during development). I've found information about using TypeScript compiler API. Thinking of "custom" build tool for this situation, but actually I am quite busy. If anyone has some ideas, notes or has something like tMartin

2 Answers

12
votes

This is a bug in TypeScript.

In the short term you can work around it by specifying the output file:

in main.ts specify the .js extension and path:

import { testText } from './module1.js';
alert(testText);

This will pick up module.ts correctly, but output with the .js extension included.

Note that you also need to prefix local files with ./ as 'bare' module names are reserved for future use.

0
votes

Keith answered it correctly.

In your main.ts

instead of

import { testText } from 'module1';

try the following

import { testText } from 'module1.js';

In my case vscode intellisense works + I get the desired output file main.js as well.