Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使TypeScript输出有效的ES6模块导入语句?_Javascript_Typescript_Es6 Modules - Fatal编程技术网

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

Javascript 如何使TypeScript输出有效的ES6模块导入语句?,javascript,typescript,es6-modules,Javascript,Typescript,Es6 Modules,已经支持ES6模块一段时间了 这些方法与许多服务器端方法的不同之处在于,它们需要指定要从中导入的确切文件—它们不能使用文件发现 这是有意义的——在节点应用程序或像WebPack这样的捆绑程序中,它们只需要模块的名称,然后就可以花费一些额外的时间来发现包含代码的特定文件。在web上,这可能会浪费很多往返时间(是library/index.js中的'library',还是library/library.js,或者library.js?require()不在乎,但在web上我们必须这样做) TypeS

已经支持ES6模块一段时间了

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

这是有意义的——在节点应用程序或像WebPack这样的捆绑程序中,它们只需要模块的名称,然后就可以花费一些额外的时间来发现包含代码的特定文件。在web上,这可能会浪费很多往返时间(是
library/index.js中的
'library'
,还是
library/library.js
,或者
library.js
require()
不在乎,但在web上我们必须这样做)

TypeScript支持ES6模块(在
tsconfig.json
中设置“模块”:“ES6”
),但它似乎使用了文件发现方法

假设我有
library.ts

export function myFunction(...) {  ... }
import {myFunction} from './library';
var x = myFunction(...);
import {myFunction} from './library.js';
var x = myFunction(...);
然后在
app.ts
中:

export function myFunction(...) {  ... }
import {myFunction} from './library';
var x = myFunction(...);
import {myFunction} from './library.js';
var x = myFunction(...);
但是,当传输文件时,这是不变的-TS输出仍然具有文件发现的
'library'
名称,这不起作用。这会引发错误,因为找不到
'library'

<script type="module" src="app.js"></script>
如何使TS输出有效的ES6模块
import
语句?


注意:我不是问如何使绑定器将TS输出连接到单个文件中。我特别想使用

单独加载这些文件。编译器采用模块种类标志:

--module ES2015
您还需要针对ECMAScript 6/2015

--target ES2015
您需要将模块种类和编译目标都设置为ECMAScript 2015最小值,以实现“零转换导入”

您的导入语句应该介于两个示例之间:

import {myFunction} from './library';
附加说明 显然,关于模块分辨率还有很多讨论。。。存在,并且-plus节点当前仍然没有文件扩展名。。。看来RequireJS的寿命可能比我们想象的要长。。。请参阅:

(即是否会添加文件扩展名?)

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

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

这是一个问题,尽管关于是否应该修复它还有一些争论

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

因此在
app.ts
中:

export function myFunction(...) {  ... }
import {myFunction} from './library';
var x = myFunction(...);
import {myFunction} from './library.js';
var x = myFunction(...);
然后在
app.js
中正确输出,TS已正确找到
import
定义和绑定

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


如果您要将这些文件合并到
library.js
输出中,最后一种情况可能是可取的,但要做到这一点,您需要查看大量嵌套的
tsconfig.json
文件(凌乱),或者可能是另一个库的预传输输出和
…来自“/library.js”是两个不同的东西,第一个是命名包,第二个是到module@MaximKoretskyi是-命名包有一个入口点,该入口点必须是模块导入的显式相对或绝对路径。web无法使用包名。如果使用命名包导入,TS无法输出相对路径,因为库与导入模块不在同一目录中,对吗?@MaximKoretskyi没关系,路径在任何情况下都不起作用
/library
失败,
。/src/utils/library
失败,
https://example.com/cdn/library
失败。何时失败?在浏览器中?这稍微好一点,但不起作用。在一个支持的浏览器(比如说金丝雀)中尝试一下,你会得到一个404作为不存在的文件“library”。TS输出需要指定符合ES6模块规范的文件,因此
从“/library.js”导入{myFunction}
“不需要
.js
扩展名”-这取决于具体情况。@Bergi这正是我的观点。在ES6模块规范中,几乎所有需要
.js
的主流浏览器都将实现该规范。如果启用ES6模块(通过命令行上的
--module ES2015
,或通过配置中的
“module”:“ES6”
),则TS会将
library.TS
传输到
library.js
,这样编译工具就可以准确地知道特定的文件,而浏览器则不会,我不认为transpiler知道弄乱模块名称。不-我不认为我们同意这一点。我在许多库/框架上工作,这些库/框架不是专门针对节点或浏览器的,因此我编写ES风格的导入,并让TypeScript使用UMD标志对它们进行传输。这允许我将库打包为
.js
+'.d.ts`包,可以在浏览器中使用,也可以在节点上使用,而不仅仅是从其他TypeScript程序使用。我们希望能够独立于模块的运行位置编写模块。如果使用Visual Studio代码,则可以将其配置为在自动导入模块时自动添加.js结尾。转到设置,然后在搜索字段中键入“模块说明符”。您可以找到选项“typescript>Preferences:Import Module Specifier Ending”,您可以将其设置为“.js”。