Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

javascript - How to make TypeScript output valid ES6 module import statements?

All major browsers have supported ES6 modules for some time.

These differ from many of the server-side approaches in that they need to specify the exact file to import from - they can't use file discovery.

This makes sense - in Node applications or bundlers like WebPack they only really need the name of the module, and then can spend a bit of extra time discovering the specific file that holds the code. On the web that could be a lot of wasted round trips (is 'library' in library/index.js, or library/library.js, or library.js? require() doesn't care but on the web we have to).

TypeScript has ES6 modules support (set "module": "es6" in tsconfig.json) but it appears to be using 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 is unchanged when transpiles - the TS output still has the 'library' name for file discovery, which doesn't work. This throws an error because 'library' isn't found:

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

In order for ES6 modules to work the TS output needs to reference the specific file:

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

How do I make TS output valid ES6 module import statements?

Note: I am not asking how to make a bundler join the TS output into a single file. I specifically want to load these files individually using <script type="module">

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is a bug in TypeScript, though there's some debate about whether it should be fixed.

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

So in app.ts:

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

This then outputs correctly in app.js, and TS has found the import definitions and bindings correctly.

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

That last case might be desirable if you're joining those files together into a library.js output, but to do that you're going to be looking at either lots of nested tsconfig.json files (messy) or possibly the pre-transpiled output of another library.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...