How to make TypeScript output valid ES6 module import statements?

Switching to all major browsers will soon be ES6 modules.

They differ from many server-side approaches in that they need to specify the exact file to import - they cannot use file detection.

This makes sense - in applications or Node bundles such as WebPack, they really only need a module name, and then they can spend a little extra time finding a specific file containing the code. On the Internet, where there can be many empty trips (the 'library' in library/index.js , or library/library.js , or library.js ? library.js require() doesn’t care, but on the Internet we have to).

TypeScript has support for ES6 modules (install "module": "es6" in tsconfig.json ), but it seems to use a file discovery approach ...

Suppose I have library.ts :

 export function myFunction(...) { ... } 

Then in app.ts :

 import {myFunction} from './library'; var x = myFunction(...); 

However, this does not change when transpiles - the TS output is still named 'library' for detecting files that do not work. This causes an error because the 'library' not found:

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

In order for ES6 modules to work, TS output must reference a specific file:

 import {myFunction} from './library.js'; var x = myFunction(...); 

How to make TS output valid ES6 import module instructions?

Note. I do not ask how to make the connector connect to the TS output in a single file. I specifically want to download these files individually using <script type="module">

+5
source share
2 answers

This is a mistake in TypeScript , although there is some debate about whether to fix it.

There is a workaround: while TS will not let you specify the .ts file as the source of the module, it will let you specify the .js extension (and then ignore it).

So in app.ts :

 import {myFunction} from './library.js'; var x = myFunction(...); 

This is then correctly displayed in app.js , and TS correctly finds import definitions and bindings.

This has one advantage / gotcha to be aware of / caution: TS simply ignores the .js extension and loads the rest of the path with the usual file detection. This means that it will import library.ts , but will also find definition files like library.d.ts or import files into the library/ folder.

This last case may be desirable if you attach these files together to the output of library.js , but for this you will either look for many attached files tsconfig.json (messy), or perhaps the pre-transpiled output of another library.

+2
source

The compiler accepts a module type flag:

 --module ES2015 

And you will also need to focus on ECMAScript 6/2015 ...

 --target ES2015 

You need both a module type and a compilation goal so that at least ECMAScript 2015 has an “import zero transformation”.

Your import statements should look halfway between two examples:

 import {myFunction} from './library'; 

Additional notes

Modular resolution is still clearly discussed ... there is the TC39 specification , and the WHATWG specification - plus Node is currently still without files ... it looks like RequireJS can live longer than we all thought ... see below :

TypeScript stream to support file extensions when importing transpilation (i.e. will it add a file extension?).

Recommendation

Stick to a module loader like RequireJS or SystemJS. It also means that your modules can be shared between the browser and server using the UMD or system module types.

Obviously, after a discussion in ECMAScript, this will require revision.

+2
source

Source: https://habr.com/ru/post/1271314/


All Articles