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

使用Jest进行TypeScript单元测试时遇ReferenceError: exports is not defined

Jest测试报错ReferenceError: exports is not defined,指向aws-lambda的import语句

问题背景

执行npm run unit运行单元测试时,tests/unit/get.test.ts用例失败,报错信息如下:

ReferenceError: exports is not defined
错误指向代码行:import { APIGatewayProxyEvent, Context } from 'aws-lambda';

此前为解决Jest encountered an unexpected token问题,已将Jest配置为ESM模式,当前jest.config.ts和测试代码如下:

测试代码

import { describe, expect, it } from '@jest/globals';
import { APIGatewayProxyEvent, Context } from 'aws-lambda';
import { lambdaHandler } from '../../app/app';

describe('Unit test for test', () => {
    it('test', async () => {
        // 测试逻辑
        const res = lambdaHandler(event, context);
        expect(res).toEqual('test');
    });
});

Jest配置文件

// jest.config.ts
export default {
    preset: 'ts-jest/presets/default-esm',
    transform: {
        '^.+\\.ts?$': 'ts-jest',
    },
    clearMocks: true,
    collectCoverage: true,
    coverageDirectory: 'coverage',
    coverageProvider: 'v8',
    testMatch: ['**/tests/unit/*.test.ts'],
    testPathIgnorePatterns: ['cf/.aws-sam/build'],
    moduleNameMapper: {
        '^/opt/nodejs/dist/db(.*)$': '<rootDir>/../../nodeLayer/db/dist/db$1',
    },
};

问题原因

核心是ESM与CommonJS模块格式的兼容性冲突:

  • 你通过preset: 'ts-jest/presets/default-esm'让Jest以ESM模式运行,但aws-lambda官方包是基于CommonJS格式开发的(使用module.exports导出)
  • Jest在ESM模式下加载CommonJS模块时,内部模块处理逻辑会出现混淆,导致exports变量未定义的错误

解决方案

1. 完善Jest的ESM兼容配置

修改jest.config.ts,显式开启ts-jest的ESM支持,并指定扩展名处理规则:

export default {
    preset: 'ts-jest/presets/default-esm',
    transform: {
        '^.+\\.ts?$': ['ts-jest', {
            useESM: true // 强制ts-jest以ESM模式处理TypeScript文件
        }],
    },
    // 指定将.ts文件当作ESM处理
    extensionsToTreatAsEsm: ['.ts'],
    moduleFileExtensions: ['ts', 'js'],
    clearMocks: true,
    collectCoverage: true,
    coverageDirectory: 'coverage',
    coverageProvider: 'v8',
    testMatch: ['**/tests/unit/*.test.ts'],
    testPathIgnorePatterns: ['cf/.aws-sam/build'],
    moduleNameMapper: {
        '^/opt/nodejs/dist/db(.*)$': '<rootDir>/../../nodeLayer/db/dist/db$1',
    },
};

2. 对齐项目的模块格式配置

检查项目根目录的package.json:

  • 如果你的项目是ESM优先:确保存在"type": "module"字段
  • 如果项目以CommonJS为主:可以移除ESM预设,改用transformIgnorePatterns排除aws-lambda等第三方包的转换(避免Jest尝试转换CommonJS模块):
    export default {
        preset: 'ts-jest', // 用默认的CommonJS预设
        transform: {
            '^.+\\.ts?$': 'ts-jest',
        },
        // 排除aws-lambda等CommonJS包的转换
        transformIgnorePatterns: ['/node_modules/(?!aws-lambda)/'],
        // 其他原有配置...
    };
    

3. 升级依赖包版本

部分旧版本的ts-jest和jest在ESM与CommonJS混合场景下存在bug,升级到最新稳定版可解决大部分兼容性问题:

npm install -D jest@latest ts-jest@latest @types/jest@latest

4. 临时兼容方案(不推荐长期使用)

如果上述方法都无效,可以临时改用require导入aws-lambda模块:

import { describe, expect, it } from '@jest/globals';
// 用require替代import加载CommonJS模块
const { APIGatewayProxyEvent, Context } = require('aws-lambda');
import { lambdaHandler } from '../../app/app';

额外检查点

  • 确认tsconfig.json中的module字段设置为ESNext或ES6+,与Jest的ESM配置保持一致
  • 检查业务代码app/app.ts的导出方式,确保使用export或export default的ESM语法,避免混合CommonJS导出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:42:03