웹사이트 검색

javascript - Jest: ESM을 내보내는 의존성과 함께 'export'라는 예상치 못한 토큰


이 문제가 해결하기 매우 간단해 보이고 비슷한 문제를 언급한 글들도 있었지만, 여기 질문하기 전에 가능한 모든 것을 시도했습니다. 이 문제는 여전히 지속됩니다.

내가 겪는 오류

저는 몇 가지 패키지가 있는 TS 모노레포를 가지고 있으며, 그 중 하나는 @repo/db-client입니다. 이것을 제 노드 패스트파이 백엔드에서 가져와 테스트를 합니다. 단순성을 위해 그리고 문제를 보여주기 위해, 다음과 같이 제 테스트라고 합시다:

import { expect, test } from "@jest/globals";
import { userSessionTable } from "@repo/db-client";

test("Test if I can access this table", () => {
  expect(userSessionTable).toBeTruthy();
});

@repo/db-client 패키지는 package.json에서 "type": "module"을 사용하여 ESM을 내보냅니다. 백엔드도 마찬가지로 "type": "module"입니다.

다음은 겉보기에는 쉽게 고칠 수 있는 오류입니다:

    D:\Projects\proj\packages\db-client\dist\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export * from "./database.js";
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

      1 | import { expect, test } from "@jest/globals";
    > 2 | import { userSessionTable } from "@repo/db-client";
        | ^
      3 |

나의 jest.config.js

/** @type {import('ts-jest').JestConfigWithTsJest} **/
export default {
  preset: "ts-jest",
  testEnvironment: "node",
  transform: {
    "^.+.(t|j)s?$": ["ts-jest", { useESM: true }],
  },
  moduleNameMapper: {
    "^(\\..*)\\.jsx?$": "$1",
    "^~(.+)\\.js$": "<rootDir>/src/$1",
  },
};

패키지/db-client/package.json

{
  "name": "@repo/db-client",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "exports": {
    ".": "./dist/index.js"
  },
  "scripts": {
    "build": "tsc"
  //...
}

패키지/db-client/tsconfig.json

{
  "extends": "@repo/typescript-config/library.json",
  "compilerOptions": {
    "outDir": "./dist",
    "sourceRoot": "./src",
    "baseUrl": "./",
    "paths": {
      "~/*": ["./src/*"]
    },
    // "@repo/typescript-config/library.json"
    "declaration": true,
    "declarationMap": true,
    "esModuleInterop": true,
    "incremental": false,
    "isolatedModules": true,
    "lib": ["es2022", "DOM", "DOM.Iterable"],
    "module": "NodeNext",
    "moduleDetection": "force",
    "moduleResolution": "NodeNext",
    "noUncheckedIndexedAccess": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "ESNext"

  }
}

앱/백엔드/package.json

{
  "name": "backend",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "nodemon -r dotenv/config --watch src src/server.ts",
    "start": "node -r dotenv/config dist/_app.js",
    "test": "jest",
    "build": "node build.js"
  //...

내가 시도한 것

저는 이미 이 게시물들에 있는 해결 방법들을 따라 해 보았습니다:

  • Jest가 다음과 같은 오류를 발생시킵니다: "SyntaxError: Unexpected token export"
  • https://github.com/aws-amplify/amplify-js/issues/11435
  • https://github.com/react-dnd/react-dnd/issues/3443
  • https://www.reddit.com/r/typescript/comments/tkvsgk/typescript_jest_unexpected_token_export/
  • ...

요약하자면, 나는TransformIgnorePatterns 설정, ts-jest에서 babel 또는 esbuild-jest로 전환, "ts-jest/presets/js-with-ts" 사용, useESM: true 확인, extensionsToTreatAsEsm 시도 등 많은 것을 시도했습니다.

문제가 무엇인 것처럼 보인다

문제의 핵심은 단순히 Jest는 ESM을 처리할 수 있지만, 의존성의 ESM은 처리할 수 없다는 것처럼 보입니다. db-client 패키지는 빌드되어 있으며, 그 index.js는 /dist에서 내보내집니다 (package.json -> exports -> ".": ["./dist/index.js"]). 그 index.js에는 export 문이 포함되어 있어 종료를 발생시킵니다.

저는 그 패키지에서 ESM만 내보내도록 강제되고 있습니다. 그래서 제 패키지들의 빌드를 재구성하지 않고도 해결책을 찾아야 합니다.