網站搜尋

javascript - 為什麼在嘗試使用 ts 檔案作為自訂 testEnvironment 時,jest 會拋出 ERR_UNKNOWN_FILE_EXTENSION?


我正在將我的 TypeScript 專案轉換為 (pnpm) monorepo,但在讓測試正常運行時遇到了問題。我有一個 jest.config.js,使用了一個自訂的 testEnvironment,該環境也是用 TypeScript 編寫的。然而,自從我將特定專案移到 monorepo 結構的 packages 目錄後,jest 就會拋出錯誤,並且不會運行任何測試:

    TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for C:\workspaces\repos\the-monorepo\packages\testproject\source\testtools\jsdom-environment-global.spec.ts

我試過使用 @swc/jest 以及 ts-jest,也查看了《如何在自訂測試環境文件中使用 TypeScript 在 Jest 中?》(這讓我想「這到底為什麼以前會成功?」),不知為何,它昨天運行得很好。我清理了 jest 緩存並重新安裝了所有 node_modules,但沒有任何效果。我還找到了一些關於 package.json 中 "type": "module" 的相關答案,但這不適用於我的 package。它不是 ESM。

這是 jest.config.js 檔案的樣子:

/** @type {import('@jest/types').Config.InitialOptions} */
const config = {
    silent: true,
    testEnvironment: "<rootDir>/source/testtools/jsdom-environment-global.spec.ts",
    roots: [
        "<rootDir>/source"
    ],
    maxWorkers: "50%",
    transform: {
        "^.+\\.(t|j)s$": ["@swc/jest", {
            sourceMaps: "inline",
            module: {
                strict: false,
                strictMode: false
            },

            jsc: {
                target: "es2021",
                parser: {
                    syntax: "typescript",
                    dynamicImport: true
                }
            }
        }]
    },
    transformIgnorePatterns: [
        "node_modules"
    ],
    testMatch: [
        "**/*/*.spec.ts",
        "**/*/*.test.ts",
        "!**/playwright-tests/**",
        "!**/playwright-tests-smoke/**"
    ],
    moduleFileExtensions: ["ts", "js", "node", "json"],
    reporters: [
        "default"
    ],
    globals: {
        self: {},
        navigator: {},
        jasmine: {},
        __UNIT__: true
    },
    coverageDirectory: "test-results",
    collectCoverage: false,
    collectCoverageFrom: [
        "./source/**/*.ts"
    ],
    coveragePathIgnorePatterns: [
        "/\\.spec\\.ts$/i",
        "/.*node_modules.*/",
        "/.*testtools.*/"
    ],
    coverageReporters: [
        "lcov", "cobertura"
    ],
    coverageProvider: "v8",
    resetMocks: true,
    restoreMocks: true,
    resetModules: true,
    setupFilesAfterEnv: [
        "jest-extended/all",
        "<rootDir>/source/testtools/setup.spec.ts"
    ],
    testPathIgnorePatterns: [
        "<rootDir>/source/testtools/",
        "<rootDir>/source/smoke-tests/",
        "<rootDir>/source/performance-tests/",
        "<rooDir>/source/playwright-tests/",
        "<rooDir>/source/playwright-tests-smoke/"
    ],
    moduleNameMapper: {
        "^@test-helpers": "<rootDir>/source/testtools/index.spec.ts",
        "^@test-tools/(.*)": "<rootDir>/source/testtools/$1",
        '^(\\.{1,2}/.*)\\.js$': '$1'
    }
};
module.exports = config;

如果 testEnvironment 是 TypeScript 文件,為什麼 jest 無法解析它?

答案#1

我找出問題了:似乎對於 transformer 沒有應用到 ESM 檔案有些混淆。在我的情況中,jsdom-environment-global.spec.ts 從 monorepo 中的另一個套件匯入了一個 ESM 模組。這個匯入會觸發異常,因為 jest 嘗試透過 require() 匯入它,這被捕獲後又透過動態匯入再次匯入。這個動態匯入然後拋出異常,顯示 ts 是未知的異常。我不確定為什麼這些檔案尚未被轉換,但根據《如何在 Jest 的自訂測試環境中使用 TypeScript》這篇文件,這似乎是正常的情況。

重點:不要在你的 jest testEnvironment 模組中匯入 ESM 檔案。