繁体   English   中英

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

[英]How to make TypeScript output valid ES6 module import statements?

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

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

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

TypeScript支持ES6模块(在tsconfig.json设置"module": "es6" )但似乎是使用文件发现方法...

假设我有library.ts

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

然后在app.ts

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

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

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

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

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

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

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

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

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

所以在app.ts

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

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

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

如果你将这些文件一起加入到library.js输出中,那么最后一种情况可能是可取的,但要做到这一点,你将会看到许多嵌套的tsconfig.json文件(凌乱)或者可能是预先编译的另一个库的输出。

编译器采用模块类标志:

--module ES2015

而且你还需要针对ECMAScript 6/2015 ...

--target ES2015

您需要将模块类型和编译目标都作为ECMAScript 2015最小值来进行“零转换导入”。

您的import语句应该看起来在两个示例之间:

import {myFunction} from './library';

补充笔记

关于模块解析仍然有很多讨论...有TC39规范WHATWG规范 - 加上节点目前仍然没有文件扩展...看起来像RequireJS可能比我们想象的更长寿。 。 请参见:

用于在导入转换期间支持文件扩展名的TypeScript线程 (即它是否会添加文件扩展名?)。

建议

坚持使用模块加载器,例如RequireJS或SystemJS。 这也意味着您可以分别使用UMD或系统模块类型在浏览器和服务器之间共享您的模块。

显然,一旦ECMAScript讨论得出结论,这将需要重新审视。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM