You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript、Webpack、Jasmine环境下ES模块import扩展名兼容问题

背景

我有一组可在个人项目中复用的公共包,开发结构基本一致。

生产环境中,这些包都用TypeScript编写,发布到npm前会通过tsc编译为JavaScript,方便在其他项目中安装使用,同时我使用Jasmine运行包的测试用例。
开发环境中,我使用Webpack搭配ts-loader编译TypeScript,用于运行浏览器端的示例脚本。我在消费这些公共包的项目中通常也会用Webpack,由于包发布前已经完成编译,这些项目只会识别JavaScript代码,不需要用到ts-loader。

我全链路都使用ES module语法,不需要在Node的CommonJS和浏览器的ES模块语法之间切换,使用体验统一。为了在Jasmine中支持该语法,我在jasmine.json配置文件中设置了"jsLoader": "import"。

目前我遇到了import语句的写法问题:如何指定文件扩展名,才能适配包开发过程中的所有使用场景。


不写文件扩展名

TypeScript的Node模块解析规则对文件扩展名有一套实用的默认处理逻辑:

TypeScript会模拟Node.js运行时的解析策略,在编译时定位模块的定义文件。为了实现该能力,TypeScript会在Node的解析逻辑之上叠加TypeScript源文件扩展名(.ts、.tsx和.d.ts)的识别。

这意味着如果我写import { foo } from './foo';这类代码,TypeScript会自动查找名为foo.ts的文件。
同理,Webpack的resolve配置对象支持通过extensions属性指定一组文件扩展名,告诉Webpack如何解析不带扩展名的导入语句。我的配置是extensions: ['.js', '.ts'],因此可以和TypeScript一样正确找到foo.ts文件。

但当我尝试在Jasmine中运行测试时,不带扩展名的import语句无法完成模块解析。

C:\Users\mark.hanna\Documents\Code Playground\analyser>npm test

> analyser@0.1.0 test C:\Users\mark.hanna\Documents\Code Playground\analyser
> tsc && jasmine

Error: While loading C:/Users/mark.hanna/Documents/Code Playground/analyser/spec/analyser.spec.js: NodeError: Cannot find module 'C:\Users\mark.hanna\Documents\Code Playground\analyser\dist\file-processing' imported from C:\Users\mark.hanna\Documents\Code Playground\analyser\dist\analyser.js
    at C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\loader.js:22:30
    at async Jasmine._loadFiles (C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\jasmine.js:182:5)
    at async Jasmine.loadSpecs (C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\jasmine.js:173:3)
    at async Jasmine.execute (C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\jasmine.js:479:3)
npm ERR! Test failed.  See above for more details.

使用.js扩展名

另一种方案是在import语句中指定.js文件扩展名,例如import { foo } from './foo.js'。
虽然我没有找到明确的官方文档,但TypeScript的模块解析逻辑确实能够识别./foo.js实际对应./foo.ts,相关资料显示该能力从TypeScript 2版本开始支持。

这意味着我指定.js扩展名后,仍然可以通过tsc正常编译代码,Jasmine测试也可以正常运行,因为带扩展名的导入语句符合它的模块解析规则。
但Webpack无法识别./foo.js可能对应./foo.ts,因此使用该方案时,我无法在包内将代码导入到浏览器示例脚本中完成构建。

ERROR in ./src/file-processing.ts 2:0-49
Module not found: Error: Can't resolve './AnalyserRows.js' in 'C:\Users\mark.hanna\Documents\Code Playground\analyser\src'
resolve './AnalyserRows.js' in 'C:\Users\mark.hanna\Documents\Code Playground\analyser\src'
  using description file: C:\Users\mark.hanna\Documents\Code Playground\analyser\package.json (relative path: ./src)
    Field 'browser' doesn't contain a valid alias configuration
    using description file: C:\Users\mark.hanna\Documents\Code Playground\analyser\package.json (relative path: ./src/AnalyserRows.js)
      no extension
        Field 'browser' doesn't contain a valid alias configuration
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js doesn't exist
      .js
        Field 'browser' doesn't contain a valid alias configuration
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js.js doesn't exist
      .ts
        Field 'browser' doesn't contain a valid alias configuration
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js.ts doesn't exist
      as directory
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js doesn't exist
 @ ./src/analyser.ts 4:0-48 69:0-50
 @ ./docs/assets/js/src/docs-script.ts 2:0-53 7:14-36 34:14-36 43:14-36 48:51-68 49:28-45

搭配Webpack别名使用.js扩展名

目前我找到的唯一可用但并不满意的解决方案,是通过Webpack的resolve.alias配置,显式告诉Webpack./foo.js实际对应./foo.ts。
比如我目前在@cipscis/csv项目中使用了该方案:

resolve: {
        extensions: ['.js', '.ts'],
        alias: {
            '@cipscis/csv': `${srcPath}/csv.ts`,
            './stringify.js': './stringify.ts',
            './parse.js': './parse.ts',
        },
    },

但该方案非常笨重,我需要为每一个导入的文件单独配置别名,完全不具备可扩展性。是否存在更合理的标准解决方案?


内容的提问来源于stack exchange,提问作者Brooke Hart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 23:27:04