Skip to content

Jest transformIgnorePatterns allowlist breaks on every ESM-only dependency bump #10443

Description

@dpage

web/jest.config.js transforms node_modules through a hand-maintained allowlist:

'[/\\\\]node_modules[/\\\\](?!react-dnd|dnd-core|@react-dnd|react-resize-detector|react-data-grid|marked).+\\.(js|jsx|mjs|cjs|ts|tsx)$',

Anything not named there is require()d untransformed, so the moment a dependency (or one of its transitive dependencies) ships ESM-only, Jest throws Must use import to load ES Module and every suite that touches it fails. Webpack is unaffected, so the app itself builds and runs fine; it is purely a test-harness problem, which makes it easy to misread as real breakage.

It has bitten twice already in the current Dependabot queue: #10336 (html-react-parser 6, via domhandler) took out 115 of 152 suites, and #10338 (@tanstack/react-table 9) took out 93. In both cases no assertion actually failed.

The allowlist fails closed, so this will recur on every future ESM-only bump. Inverting it, so node_modules is transformed by default with a short exclusion list, would fail in the safe direction.

I measured what that would cost, on 4 CPUs with --maxWorkers=50%, over the full 154 suites:

cold cache warm cache Babel cache
current allowlist 139s 130s 26 MB
transform all of node_modules 184s 136s 220 MB

Cold is the number that matters, since run-javascript-tests.yml caches nothing between runs, so roughly +32%, about 45s on each of the three platform jobs.

Two things anyone picking this up should know:

  1. Fully inverting does not work. Babel then tries to transform Jest's own runner and the run dies in under a second, before a single suite starts, with SyntaxError: .../jest-runner/build/index.js: Class private methods are not enabled. The figures above come from a bounded version that still excludes @jest, jest-*, @babel, babel-*, pretty-format and expect.
  2. @tanstack/query-core needs a Babel plugin. Under the inverted config six suites (BgProcessManager, BgProcessNotify, Proceses, ProcessDetails, Roles, Users) fail on the same Class private methods are not enabled error from query-core/build/modern/queryObserver.cjs. Adding @babel/plugin-transform-private-methods should settle it.

So the work is: add the Babel plugin, invert the pattern with an exclusion list, and accept roughly a minute more per CI job.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions