具有文件扩展名的TypeScript模块的Visual Studio 2022生成错误

wxclj1h5  于 2023-03-04  发布在  TypeScript
关注(0)|答案(2)|浏览(1897)

我正在使用最新版本的Rollup重新构建我的Gulp实现,以便将TypeScript文件编译、缩小和压缩到一个包中。新的实现已经完成并正在工作,我可以从任务运行器或使用Gulp的文件系统监视器触发它,它完全按照我的需要工作。
我遇到的问题是,为了让Rollup看到模块导入,我不得不在导入后附加.ts扩展名:

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

导致Visual Studio给予此错误:
TS 2691:(TS)导入路径不能以.“ts”扩展名结尾。请考虑改为导入.“/Module.js”。
TypeScript编译器似乎忽略了这个错误,因为当我运行Gulp任务时,它会按照预期编译TypeScript文件。阅读GitHub关于.ts扩展名的讨论,最新版本的TypeScript的推荐解决方案似乎是在tsconfig.json文件中添加一些属性:

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

这导致Visual Studio给予更多错误:
(TS)未知的编译器选项“allowImportingTsExtensions”。
(TS)“--moduleResolution”选项的参数必须为:“节点”、“经典”、“节点16”、“节点下一个”。
所有这些最终导致我根本无法构建这个项目。现在,我只是在一个实验项目中,我打算在弄清楚新的Gulp实现后扔掉它,但如果我将这些更改应用到我的真实的项目中,那么我将永远无法编译它们。
我需要做什么来解决这些错误?我尝试在项目属性中取消TS 2691,但没有效果。我还尝试从NuGet TypeScript包切换到npm TypeScript包,也没有效果。作为参考,我使用的是Visual Studio 2022、TypeScript 4.9.5和Rollup 3.17.3。

km0tfn4u

km0tfn4u1#

如果你使用的是现代的捆绑包,删除allowImportingTsExtensions,将moduleResolution设置为"node",并在导入时保留文件扩展名。
如果你不用打包机,答案就是(在我看来很奇怪),即使源文件是.ts文件,您也必须在import语句中使用.js。因此,如果您要从mod.ts导入index.ts,则必须编写import { something } from "./mod.js";,使其与编译器生成的JavaScript中的import { something } from "./mod.js";类似,并且浏览器可以正确处理它。

4ktjp1zp

4ktjp1zp2#

最后我用自己的方法解决了这个问题,因为Rollup想要这个扩展,而TypeScript不想要这个扩展,所以我决定给予他们两个他们需要的东西。
为了做到这一点,我首先有一个gulp任务,复制输入文件,从Default.tsDefault.ts-copy。然后使用gulp-replace,我使用正则表达式匹配导入模式,并重写值以包括扩展名。然后复制和修改的文件传递给Rollup,它做它的事情,最后我删除复制文件。
这样我就可以让TypeScript高兴地看到没有扩展名,Rollup也会收到一个带有扩展名的修改过的文件,所有人都很高兴。

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语言服务会跟随编译器的脚步,支持所有的配置选项。

相关问题