带有文件扩展名的 TypeScript 模块的 Visual Studio 2022 构建错误

问题描述 投票:0回答:2

我正在重建我的 Gulp 实现,以使用最新版本的 Rollup 将 TypeScript 文件编译、缩小和压缩成一个包。新的实现已经完成并且可以正常工作,我可以从 Task Runner 或使用 Gulp 的文件系统观察器触发它,它完全按照我的需要去做。

我遇到的问题是,为了让 Rollup 看到模块导入,我不得不将“.ts”扩展名附加到导入中:

import { something } from "./Module.ts";

导致 Visual Studio 报错的原因:

TS2691:(TS)导入路径不能以“.ts”扩展名结尾。考虑改为导入“./Module.js”。

TypeScript 编译器似乎忽略了错误,因为当我运行 Gulp 任务时,它会按预期编译 TypeScript 文件。阅读有关“.ts”扩展名的 GitHub 讨论,最新版本的 TypeScript 的推荐解决方案似乎是向

tsconfig.json
文件添加几个属性:

{
  "allowImportingTsExtensions": true,
  "moduleResolution": "bundler",
  "noEmit": true
}

这导致 Visual Studio 给出更多错误:

(TS) 未知的编译器选项“allowImportingTsExtensions”。

(TS) '--moduleResolution' 选项的参数必须是:'node'、'classic'、'node16'、'nodenext'。

所有这些最终导致我根本无法构建项目。现在,我只是在一个实验项目中,在弄清楚新的 Gulp 实现后我将放弃,但如果我将这些更改应用到我的实际项目中,那么我将永远无法编译它们。

我需要做什么来解决这些错误?我尝试在项目属性中抑制 TS2691,但没有效果。我还尝试从 NuGet TypeScript 包切换到 npm TypeScript 包,但也没有效果。作为参考,我使用的是 Visual Studio 2022、TypeScript 4.9.5 和 Rollup 3.17.3.

typescript visual-studio gulp visual-studio-2022
2个回答
1
投票

如果您使用的是现代捆绑器,请删除

allowImportingTsExtensions
,将
moduleResolution
设置为
"node"
,并将文件扩展名从导入中删除。现代捆绑器了解文件扩展名不存在。


如果您没有使用捆绑器,答案将是(在我看来很奇怪)您必须在您的

.js
语句中使用
import
,即使您的源文件是
.ts
文件。那是因为 TypeScript 不会重写模块说明符(作为 policy decision)。所以如果你有
index.ts
mod.ts
导入,你必须写
import { something } from "./mod.js";
这样它就像在编译器生成的 JavaScript 中一样,浏览器可以正确处理它。


0
投票

TypeScript 5 发布后的更新

TypeScript 5 发布后,我决定尝试一个没有作弊的干净解决方案,现在它按预期工作。我必须在 tsconfig.json 中设置以下内容:

{
  "compilerOptions": {
    "allowImportingTsExtensions": true,
    "moduleResolution": "bundler"
  }
}

我还删除了

gulp-replace
并将 gulp 任务减少为:

gulp.task(taskTsRollup, () => rollup.rollup({
    input: inputTs,
    plugins: [
        rollupTypeScript,
        rollupTerser()
    ]
}).then(
    _ => _.write({
        file: targetJs,
        format: "iife",
        sourcemap: false
    })));

宣布 TypeScript 5.0 帖子中的更多信息。


最后我绕过了它。由于 Rollup 想要扩展而 TypeScript 不想要扩展,我决定给他们两个他们需要的东西。

为此,我首先有一个复制输入文件的 gulp 任务,因此从

Default.ts
Default.ts-copy
。然后使用
gulp-replace
我使用正则表达式匹配导入模式并重写值以包含扩展名。然后将复制和修改后的文件传递给 Rollup,它就完成了,最后我删除了复制文件。

这样我就可以让 TypeScript 对没有扩展感到满意,而 Rollup 会得到一个带有扩展的修改后的文件。都很开心。这是最后的 Gulp 任务:

gulp.task(taskTsRollup, gulp.series(
    () => gulp
        .src(inputTs)
        .pipe(gulpRename(`${inputTs}-copy`))
        .pipe(gulpReplace(/from\s+\".\/([a-zA-Z0-9_-]+)\"\;/g, "from \".\/$1.ts\";"))
        .pipe(gulp.dest(`${rootResources}/Scripts`)),
    () => rollup.rollup({
        input: `${inputTs}-copy`,
        plugins: [
            rollupTypeScript,
            rollupTerser()
        ]
    }).then(
        _ => _.write({
            file: targetJs,
            format: "iife",
            sourcemap: false
        })),
    () => del([
        `${rootResources}/Scripts/${inputTs}-copy`
    ])
));

也许未来 TypeScript 语言服务会跟随编译器的脚步,支持所有的配置选项。

© www.soinside.com 2019 - 2024. All rights reserved.