fix: add TypeScript project references, mirroring MetaMask/core - #170
Closed
ulissesferreira wants to merge 4 commits into
Closed
fix: add TypeScript project references, mirroring MetaMask/core#170ulissesferreira wants to merge 4 commits into
ulissesferreira wants to merge 4 commits into
Conversation
Adds a `references` entry to bitcoin-wallet-snap, solana-wallet-snap, and tron-wallet-snap's tsconfig.json for their dependency on snap-networks-utils, and lists every snap package in the root tsconfig.json's references, matching the pattern used in MetaMask/core/packages/profile-metrics-controller. Does not touch the existing @metamask/* paths/baseUrl mapping. Project references solve build ordering (tsc --build) and editor go-to-source navigation; they do not change how a plain `tsc --noEmit` resolves `@metamask/*` imports, which still goes through node_modules to each package's built dist/ output. That's a separate problem (see #167, #169).
…demonstrative) Structurally replicates core's incremental repository-wide type-checking setup: tsconfig.packages.lint.json (shared), a tsconfig.lint.json per package (outDir/tsBuildInfoFile -> .tsc-lint-cache, references to workspace deps), a root tsconfig.lint.json referencing all six packages, and a `lint:tsc` script wired into `yarn lint`, exactly matching MetaMask/core/tsconfig.lint.json and MetaMask/core/packages/base-controller/tsconfig.lint.json. This intentionally does NOT touch the existing @metamask/* paths/baseUrl mapping (per #170's original scope). Running `yarn lint:tsc` from a clean state (no packages/*/dist, no .tsbuildinfo/.tsc-lint-cache) currently fails: - ~70 "Cannot find module '@metamask/snap-networks-utils/...'" errors in bitcoin-wallet-snap, solana-wallet-snap, tron-wallet-snap. This is the expected, confirmed result: the reference graph rebuilds each project's OWN .tsc-lint-cache output, but the importing package still resolves the bare specifier via node_modules -> package.json -> the real dist/, which this graph never touches. `references` + `tsc --build` do not remove the need for a paths -> src mapping (#167/#169) -- core's own tsconfig.lint.json files extend each package's regular tsconfig.json specifically to inherit that mapping. - 13 TS6307 "Projects must list all files or use an 'include' pattern" errors, specific to composite/--build mode's stricter accounting of every file entering the program (nested JSON test fixtures, snap.manifest.json) vs plain `tsc --noEmit`. A real migration would need broader `include` patterns per package. - 18 pre-existing, unrelated "Cannot find module '@metamask/superstruct'" errors via a ../snaps-registry path, confirmed byte-for-byte identical on unmodified main with or without any of this branch's changes. Committed as-is, findings documented, to answer "what would full Core parity require" -- not intended to be merged in this state.
This was referenced Aug 19, 2026
…ike Core References alone (the prior commit) don't fix workspace resolution: tsc --noEmit and tsc --build both still went through node_modules -> dist for `@metamask/*` imports. This adds the piece Core actually relies on: - An explicit `@metamask/snap-networks-utils/*` subpath entry in the shared `tsconfig.packages.json` `paths` map (TS path patterns only allow one `*`), mirroring Core's own `@metamask/json-rpc-engine/v2` subpath entry. - `baseUrl: "./"` on `tron-wallet-snap` and `stellar-wallet-snap` (the two packages that didn't have it), so every package now reinterprets the shared `../*/src` mapping against its own directory like the rest of the monorepo already does, matching Core's convention of every package setting `baseUrl`. - Expanded `include` in the four affected packages' `tsconfig.lint.json` to cover `snap.manifest.json` and JSON test fixtures pulled in via `resolveJsonModule`, satisfying `--build` mode's stricter file-listing requirement (TS6307). `yarn lint:tsc` (tsc --build tsconfig.lint.json) now passes with 0 errors from a clean state, matching Core's actual behavior. Caveat: plain per-package `tsc --noEmit` (what `yarn typecheck` runs) still fails with TS6305 for bitcoin-wallet-snap, solana-wallet-snap, and tron-wallet-snap - the packages with a `references` entry. This is because `references` to a composite project always require `--build` mode (which builds referenced projects in order) to resolve cleanly; a bare `tsc --noEmit` invocation never builds dependencies first. This isn't fixable by matching Core's config more closely - it's inherent to combining `references` with plain `--noEmit`, and only `tsc --build` resolves it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation
Status:
yarn lint:tscnow passes with 0 errors from a clean state ✅ (plain per-packagetsc --noEmit/yarn typecheckhas one remaining, separate caveat — see below).Third option for comparison alongside #167 and #169, modeled on
MetaMask/core's pattern (e.g.packages/profile-metrics-controller/tsconfig.jsonand itstsconfig.build.json).bitcoin-wallet-snap,solana-wallet-snap, andtron-wallet-snapeach get"references": [{ "path": "../snap-networks-utils" }]in theirtsconfig.json(their only workspace dependency).tsconfig.jsonlists every snap package alongsidesnap-networks-utils, matchingcore's root config.tsc --buildlint-graph (tsconfig.packages.lint.json, per-packagetsconfig.lint.json, roottsconfig.lint.json,"lint:tsc"wired as the first step ofyarn lint), mirroringMetaMask/core's incremental repo-wide typechecking setup exactly.@metamask/snap-networks-utils/*subpath entry in the sharedtsconfig.packages.jsonpathsmap (TypeScriptpathspatterns only allow one*, mirroring Core's own@metamask/json-rpc-engine/v2subpath entry),baseUrl: "./"added totron-wallet-snapandstellar-wallet-snap(the two packages that didn't have it — every other package, and every package in Core, sets this), and expandedincludein the four affectedtsconfig.lint.jsonfiles to coversnap.manifest.json/JSON test fixtures (required by--buildmode's stricter file-listing rule, TS6307).How this got here (history, kept for the record)
Earlier revisions of this PR were deliberately scoped to "references only, change nothing else," to test in isolation whether
referencesalone fixes the resolution problem #167/#169 address. It doesn't — confirmed empirically both with plaintsc --noEmitand with a full clean-stateyarn lint:tscrun, which failed with ~70 "Cannot find module@metamask/snap-networks-utils" errors + 13TS6307file-inclusion errors. That confirmedreferencesalone gives you (a) correcttsc --buildordering/incrementality and (b) editor "go to definition" to source, but does not change how a bare@metamask/*specifier resolves — that still needs apathsmapping to source, exactly like #167/#169 add.Adding that
pathsmapping directly (matching Core's exact declaring-relative form,"@metamask/*": ["../*/src"], reinterpreted per-package via each package's ownbaseUrl) is what actually closes the gap —yarn lint:tscnow buildssnap-networks-utilsfirst (in correct topological order, per thereferencesgraph) and every consumer resolves it from source, with 0 errors.Remaining caveat: plain
tsc --noEmit(yarn typecheck)Running
tsc --noEmitdirectly onbitcoin-wallet-snap,solana-wallet-snap, ortron-wallet-snap(the three packages with areferencesentry) still fails withTS6305 Output file '...index.d.ts' has not been built from source file '...index.ts', even after this fix. This is not a config gap fixable by matching Core more closely — it's inherent to combiningreferences(to acomposite: trueproject) with a bare--noEmitinvocation: TypeScript's project-reference redirect logic requires the referenced project to actually have been built first, and onlytsc --build(not--noEmit) builds dependencies in order before checking the dependent. Confirmed by testing bothcomposite: falseon the consumer (no change) and removingreferencesentirely (error disappears, replaced by the expected TS6307 file-listing error instead).yarn typecheck(workspaces foreach ... exec tsc --noEmit) will keep hitting this for the three referenced packages unless it's changed to invoketsc --buildinstead — out of scope for this PR, called out for visibility.Unrelated pre-existing issues found while testing
tron-wallet-snap/stellar-wallet-snappreviously showedCannot find module '@metamask/superstruct'/'@metamask/utils'from asnaps-registrypath in earlier testing on this branch — re-verified from a clean worktree and that package/path doesn't actually exist in this repo; see "Clean-install verification" for the corrected finding (10 unrelated pre-existing type errors elsewhere instead).yarn typecheckis not wired into any CI workflow today.Validation
yarn lint:tsc(tsc --build tsconfig.lint.json): passes with 0 errors, from a clean state (nodist, no.tsbuildinfo, no.tsc-lint-cache).yarn build:types: passes, unaffected.yarn changelog:validate: passes.tsc --noEmitforsample-snap,snap-networks-utils,stellar-wallet-snap: passes with 0 errors.tsc --noEmitforbitcoin-wallet-snap,solana-wallet-snap,tron-wallet-snap: fails withTS6305— see "Remaining caveat" above; this is areferences+--noEmitlimitation, not a resolution bug.yarn lint:eslint: not verified in this sandbox due to an environment memory limit (Node heap OOM building the full ESLint TS program graph) unrelated to this change; a single-file spot-check passed.Pros and Cons
Pros:
tsc --buildpath, while also gaining whatreferencesalone provided: correcttsc --buildordering/incrementality and editor "go to definition" to source.referenceshalf.yarn typecheck/lint:tscin CI today).Cons:
tsc --noEmit(yarn typecheck) still fails for the three packages with areferencesentry — fixing that would mean changingyarn typecheckto usetsc --buildsemantics, which is out of scope here.tsconfig.lint.jsonfiles, a root lint config, a newlint:tscscript) to get to a working state.references+ cross-projectpaths+--buildvs--noEmit) to maintain correctly going forward.Clean-install verification
Re-verified from a genuinely fresh worktree — no
node_modules, nopackages/*/dist, no.tsc-lint-cacheanywhere — with onlyyarn installrun (noyarn build), before the paths-mapping fix:TS2307"Cannot find module@metamask/snap-networks-utils..." (69 via/logger, 4 bare) — matches the previously documented ~70.TS6307file-inclusion errors — exact match to previously documented ~13.snaps-registrypackage exists in this repo/branch. Instead, 10 other pre-existing, unrelated type errors (5×TS7006, 2×TS2769, 2×TS2345, 1×TS7019) insolana-wallet-snap/tron-wallet-snap, landing at a similar total (96 vs. ~101).After the paths-mapping fix (this same clean-state methodology, re-run locally):
yarn lint:tscexits 0 with 0 errors.References
Checklist