发布

  • fix(js): pin rootDir on composite tsconfigs for ts6 (ts-jest strips composite) (#36285)

    frostbyte_neo 发布于 2026-07-09 22:14:31 +00:00

    Current Behavior

    The 23-1-0-set-tsconfig-root-dir-for-ts6 migration exempts composite
    configs
    from pinning rootDir. That rests on a correct-in-isolation
    fact — TypeScript 6's TS5011 containment check carries an explicit
    !options.composite guard, so a genuinely composite program never emits
    TS5011.

    The gap: ts-jest strips composite (it does transpile-only,
    per-file compilation and force-disables
    composite/incremental/declaration). So a spec tsconfig that
    inherits composite: true from a base — the standard TS-solution layout
    — is composite at rest but not composite when ts-jest compiles a
    single test file. The !composite guard no longer applies, the per-file
    program re-infers a deeper common directory, and it fails with:

    error TS5011: The common source directory of 'tsconfig.spec.json' is './src/lib'.
    The 'rootDir' setting must be explicitly set to this or another path...
    

    This breaks the atomized e2e-ci jest tasks in any such workspace. It
    surfaced on nrwl/nx-console migrating to 23.1.0-rc.1: 31 of 33 spec
    tsconfigs resolve as composite (inherited from the base) and the
    migration pinned none of them, so a whole set of projects (shared-npm,
    the language-server libs, etc.) failed with TS5011. Note the earlier
    own-dir fix (#36272) deliberately kept the composite exemption, so
    rc.1 has that fix yet still skips these.

    Expected Behavior

    Composite configs (with an emit gate and input files) are pinned to
    their own directory ("."). Under tsc a composite rootDir
    already defaults there, so "." is a no-op for a real composite build —
    but it's the explicit value ts-jest's composite-stripped per-file
    compile needs. It's pinned to the config dir, not the deeper
    file-derived value, so a genuine composite build's emit layout is
    unchanged.

    Because every emitting config now receives its own explicit rootDir in
    phase 2, no config is left to inherit a value pinned on a base — so the
    phase-3 shield loop and inheritsRootDir are removed (the migration is
    ~100 lines shorter).

    Re-stamped 23.1.0-rc.123.1.0-rc.2 so workspaces already on rc.1
    re-run it (idempotent: has-rootDir configs are skipped).

    Validation

    • Unit spec: 11/11 pass, incl. new tests — pins a composite project to its own directory, pins a composite spec config compiled by ts-jest (composite inherited from base). The new tests fail on the pre-fix
      source.
    • End-to-end on nx-console (transpiled this migration, swapped into
      node_modules, reset spec tsconfigs to the un-pinned baseline): the
      migration pins 33/33 spec tsconfigs to "." (rc.1's version pinned
      0/33). After it runs, the previously-failing shared-npm tests
      pass (5 + 2), and nxls-e2e / nx-mcp-e2e config-load with no
      TS5011
      .

    Related Issue(s)

    Follow-up to #36272 (same migration). Fixes the composite-spec case
    exposed by the nx 23.1.0-rc.1 migration of nrwl/nx-console.


    View session information

    下载附件