使用JavaScript+Jest测试Typescript项目(解决SyntaxError: Cannot use import statement outside a module问题)

TL;DR

  1. 安装依赖项npm install --save-dev ts-jest @types/jest

  2. 在某个路径下新建一个tsconfig.json(以<rootDir>/tests/tsconfig.json为例),内容为:

    {
    	// 原tsconfig.json路径
      "extends": "../tsconfig.json",
      "compilerOptions": {
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "allowJs": true,
        "checkJs": false
      }
    }
    
  3. 配置jest:

    {
    		transform: {
    		    '^.+.(ts|js)x?$': ['ts-jest', {
    		        tsconfig: '<rootDir>/tests/tsconfig.json',
    		    }],
    		},
    }
    

原理

首先,要让jest支持TypeScript(参考这里)。优先使用ts-jest的方法:

npm install --save-dev ts-jest @types/jest

在jest的配置里,设置:

transform: {
		// 这里数组的第二个元素是传给ts-jest的配置
    '^.+.tsx?$': ['ts-jest', {}],
},

这样,ts-jest就会把检测到的所有.ts或者.tsx的文件,用ts-jest先转换一遍。

但当我们偷懒想直接写js文件去测试ts项目的时候,总会遇到以下的错误:

SyntaxError: Cannot use import statement outside a module

原因为:

测试文件.js未经过转换,测试文件引用了.ts文件,.ts文件用了import → 报错

所以,我们不但要用ts-jest转换.ts.tsx文件,还要转换.js.jsx文件,因此jest的配置需要为:

transform: {
		// 这里数组的第二个元素是传给ts-jest的配置
		'^.+.(ts|js)x?$': ['ts-jest', {}],
},

但这样有时候还是会出错,这是为什么呢?

原因是ts-jest会调用你的tsconfig.json来进行ts到js的转换,但在某些tsconfig.json配置下,js文件会被当成纯js文件忽略掉,于是转了跟没转也没啥区别。

需要配置tsconfig.json使得ts和js可以混用:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "checkJs": false
  }
}

为了不污染项目本身的tsconfig.json,在测试目录里可以专门新建一个<rootDir>/tests/tsconfig.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "checkJs": false
  }
}

同时还需要修改ts-jest的配置:

transform: {
    '^.+.(ts|js)x?$': ['ts-jest', {
        tsconfig: '<rootDir>/tests/tsconfig.json',
    }],
},
posted @ 2025-02-08 16:28  milliele  阅读(254)  评论(0)    收藏  举报