这似乎是一个微不足道的问题,但不太清楚需要使用什么设置/配置来解决这个问题.

以下是Hello World程序目录 struct 和源代码:

目录 struct :

| -- HelloWorldProgram
     | -- HelloWorld.ts
     | -- index.ts
     | -- package.json
     | -- tsconfig.json

指数ts:

import {HelloWorld} from "./HelloWorld";

let world = new HelloWorld();

你好世界ts:

export class HelloWorld {
    constructor(){
        console.log("Hello World!");
    }
}

包裹json:

{
  "type": "module",
  "scripts": {
    "start": "tsc && node index.js"
  }
}

现在,执行命令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 moduleResolve (internal/modules/esm/resolve.js:662:10)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:752:11)
    at Loader.resolve (internal/modules/esm/loader.js:97:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:50:40)
    at link (internal/modules/esm/module_job.js:49:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

显然,这个问题似乎源于这样一个事实:在index.ts Typescript文件中,import语句(import {HelloWorld} from "./HelloWorld";)中没有.js扩展名.Typescript在编译过程中没有抛出任何错误.然而,在运行时 node (v14.4.0)想要.js扩展.

希望背景清楚.

现在,如何更改编译器输出设置(tsconfig.json或任何标志),以便在index.js文件中的Typescript到Javascript编译期间,本地相对路径导入(如import {HelloWorld} from ./Helloworld;)将被import {HelloWorld} from ./Helloworld.js;替换?

注:

推荐答案

对于正在寻找此问题解决方案的开发人员,我们遇到的可能解决方法如下:

  1. 对于新文件,编辑时只需在Typescript文件的import语句中添加".js"扩展名即可.示例:import {HelloWorld} from "./HelloWorld.js";

  2. 如果使用旧项目,而不是遍历每个文件并更新导入语句,我们发现通过一个简单的自动化脚本,只需批量重命名并从生成的Javascript中删除".js"扩展名就更容易了.但是,请注意,这可能需要对服务器端代码进行微小的更改,以便为客户端提供具有适当MIME类型的扩展名小于".js"的文件.如果要避免这种情况,可以使用正则表达式来批量查找并递归替换导入语句,以添加.js扩展名.

Side note:

关于TS团队在解决这个问题上的失败,似乎有一种倾向,即试图断章取义地夸大这个问题,并将其与一些设计原则联系起来进行辩护.

然而,事实上,这只不过是一个关于compiler deals asymmetrically with the extension人如何生活的问题.Typescript编译器允许import语句不带扩展名.然后,在翻译文件时,它会继续向相应的输出文件名添加".js"扩展名,但对于引用该文件的相应导入语句,它会忽略在翻译过程中添加".js"扩展名的事实.这种不对称性如何能被断章取义的URI重写原则所捍卫?

在编译期间,Typescript文件和生成的Javascript输出文件之间存在固定的一一对应关系.如果引用的导入不存在,编译器将抛出错误.这些文件甚至无法编译!因此,断章取义或不可编译的例子提到了其他冲突URI的可能性,这些声明就无效了.

但是,这是否也违反了URI重写的设计原则?当然,在这种情况下,可能存在其他设计原则来捍卫这一立场!但是,这种固执是否只会进一步证实TS团队在这个问题上的坚定或无知?

Typescript相关问答推荐

在控制器中使用@ DeliverGuards时实现循环依赖项时未定义的依赖项

如何使用另一个类型的属性中的类型

如何在ts中使用函数重载推断参数类型

根据另一个成员推断类成员的类型

对于使用另一个对象键和值类型的对象使用TS Generics

如果存在ts—mock—imports,我们是否需要typescpt中的IoC容器

部分类型化非 struct 化对象参数

如何在typescript中设置对象分配时的键类型和值类型

通配符路径与每条路径一起显示

通过字符串索引访问对象';S的值时出现文字脚本错误

我可以使用TypeScrip从字符串词典/记录中填充强类型的环境对象吗?

带下拉菜单的Angular 响应式选项卡

路由链接始终返回到

AngularJS服务不会解析传入的Json响应到管道中的模型

为什么TypeScrip假定{...省略类型,缺少类型,...选取类型,添加&>}为省略类型,缺少类型?

如何在Angular /字体中访问API响应的子元素?

打字:注解`是字符串`而不是`布尔`?

如何在TypeScript中将元组与泛型一起使用?

为什么TS条件返回要求不明确的强制转换而不是精确的强制转换?

在类型{}上找不到带有string类型参数的索引签名 - TypeScript