使用 tsc 转译动态导入?

Hit*_*sro 2 javascript dynamic-import transpiler typescript tsc

我\xe2\x80\x99 已经使用 Typescript 一段时间了。我们在前端 Web 组件中使用本地化,并且我们有自己的实现。

\n

因此,我们有一个翻译文件夹,其中包含所有以翻译作为键值对的语言环境文件。

\n

我们使用区域设置文件根据用户从浏览器中选择的语言加载翻译文件。

\n

我们通过动态导入来加载语言环境:

\n
{\n  'component': locale => import(`./translations/${locale}.ts`),\n},\n
Run Code Online (Sandbox Code Playgroud)\n

虽然当我们使用扩展时一切正常,.js但当我们使用 时.tstsc无法转译这部分代码。

\n

我希望构建是这样的:

\n
{\n  'component': locale => import(`./translations/${locale}.js`),\n},\n
Run Code Online (Sandbox Code Playgroud)\n

有人知道这是为什么吗?

\n

0xt*_*xts 7

太长了;

\n

不可能使用.ts扩展名并让 Typescript 编译器将其更改为.js,因为 Typescript 编译器本身从不修改模块说明符(即模块的路径)。.js因此,如果您正在使用,则必须提供扩展tsc,否则,如果您确实需要使用它,则需要使用WebpackVite等捆绑器来捆绑您的代码,然后将其转译为JavaScript。

\n

Typescript 中的 ESM

\n

ESM(ECMAScript 模块)在高于 的 Node 版本中可用12.0.0,需要在导入 ESM 模块时指定扩展名。如果您在浏览器中使用它们,情况也是如此。所以,我们需要添加一个.js扩展。

\n

ESM 模块的 Typescript 文档本身指定使用.js扩展来获取正确的运行时文件作为使用 ESM 导入的规则。引用 Typescript ESM 文档 -

\n
\n

相对导入路径需要完整扩展(例如我们必须编写 import./foo.js而不是 import ./foo

\n
\n

之所以会出现这种情况,是因为 Typescript 编译器永远不会更改模块说明符。引用 Typescript ESM 文档 -

\n
\n

.ts文件被编译为 ES 模块时,ECMAScript 导入/导出语法将单独保留在输出.js

\n
\n

这就是编译时它没有改变的原因。

\n

现状

\n

针对由此产生的问题,在 GitHub 上创建了许多问题并寻求支持 -

\n\n

直到出现此提案并使用此 PR 的moduleResolution新选项更新该选项,该 PR 明确指定 -bundler

\n
\n

谁应该使用此模式?

\n
\n
    \n
  • \xe2\x9c\x85 在运行时使用该捆绑包之前对其 TS 或 JS 文件使用捆绑器的应用程序作者
  • \n
  • \xe2\x9c\x85 在 Bun 中运行的应用程序作者
  • \n
  • \xe2\x9c\x85 使用捆绑器部署 UMD 捆绑包的库作者
  • \n
  • \xe2\x9a\xa0\xef\xb8\x8f 使用 Rollup 等工具以不同模块格式部署多个构建的库作者\xe2\x80\x94 听取构建工具的建议
  • \n
  • 任何想要使用 tsc 生成可在 Node 或浏览器中运行而无需进一步捆绑或处理的模块的人
  • \n
  • 任何想要使用 tsc 生成将在 Deno 中运行而无需进一步捆绑或处理的模块的人
  • \n
\n
\n

为什么?因为 Typescript 编译器本身永远不会修改模块说明符,并且需要依赖外部捆绑器来为您执行此操作。

\n

你能做什么?

\n

我想说的是,只要使用该.js扩展程序,除非您有充分的理由不使用它(我怀疑是否会有这样的理由)。否则,请在您的 中添加moduleResolutionwithbundler选项和noEmitwithtruetsconfig.json,以及allowImportingTsExtensions使用.ts扩展的选项并配置与其一起使用的捆绑程序。

\n