【问题标题】:Typescript compiler is forgetting to add file extensions to ES6 module imports?Typescript 编译器忘记为 ES6 模块导入添加文件扩展名?
【发布时间】:2017-12-12 07:04:45
【问题描述】:

我正在尝试使用 ES6 模块解析将 Typescript 项目编译为 JS,但似乎有些不对劲。

我的 tsconfig.json 看起来像这样:

{
    "compilerOptions": {
    "module": "es6",
    "target": "es6",
    "sourceMap": true,
    "lib": ["es6"]
  }
}

我用两个模块构建了一个简单的测试用例。第一个模块 (module1.ts) 只是导出一个常量:

export const testText = "It works!";

第二个模块 (main.ts) 只是从第一个模块导入导出:

import { testText } from 'module1';
alert(testText);

第二个模块的输出文件 (main.js) 包含在我的 index.html 中,type="module"-Attribute:

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

当我使用 Firefox(dom.moduleScripts.enabled 在 about:config 中设置)和 Chrome Canary(设置了实验性 Web 平台标志)进行测试时。在这两种情况下都不起作用。

Typescript 编译器似乎将 TS import { testText } from 'module1'; 语句转换为 JS 语句 import { testText } from 'module1';。 (注:两者完全相同)

正确的 ES6 导入语句应该是: import { testText } from 'module1.js'; (注意 .js 文件扩展名) 如果我手动将文件扩展名添加到生成的代码中,它就可以工作。

是我做错了什么还是 Typescript "module": "es6" 设置无法正常工作? 有没有办法配置 tsc 以将 .js 文件扩展名添加到生成的导入语句中?

【问题讨论】:

  • 我正在解决同样的问题。导入*.js 文件是一个很好的解决方法,但后来我在 IDE 中重构(使用 CLion)和去声明、定义等时遇到了问题。所以我切换回没有*.js 扩展名的导入,实际上我正在使用 SystemJS 进行转译ES6 JavaScript(作为开发过程中的临时解决方案)。我找到了有关使用 TypeScript 编译器 API 的信息。为这种情况考虑“自定义”构建工具,但实际上我很忙。如果有人有一些想法、笔记或有类似的东西

标签: javascript typescript ecmascript-6 es6-modules


【解决方案1】:

这是bug in TypeScript

短期内您可以通过指定输出文件来解决它:

main.ts 中指定.js 扩展名和路径:

import { testText } from './module1.js';
alert(testText);

这将正确选择module.ts,但输出时包含.js 扩展名。

请注意,您还需要在本地文件前加上 ./ 作为“裸”模块名称的前缀,以供将来使用。

【讨论】:

  • 对于这种糟糕的 TS 错误的真正聪明的解决方法 ;) 谢谢。
  • github.com/microsoft/TypeScript/issues/40878 因“按预期工作”而关闭。所以这是一个错误而不是一个错误?
  • 好答案,只是想提一下 baseUrl 属性已作为 tsconfig 选项添加到 typescript v3.5 中。如果将其设置为所有打字稿源文件的根目录,则可以从本地导入中省略 ./
  • @MuhammedAydogan - 不幸的是,更新是 TypeScript 团队认为这“按预期工作”并且不会改变行为。
  • 另外,如果你错过了 .js 后缀,代码仍然可以编译,所以你会遇到运行时失败,至少可以说这不是很好。
【解决方案2】:

基思回答正确。

在你的 main.ts 中

而不是

import { testText } from 'module1';

试试下面的

import { testText } from 'module1.js';

在我的情况下,vscode intellisense 有效 + 我也得到了所需的输出文件 main.js。

【讨论】:

    【解决方案3】:

    这是弹出的更新的解决方案:

    This TypeScript issue 在此线程的另一个答案中提到。答案的作者写道,这是一个错误,但如果你阅读了这个帖子,有些人认为它不是。我个人将其解释为与 ES6 不兼容,考虑到它是一个转译器,IMO 会使其成为一个错误。无论哪种方式,它都是一个令人讨厌的问题。自从首次编写 OP 以来,GitHub 问题(现已关闭)中包含了更多有用的 cmets。在问题的最后,我找到了一个解决方案,可以像人们对 ES6 模块所期望的那样解决路径,而且我个人认为这是迄今为止最好的解决方案。我将标志写为下面的标题。这是在 2021 年 11 月(目前是 2022 年 1 月)提出的,在撰写本文时,这是最好的选择,或者至少我认为是这样。


    node --es-module-specifier-resolution=node


    注意:这对我来说很明显,但以防万一其他人不是这样:上面是使用 node 运行文件时使用的标志。

    【讨论】:

      猜你喜欢
      • 2020-10-18
      • 2018-03-08
      • 1970-01-01
      • 2015-12-24
      • 2015-08-13
      • 1970-01-01
      • 2020-04-03
      • 2013-01-18
      • 1970-01-01
      相关资源
      最近更新 更多