jest icon indicating copy to clipboard operation
jest copied to clipboard

[Bug]: Failed to parse the TypeScript config file with [email protected]

Open wtto00 opened this issue 1 year ago • 32 comments

Version

29.7.0

Steps to reproduce

After I upgraded typeScript version from 5.5.4 to 5.6.2, my test pipeline execution failed.

My execution failed pipeline is https://github.com/wtto00/android-tools/actions/runs/10907495575/job/30271298092

Expected behavior

jest --detectOpenHandles --verbose executed successfully.

Actual behavior

jest --detectOpenHandles --verbose execution failed, the failure information is as follows:

> @wtto00/[email protected] test E:\projects\github\wtto00\android-tools
> jest --detectOpenHandles --verbose

Error: Jest: Failed to parse the TypeScript config file E:\projects\github\wtto00\android-tools\jest.config.ts
  SyntaxError: Unexpected token 'export'
    at readConfigFileAndSetRootDir (E:\projects\github\wtto00\android-tools\node_modules\.pnpm\[email protected]_@[email protected][email protected]_@[email protected][email protected]_\node_modules\jest-config\build\readConfigFileAndSetRootDir.js:116:13)
    at async readInitialOptions (E:\projects\github\wtto00\android-tools\node_modules\.pnpm\[email protected]_@[email protected][email protected]_@[email protected][email protected]_\node_modules\jest-config\build\index.js:403:13)
    at async readConfig (E:\projects\github\wtto00\android-tools\node_modules\.pnpm\[email protected]_@[email protected][email protected]_@[email protected][email protected]_\node_modules\jest-config\build\index.js:147:48)
    at async readConfigs (E:\projects\github\wtto00\android-tools\node_modules\.pnpm\[email protected]_@[email protected][email protected]_@[email protected][email protected]_\node_modules\jest-config\build\index.js:424:26)
    at async runCLI (E:\projects\github\wtto00\android-tools\node_modules\.pnpm\@[email protected][email protected]_@[email protected][email protected]_\node_modules\@jest\core\build\cli\index.js:151:59)
    at async Object.run (E:\projects\github\wtto00\android-tools\node_modules\.pnpm\[email protected]_@[email protected][email protected]_@[email protected][email protected]_\node_modules\jest-cli\build\run.js:130:37)

Additional context

Related dependency versions:

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

Environment

System:
    OS: Windows 11 10.0.22631
    CPU: (6) x64 Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
  Binaries:
    Node: 20.13.1 - ~\AppData\Local\fnm_multishells\11248_1726675469235\node.EXE
    npm: 10.8.1 - ~\AppData\Local\fnm_multishells\11248_1726675469235\npm.CMD
    pnpm: 9.1.1 - ~\AppData\Local\fnm_multishells\11248_1726675469235\pnpm.CMD
  npmPackages:
    jest: ^29.7.0 => 29.7.0

wtto00 avatar Sep 18 '24 17:09 wtto00

We are having the same issue, strangely enough it is only one module that is failing at our end. The below line inside a jest.config.js file used to work for [email protected] and started failing when updating to [email protected]

transformIgnorePatterns: ['node_modules/(?!p-defer)']

joshuablokland avatar Sep 19 '24 10:09 joshuablokland

Could you try renaming the file to jest.config.cts? tsconfig.json targets "module": "NodeNext" and package.json has "type": "module", so TS will emit ESM and I'm wondering whether changing the extension to request CJS would make a difference.

JoostK avatar Sep 19 '24 16:09 JoostK

Hello @JoostK My config file is jest.config.ts, "module": "NodeNext" in tsconfig.json and "type": "module" in package.json. You can see them in https://github.com/wtto00/android-tools .

After I renamed the file to jest.config.cts, a new error occurred:

> @wtto00/[email protected] test E:\projects\github\wtto00\android-tools
> jest --detectOpenHandles --verbose

 FAIL  spec/start.test.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    E:\projects\github\wtto00\android-tools\spec\start.test.ts:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import Android from '../src/index.js';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/.pnpm/[email protected]/node_modules/jest-runtime/build/index.js:1505:14)

wtto00 avatar Sep 19 '24 17:09 wtto00

Same here:

` ● Test suite failed to run

Jest encountered an unexpected token

Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

By default "node_modules" folder is ignored by transformers.

Here's what you can do:
 • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.                                                                                  
 • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.                                                               
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation

Details:

 ..../node_modules/vscode-ws-jsonrpc/lib/index.js:6
export * from './disposable.js';
^^^^^^

SyntaxError: Unexpected token 'export'

  24 | exports.WebSocketClient = void 0;
  25 | const inversify_1 = require("inversify");
> 26 | const vscode_ws_jsonrpc_1 = require("vscode-ws-jsonrpc");
     |                             ^

`

legendsland avatar Sep 20 '24 11:09 legendsland

Same:

Error: Jest: Failed to parse the TypeScript config file C:\Dev\wl-squide\packages\core\jest.config.ts
  Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.

patricklafrance avatar Sep 20 '24 16:09 patricklafrance

I'm having the same issue, but not with Node 22: https://github.com/Vonage/vonage-node-sdk/actions/runs/10997790768 Forcing TS 5.5.4 resolves this issue

manchuck avatar Sep 23 '24 17:09 manchuck

Same issue for me, I have a jest.config.js which transforms some node_modules that are ES6 via transformIgnorePatterns. This does not work anymore since TypeScript 5.6.

I am linking the changelog which mentions a behavior change for ES6 modules, but I really don't understand how this break jest (or ts-jest).

https://devblogs.microsoft.com/typescript/announcing-typescript-5-6/

mmomtchev avatar Sep 23 '24 18:09 mmomtchev

Ok, I do understand it - here is the precise problem: https://github.com/microsoft/TypeScript/issues/59991

Alas, the answer is "working as intended".

Before 5.6, TypeScript would output whatever it was configured to output. Since 5.6, if the module is a type: module or if the file is a .mjs, TypeScript will output ES6 which jest fails to parse.

mmomtchev avatar Sep 23 '24 18:09 mmomtchev

Time to go back to the good ol' babel:

transform: {
    '\\.tsx?$': [
        'ts-jest',
        {
            tsconfig: {
                outDir: './.ts-jest'
            }
        }
    ],
    '\\.jsx?$': ['babel-jest', {plugins: ['@babel/plugin-transform-modules-commonjs']}]
},
transformIgnorePatterns: [
    '/node_modules/(?!(yourstuff))'
],
npm install --save-dev babel-jest @babel/core @babel/plugin-transform-modules-commonjs

Keep ts-jest for the TypeScript stuff and use babel for the rest.

mmomtchev avatar Sep 23 '24 22:09 mmomtchev

@mmomtchev Yeah, that is another workaround until this is addressed, but it's not ideal. When using Babel, you lose the type checking in your tests. Hopefully, this can be addressed by providing more support for ESM. However, I think that will not happen since Node can support mixing CJS and ESM in the future. Its unlikely we will get this resolved for Node 18 and 20 (which is still in LTS)

manchuck avatar Sep 24 '24 18:09 manchuck

No, you still use ts-jest for your TypeScript - with type checking - and babel for the ES6 JS. You still get type checking with this configuration.

mmomtchev avatar Sep 24 '24 18:09 mmomtchev

@manchuck how do you get it to work with Node 22? Doesn't work for me with Node 22 until I force TS to version 5.5.4.

patricklafrance avatar Sep 25 '24 17:09 patricklafrance

@mmomtchev sorry I meant you loose type checking for your test scripts. Yes you still get TS checking for code. Apologies for the mis type

@patricklafrance I didn't do anything it was working just fine with 22. Here is the run that passed in our action: https://github.com/Vonage/vonage-node-sdk/actions/runs/10997790768/job/30534604593

manchuck avatar Sep 26 '24 10:09 manchuck

@manchuck why would the rules be different for the tests? Are you tests named *.js? I just changed a type and ts-jest spewed an error.

@patricklafrance he is in a very specific particular case of this issue, because unlike us, he is not transpiling any external node_modules - he is transpiling only his own code. But it is still interesting to know what is different in Node 22.

mmomtchev avatar Sep 26 '24 11:09 mmomtchev

In my project https://github.com/wtto00/android-tools, after I switched to node@22, I found that my test scripts worked fine.

typescript node result
v5.5.4 v20
v5.5.4 v22
v5.6.2 v20
v5.6.2 v22

However, it is still unclear why node20 cannot work properly while node22 can.

wtto00 avatar Sep 26 '24 15:09 wtto00

@mmomtchev yes ts-jest will run it through typescript. Babel will not and you lose type checking. It is described in the documentation https://jestjs.io/docs/getting-started#using-typescript

However, there are some caveats to using TypeScript with Babel. Because TypeScript support in Babel is purely transpilation, Jest will not type-check your tests as they are run. If you want that, you can use ts-jest instead, or just run the TypeScript compiler tsc separately (or as part of your build process).

In terms of node 22 it could be how I'm running the tests with NODE_NO_WARNINGS=1 NODE_OPTIONS=\"--experimental-vm-modules\" set. Maybe it has something to do with that? I didn't spend too much time looking into it as we really don't need ts 5.6

manchuck avatar Sep 26 '24 20:09 manchuck

@manchuck now it is because it is described in the documentation? For both the tests and the code? Or only for the code without the tests? :smile:

This configuration runs TypeScript code through ts-jest and ES6 code through babel - so that you have type checking.

mmomtchev avatar Sep 27 '24 07:09 mmomtchev

@mmomtchev Babel will not type check tests. I don't know how else to explain it. I recently reviewed the entire code base to ensure that tests were correctly typed by removing babel: https://github.com/Vonage/vonage-node-sdk/commit/e361fbe755ee5bd4b264e5f7e41900624c7d9f25

Babel will not type check tests. It will type check code. The documentation on that is correct.

manchuck avatar Sep 27 '24 11:09 manchuck

Yes, but so is my statement that ts-jest and not babel is used for all files ending in .ts.

mmomtchev avatar Sep 27 '24 13:09 mmomtchev

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar Oct 27 '24 14:10 github-actions[bot]

Bump

gehringf avatar Nov 21 '24 08:11 gehringf

I'm using a project with ESM settings:

  • package.json has "type": "module"
  • tsconfig has "module": "nodenext".

After upgrading to node v22.11.0, the error mentioned in this issue disappeared in almost all modules of the monorepository. But it was still issued if jest.config.ts contained imports of third-party modules (eg node:path or dotenv).

After I commented out "moduleResolution": "nodenext" in tsconfig, everything started working as expected.

KostyaTretyak avatar Nov 23 '24 12:11 KostyaTretyak

Yes, but so is my statement that ts-jest and not babel is used for all files ending in .ts.

I'm not doing this, but couldn't you be type-checking JS doc in .js files and now this ability is gone?

kylemh avatar Jan 14 '25 09:01 kylemh

Workaround for working with:

  • TypeScript (>= 5.6)
  • tsconfig.json
    {
      "compilerOptions": {
        "module": "NodeNext",
        "moduleResolution": "NodeNext",
        "noEmitOnError": true
      }
    }
    
  • ESM (type: module)
  • jest.config.ts (requires ts-node)
    import type { Config } from "jest";
    import { createDefaultEsmPreset } from "ts-jest";
    
    export default {
      ...createDefaultEsmPreset()
    } as const satisfies Config;
    

STEPS | FIX:

  1. Create a dedicated tsconfig.test.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "node",
    "noEmitOnError": false
  }
}
  1. Update jest.config.ts
import type { Config } from "jest";
import { createDefaultEsmPreset } from "ts-jest";

export default {
  ...createDefaultEsmPreset({ tsconfig: "<rootDir>/tsconfig.test.json" })
} as const satisfies Config;
  1. Use tsconfig.test.json when running jest (ts-node project)
    1. Linux & Mac
      TS_NODE_PROJECT="tsconfig.test.json" npx jest
      
    2. Windows
      $env:TS_NODE_PROJECT="tsconfig.test.json"
      npx jest
      
    3. OS AGNOSTIC
      1. Install cross-env
        npm install --save-dev cross-env
        
      2. Run jest via cross-env
        npx cross-env TS_NODE_PROJECT="tsconfig.test.json" npx jest
        

Hope it helps! 🙌🥳

carlocorradini avatar Jan 23 '25 17:01 carlocorradini

Still an issue with typescript 5.7.3

As I understand the announcement typescript >5.6 now respects the package.json from node_modules regarding ESM. So even if you include a package for transformation by adjusting transformIgnorePatterns, the package will run through the typescript compiler, but typescript will not remove those ESM import/exports. Therefore jest fails, because it does not understand them.

angelo-v avatar Feb 18 '25 08:02 angelo-v

I've been hit by this issue since September. Typescript is now at version 5.8 and the problem remains. How are people solving this? @carlocorradini's solution did not work for me, I'm afraid.

luisabtrace avatar May 12 '25 16:05 luisabtrace

@luisabtrace I've simply moved to Vitest: easier and way better monorepo and ESM support.

carlocorradini avatar May 12 '25 16:05 carlocorradini

@luisabtrace I have used isolatedModules to be able to upgrade Typescript. See https://github.com/kulshekhar/ts-jest/issues/4561#issuecomment-2676155216

helylle avatar May 13 '25 15:05 helylle

@helylle Thanks, but it didn't work for me.

luisabtrace avatar May 13 '25 22:05 luisabtrace

@luisabtrace , try this: https://github.com/jestjs/jest/issues/15312#issuecomment-2495457792

KostyaTretyak avatar May 14 '25 05:05 KostyaTretyak