如何使TypeScript输出有效的ES6模块导入语句?

Kei*_*ith 12 javascript typescript es6-modules

一段时间以来,所有主流浏览器都支持ES6模块.

这些与许多服务器端方法的不同之处在于,它们需要指定要导入的确切文件 - 它们不能使用文件发现.

这是有道理的 - 在Node应用程序或像WebPack这样的捆绑器中,它们只需要模块的名称,然后可以花费一些额外的时间来发现保存代码的特定文件.在网络上,可能是白白浪费了很多往返的(是'library'library/index.js,还是 library/library.js,还是library.jsrequire()不关心,但在网络上,我们必须).

打字稿有ES6模块的支持(设置"module": "es6"tsconfig.json),但它似乎是使用文件发现方法...

假设我有library.ts:

export function myFunction(...) {  ... }
Run Code Online (Sandbox Code Playgroud)

然后在app.ts:

import {myFunction} from './library';
var x = myFunction(...);
Run Code Online (Sandbox Code Playgroud)

但是,在转换时这没有改变 - TS输出仍然具有'library'文件发现的名称,这不起作用.这会抛出错误,因为'library'找不到:

<script type="module" src="app.js"></script>
Run Code Online (Sandbox Code Playgroud)

为了使ES6模块工作,TS输出需要引用特定文件:

import {myFunction} from './library.js';
var x = myFunction(...);
Run Code Online (Sandbox Code Playgroud)

如何使TS输出有效的ES6模块import语句?

注意:我不是问如何使捆绑器将TS输出连接到单个文件中.我特别想要使用单独加载这些文件<script type="module">

Kei*_*ith 11

这是TypeScript 中的一个错误,尽管关于是否应该修复它存在一些争论。

有一个解决方法:虽然 TS 不允许您将.ts文件指定为模块的源,但它可以让您指定.js扩展名(然后忽略它)。

所以在app.ts

import {myFunction} from './library.js';
var x = myFunction(...);
Run Code Online (Sandbox Code Playgroud)

然后在 中正确输出app.js,并且 TS 已import正确找到定义和绑定。

这有一个优点/需要注意/注意的问题:TS 只是忽略.js扩展名并使用通常的文件发现加载路径的其余部分。这意味着它将 import library.ts,但它也会library.d.tslibrary/文件夹中找到定义文件或导入文件。

如果您将这些文件连接到一个library.js输出中,那么最后一种情况可能是可取的,但要做到这一点,您将要查看大量嵌套tsconfig.json文件(杂乱无章)或可能是另一个库的预编译输出。