使用 typescript 和 esm 运行 jest 时找不到模块“@middy/core”

pha*_*nan 5 node.js typescript jestjs ts-jest middy

你好,我正在使用 esm 和 jest 运行 typescript,但 middy 遇到问题:

\n

我做了这个测试:

\n
import { APIGatewayEvent, Context } from \'aws-lambda\';\nimport { lambda } from \'../index.js\';\n\ndescribe(\'get-by-id handler\', () => {\n  test(\'Should not find id\', async () => {\n    const x = jest.fn();\n    x();\n    expect(x).toHaveBeenCalled();\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

它与我在下面提供的配置和npm run test命令配合得很好。\n但是当我将其更改为如下所示时:

\n
import { APIGatewayEvent, Context } from \'aws-lambda\';\nimport { lambda } from \'../index.js\';\n\ndescribe(\'get-by-id handler\', () => {\n  test(\'Should not find id\', async () => {\n    const res = await lambda({\n    pathParameters: { id: \'id\' },\n    } as unknown as APIGatewayEvent, {} as Context);\n    console.log(res);\n\n    const x = jest.fn();\n    x();\n    expect(x).toHaveBeenCalled();\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

我收到这个错误

\n
jest -c jest.config.cjs\n\nFAIL  app/src/handlers/get-by-id/tests/index.test.ts\n\xe2\x97\x8f Test suite failed to run\n\n    app/src/handlers/get-by-id/index.ts:4:19 - error TS2307: Cannot find module \'@middy/core\' or its corresponding type declarations.\n    \n    4 import middy from \'@middy/core\';\n                        ~~~~~~~~~~~~~\n\nTest Suites: 1 failed, 1 total\nTests:       0 total\nSnapshots:   0 total\nTime:        11.409 s, estimated 13 s\nRan all test suites.\n
Run Code Online (Sandbox Code Playgroud)\n

这是配置:\n tsconfig.json

\n
{\n  "extends": "./node_modules/@tsconfig/node20/tsconfig.json",\n  "compilerOptions": {\n    "declaration": true,\n    "outDir": "./dist/",\n    "noUnusedParameters": false,\n    "noPropertyAccessFromIndexSignature": false,\n    "resolveJsonModule": true\n  },\n}\n
Run Code Online (Sandbox Code Playgroud)\n

jest.config.cjs:

\n
module.exports = {\n    preset: \'ts-jest\',\n    testEnvironment: \'node\',\n    testRegex: \'(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.(ts?)$\',\n    moduleNameMapper: {\n        \'^(\\\\.{1,2}/.*)\\\\.js$\': \'$1\',\n    },\n};\n
Run Code Online (Sandbox Code Playgroud)\n

package.json:

\n
{\n  "type": "module",\n  "main": "index.js",\n  "scripts": {\n    "build": "npm run clean && npm run copy-files && npm run tsc",\n    "copy-files": "copyfiles -e \\"!{*.md,package?(-lock).json}\\" \\"**/*.*\\" dist",\n    "clean": "rimraf ./dist",\n    "tsc": "tsc -p tsconfig.build.json",\n    "deploy": "cdktf deploy",\n    "lint": "npx eslint . --ext .ts,.tsx",\n    "test": "jest -c jest.config.cjs",\n    "coverage": "jest -c jest-cov.config.cjs"\n  },\n  "license": "ISC",\n  "devDependencies": {\n    "@cdktf/provider-aws": "^18.0.6",\n    "@tsconfig/node20": "^20.1.2",\n    "@types/aws-lambda": "^8.10.129",\n    "@types/jest": "^29.5.10",\n    "@types/node": "^20.10.0",\n    "@typescript-eslint/eslint-plugin": "^6.13.0",\n    "@typescript-eslint/parser": "^6.13.0",\n    "cdktf": "^0.19.1",\n    "constructs": "^10.3.0",\n    "copyfiles": "^2.4.1",\n    "eslint": "^8.54.0",\n    "eslint-config-airbnb-base": "^15.0.0",\n    "eslint-config-airbnb-typescript": "^17.1.0",\n    "eslint-plugin-import": "^2.29.0",\n    "eslint-plugin-require-extensions": "^0.1.3",\n    "jest": "^29.7.0",\n    "rimraf": "^5.0.5",\n    "ts-jest": "^29.1.1",\n    "ts-node": "^10.9.1",\n    "typescript": "^5.3.2"\n  },\n  "dependencies": {\n    "@aws-sdk/client-dynamodb": "^3.460.0",\n    "@aws-sdk/client-secrets-manager": "^3.460.0",\n    "@aws-sdk/lib-dynamodb": "^3.460.0",\n    "@middy/core": "^5.0.3",\n    "axios": "^1.6.2",\n    "dotenv": "^16.3.1"\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

处理程序:

\n
import type { APIGatewayEvent } from \'aws-lambda\';\nimport middy from \'@middy/core\';\nconst handler = async (event: APIGatewayEvent) => {\n    return {\n        statusCode: 200,\n    };\n};\n\n// eslint-disable-next-line import/prefer-default-export\nexport const lambda = middy().handler(handler);\n
Run Code Online (Sandbox Code Playgroud)\n

运行在节点上20.9.0

\n

到目前为止我一步一步尝试过的:

\n
    \n
  1. test将脚本更改packge.json为此\n \nas此处"NODE_OPTIONS=--experimental-vm-modules jest -c jest.config.cjs"提到\n结果是相同的

    \n
  2. \n
  3. 改成jest.config.cjs这样:

    \n
  4. \n
\n
module.exports = {\n    preset: \'ts-jest/presets/default-esm\',\n    testEnvironment: \'node\',\n    testRegex: \'(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.(ts?)$\',\n    moduleNameMapper: {\n        \'^(\\\\.{1,2}/.*)\\\\.js$\': \'$1\',\n    },\n    transform: {\n        // \'^.+\\\\.[tj]sx?$\' to process js/ts with `ts-jest`\n        // \'^.+\\\\.m?[tj]sx?$\' to process js/ts/mjs/mts with `ts-jest`\n        \'^.+\\\\.tsx?$\': [\n            \'ts-jest\',\n            {\n                useESM: true,\n            },\n        ],\n    },\n};\n
Run Code Online (Sandbox Code Playgroud)\n

正如这里提到的\n结果是一样的

\n
    \n
  1. 改成jest.config.cjs这样:
  2. \n
\n
const esModules = ["@middy"].join("|")\nmodule.exports = {\n    preset: \'ts-jest/presets/default-esm\',\n    testEnvironment: \'node\',\n    testRegex: \'(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.(ts?)$\',\n    moduleNameMapper: {\n        \'^(\\\\.{1,2}/.*)\\\\.js$\': \'$1\',\n    },\n    transform: {\n        \'^.+\\.ts?$\': [\n            \'ts-jest\',\n            {\n                useESM: true,\n            },\n        ],\n    },\n    transformIgnorePatterns: [`node_modules/(?!${esModules})`],\n};\n
Run Code Online (Sandbox Code Playgroud)\n

正如这里提到的\n结果是一样的

\n
    \n
  1. 改成tsconfig.json这样:
  2. \n
\n
{\n  "compilerOptions": {\n    "incremental": true,\n    "target": "es2020",\n    "module": "es2020",\n    "declaration": true,\n    "sourceMap": true,\n    "composite": true,\n    "strict": true,\n    "moduleResolution": "node",\n    "esModuleInterop": true,\n    "skipLibCheck": true,\n    "forceConsistentCasingInFileNames": true,\n    "preserveConstEnums": true,\n    "resolveJsonModule": true,\n    "allowJs": true,\n    "rootDir": ".",\n    "outDir": "lib"\n  },\n  "include": ["src/**/*", "tests/**/*"],\n  "exclude": ["node_modules"]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

正如这里提到的\n出现此错误:

\n
ReferenceError: jest is not defined\n\n       9 |         console.log(res);\n      10 |\n    > 11 |         const x = jest.fn();\n         |                   ^\n      12 |         x();\n      13 |         expect(x).toHaveBeenCalled();\n      14 |     });\n\n      at Object.<anonymous> (app/src/handlers/get-by-id/tests/index.test.ts:11:19)\n
Run Code Online (Sandbox Code Playgroud)\n