发布

  • fix(js): resolve package and extension-less tsconfig extends read from the tree (#36271)

    frostbyte_neo 发布于 2026-07-28 18:19:49 +00:00

    Current Behavior

    Generators and migrations that parse a tsconfig.json from the devkit
    Tree each build their own host that reads file contents from the
    Tree but resolves file existence and paths through ts.sys. That host
    cannot follow two extends forms:

    • A package-provided base such as @tsconfig/node20/tsconfig.json.
      TypeScript resolves it to an absolute path, which the Tree re-roots
      under the workspace, so the base reads as nothing.
    • An extension-less base such as ./tsconfig. It resolves against the
      current working directory, so it only works when the command runs from
      the workspace root.

    In both cases the base's options silently vanish from the merged result
    (the failure surfaces only as a TS5083/TS6053 the callers discard).
    The add-ignore-deprecations TypeScript 6 migration can then miss a
    deprecated option a config inherits from such a base, and generators can
    read the wrong compiler options.

    Expected Behavior

    extends resolves the way tsc resolves it, regardless of the
    extends form or the working directory, when a config is parsed from
    the Tree. A config that inherits a deprecated option through a package
    or extension-less base is handled correctly by the TypeScript 6
    migration, and generators read the fully-merged compiler options.

    Implementation Details

    A single tree-faithful host, createTreeParseConfigHost, is extracted
    into @nx/js and adopted at the five sites that each rebuilt one: the
    angular and js tsconfig utilities, the js setup-build and rollup
    configuration generators, and the update-23-1-0
    add-ignore-deprecations TypeScript 6 migration. It maps absolute paths
    under the Tree root back to tree-relative, falls back to fs for
    paths that resolve outside the workspace (a pnpm store or a
    link:/file: target), and answers existence from the Tree.
    realpath and getCurrentDirectory are anchored to the Tree root, so
    resolution is independent of the working directory: TypeScript resolves
    a package-form base as a relative path and hands it to realpath, which
    ts.sys would re-anchor to process.cwd(). The out-of-root fs branch
    is gated on isFile to match ts.sys, so a directory is never read as
    a config file.

    The migration now warns about a config whose extends chain is
    genuinely unresolvable instead of silently guessing at incomplete
    options.

    Two changes worth calling out: existence at the generator sites now
    comes from the Tree rather than disk, so a base present on disk but
    deleted in the Tree is reported unresolvable; and readTsConfig's
    optional sys parameter widens from ts.System to
    ts.ParseConfigHost, a public @nx/js signature change that stays
    source-compatible for existing callers.

    Host unit tests and package-form and extension-less extends fixtures
    are added to the migration spec.

    Related Issue(s)

    Fixes NXC-4609


    View session information

    下载附件