这似乎是一个微不足道的问题,但需要使用什么设置/配置来解决这个问题并不是很明显。
下面是Hello World程序目录结构和源代码:
目录结构:
| -- HelloWorldProgram
| -- HelloWorld.ts
| -- index.ts
| -- package.json
| -- tsconfig.json
Run Code Online (Sandbox Code Playgroud)
索引.ts:
import {HelloWorld} from "./HelloWorld";
let world = new HelloWorld();
Run Code Online (Sandbox Code Playgroud)
HelloWorld.ts:
export class HelloWorld {
constructor(){
console.log("Hello World!");
}
}
Run Code Online (Sandbox Code Playgroud)
包.json:
{
"type": "module",
"scripts": {
"start": "tsc && node index.js"
}
}
Run Code Online (Sandbox Code Playgroud)
现在,执行该命令会 tsc && node index.js导致以下错误:
internal/modules/run_main.js:54
internalBinding('errors').triggerUncaughtException(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'HelloWorld' imported from HelloWorld\index.js
Did you mean to import ../HelloWorld.js?
at finalizeResolution (internal/modules/esm/resolve.js:284:11)
at …Run Code Online (Sandbox Code Playgroud) 一段时间以来,所有主流浏览器都支持ES6模块.
这些与许多服务器端方法的不同之处在于,它们需要指定要导入的确切文件 - 它们不能使用文件发现.
这是有道理的 - 在Node应用程序或像WebPack这样的捆绑器中,它们只需要模块的名称,然后可以花费一些额外的时间来发现保存代码的特定文件.在网络上,可能是白白浪费了很多往返的(是'library'的library/index.js,还是 library/library.js,还是library.js?require()不关心,但在网络上,我们必须).
打字稿有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">
我正在尝试使用ES6模块解析将一个Typescript项目编译为JS,但似乎有些不对劲.
我的tsconfig.json看起来像这样:
{
"compilerOptions": {
"module": "es6",
"target": "es6",
"sourceMap": true,
"lib": ["es6"]
}
}
Run Code Online (Sandbox Code Playgroud)
我用两个模块构建了一个简单的测试用例.第一个模块(module1.ts)只导出一个常量:
export const testText = "It works!";
Run Code Online (Sandbox Code Playgroud)
第二个模块(main.ts)只是从第一个模块导入导出:
import { testText } from 'module1';
alert(testText);
Run Code Online (Sandbox Code Playgroud)
第二个模块(main.js)的输出文件包含在我的index.html中,带有type="module"-Attribute:
<script src="main.js" type="module"></script>
Run Code Online (Sandbox Code Playgroud)
当我使用Firefox(dom.moduleScripts.enabled在about:config中设置)和Chrome Canary(实验Web平台标志设置)进行测试时.在这两种情况下它都不起作用.
Typescript编译器似乎将TS import { testText } from 'module1';语句转换为JS语句import { testText } from 'module1';.(注意:两者完全一样)
正确的ES6 import语句将是:(
import { testText } from 'module1.js';
注意.js文件扩展名)如果我手动将文件扩展名添加到生成的代码中,它就可以工作.
我做错了什么或者Typescript "module": "es6"设置不正常吗?有没有办法以这样的方式配置tsc:.js文件扩展名被添加到生成的import语句中?