microsoft / microsoft/TypeScript

Importing causes side effect of changing module resolution for transitive dependencies for other imports in 5.6

Open
#60,062 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Needs More Info
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

🔎 Search Terms

"module resolution cache", "5.6 cache"

🕗 Version & Regression Information
  • This changed between versions 5.5.4 and 5.6.2
⏯ Playground Link

No response

💻 Code

Importing dependency B that transitively imports dependency D can pollute the cache for dependency C which also needs dependency D. In the example I observed this caused the types used for D to be CommonJS types for D when ESM should have been used, just because C imported D as CommonJs. This behavior changed in TypeScript 5.6.


import { Aggregate } from '@convex-dev/aggregate'
import { Migrations } from '@convex-dev/migrations'

Both of these packages transitively import convex.

The @convex-dev/aggregate package is "broken:" it uses export conditions to point '.' (see https://unpkg.com/browse/@convex-dev/aggregate@0.1.6/package.json) to point to a file in a directory with a package.json with "type": "commonjs" (see https://unpkg.com/browse/@convex-dev/aggregate@0.1.6/dist/esm/package.json), when based on the directory names that doesn't really make sense.

@convex-dev/migrations works more like you'd expect, a similar layout but the package.json at dist/esm/package.json more reasonably has "type": "module".

🙁 Actual behavior

In 5.5.6, just adding the import

`import { Aggregate } from '@convex-dev/aggregate` 

is enough to change the resolution of package 'convex' used by '@convex-dev/migrations'.

tsc --traceResolution with import { Aggregate } from '@convex-dev/aggregate: cache is used to resolve 'convex/server' to /Users/tomb/memory-palace/node_modules/convex/dist/cjs-types/server/index.d.ts
(partial output)

======== Resolving module 'convex/server' from '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/index.d.ts'. ========
Explicitly specified module resolution kind: 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
File '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/package.json' does not exist according to earlier cached lookups.
File '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/package.json' exists according to earlier cached lookups.
Loading module 'convex/server' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/node_modules' does not exist, skipping all lookups in it.
Resolution for module 'convex/server' was found in cache from location '/Users/tomb/memory-palace/node_modules/@convex-dev'.
======== Module name 'convex/server' was successfully resolved to '/Users/tomb/memory-palace/node_modules/convex/dist/cjs-types/server/index.d.ts' with Package ID 'convex/dist/cjs-types/server/index.d.ts@1.16.2+@auth0/auth0-react@2.0.2+react@18.2.0+react-dom@18.2.0'. ========

tsc --traceResolution with import { Aggregate } from '@convex-dev/aggregate commented out: cache is not used, 'convex/server' resolved to /Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts
(partial output)

======== Resolving module 'convex/server' from '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/index.d.ts'. ========
Explicitly specified module resolution kind: 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
File '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/package.json' does not exist according to earlier cached lookups.
File '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/package.json' exists according to earlier cached lookups.
Loading module 'convex/server' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/node_modules' does not exist, skipping all lookups in it.
File '/Users/tomb/memory-palace/node_modules/convex/server/package.json' exists according to earlier cached lookups.
File '/Users/tomb/memory-palace/node_modules/convex/package.json' exists according to earlier cached lookups.
Entering conditional exports.
Saw non-matching condition 'require'.
Matched 'exports' condition 'import'.
Entering conditional exports.
Matched 'exports' condition 'types'.
Using 'exports' subpath './server' with target './dist/esm-types/server/index.d.ts'.
File '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts' exists - use it as a name resolution result.
Resolved under condition 'types'.
Exiting conditional exports.
Resolved under condition 'import'.
Exiting conditional exports.
Resolving real path for '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts', result '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts'.
======== Module name 'convex/server' was successfully resolved to '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts' with Package ID 'convex/dist/esm-types/server/index.d.ts@1.16.2+@auth0/auth0-react@2.0.2+react@18.2.0+react-dom@18.2.0'. ========
🙂 Expected behavior

In 5.5.4, adding

`import { Aggregate } from '@convex-dev/aggregate` 

has no effect on the resolution of package 'convex' used by '@convex-dev/migrations'.

tsc --traceResolution with import { Aggregate } from '@convex-dev/aggregate commented out
(partial output)

======== Resolving module 'convex/server' from '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/index.d.ts'. ========
Explicitly specified module resolution kind: 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
File '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/package.json' does not exist.
File '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/package.json' exists according to earlier cached lookups.
Loading module 'convex/server' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/client/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/esm/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/dist/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/migrations/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/tomb/memory-palace/node_modules/@convex-dev/node_modules' does not exist, skipping all lookups in it.
File '/Users/tomb/memory-palace/node_modules/convex/server/package.json' exists according to earlier cached lookups.
File '/Users/tomb/memory-palace/node_modules/convex/package.json' exists according to earlier cached lookups.
Entering conditional exports.
Saw non-matching condition 'require'.
Matched 'exports' condition 'import'.
Entering conditional exports.
Matched 'exports' condition 'types'.
Using 'exports' subpath './server' with target './dist/esm-types/server/index.d.ts'.
File '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts' exists - use it as a name resolution result.
Resolved under condition 'types'.
Exiting conditional exports.
Resolved under condition 'import'.
Exiting conditional exports.
Resolving real path for '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts', result '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts'.
======== Module name 'convex/server' was successfully resolved to '/Users/tomb/memory-palace/node_modules/convex/dist/esm-types/server/index.d.ts' with Package ID 'convex/dist/esm-types/server/index.d.ts@1.16.2+@auth0/auth0-react@2.0.2+react@18.2.0+react-dom@18.2.0'. ========
Additional information about the issue

Restating the issue: Having already resolved a module import causes important steps to be skipped:

Resolution for module 'convex/server' was found in cache from location '/Users/tomb/memory-palace/node_modules/@convex-dev'.

seems to indicate that exports condition logic is being skipped inappropriately for this cached lookup: because it had been found before from a place where exports condition "require" matched, that was used instead of re-resolving now that "require" would not have matched.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the imports of @convex-dev/aggregate and @convex-dev/migrations with TypeScript 5.5.4 and 5.6.2, then compare the provided tsc --traceResolution output. Investigate the module-resolution cache path that resolves convex/server from @convex-dev and add a regression test showing that cached results do not bypass conditional exports; done means the ESM target remains selected regardless of import order.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.