[英]How to make TypeScript output valid ES6 module import statements?
一段时间以来, 所有主流浏览器都支持ES6模块。
这些与许多服务器端方法的不同之处在于,它们需要指定要导入的确切文件 - 它们不能使用文件发现。
这是有道理的 - 在Node应用程序或像WebPack这样的捆绑器中,它们只需要模块的名称,然后可以花费一些额外的时间来发现保存代码的特定文件。 在网上可能是浪费了很多的往返(在library/index.js
'library'
,或者library/library.js
,或者library.js
? require()
并不关心,但在网络上我们必须)。
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.