rescript-lang / rescript-lang/rescript
`genType` emits relative `./S.gen` for workspace (file:) dependencies instead of package-qualified sury/src/S.gen
Nessuno ha ancora preso questa issue.
- Lingua principale
- OCaml
- Stelle
- 7.5k
- Fork
- 485
- Merge medio
- 1g 2h
- PR unite (30g)
- 55
Descrizione
Summary
When a consumer package depends on another package via a pnpm/npm workspace file: link, genType emits the import path for cross-package types as a relative path (./S.gen) instead of the package-qualified path (sury/src/S.gen). The relative path does not resolve — there's no S.gen.{ts,d.ts} next to the generated file — so downstream tsc fails with TS2307: Cannot find module './S.gen'.
Versions
rescript:12.2.0(also reproduces on12.0.0-beta.5)- Package manager:
pnpm@9.0.5 - Node:
22.6.0 - OS: Ubuntu 24.04
Minimal repro
Two-package pnpm workspace. lib publishes hand-written S.gen.d.ts; app imports its type via @genType.
repro/
├─ pnpm-workspace.yaml # packages: ["packages/*"]
├─ packages/
│ ├─ lib/
│ │ ├─ package.json # { "name": "lib" }
│ │ ├─ rescript.json # below
│ │ └─ src/
│ │ ├─ S.res # let string: t<string> ; type error = {…}
│ │ └─ S.gen.d.ts # hand-written: export type t<T> = …; export type error = …
│ └─ app/
│ ├─ package.json # { "dependencies": { "lib": "file:../lib" } }
│ ├─ rescript.json # below
│ └─ src/
│ └─ Demo.res # @genType let x: S.error = …
packages/lib/rescript.json:
{
"name": "lib",
"namespace": false,
"suffix": ".res.mjs",
"package-specs": { "module": "esmodule", "in-source": true },
"sources": [{ "dir": "src", "public": ["S"] }]
}
packages/app/rescript.json:
{
"name": "app",
"sources": [{ "dir": "src", "subdirs": true }],
"package-specs": { "module": "esmodule", "in-source": true },
"suffix": ".res.mjs",
"dependencies": ["lib"],
"gentypeconfig": { "generatedFileExtension": ".gen.ts" }
}
packages/app/src/Demo.res:
@genType
let err: S.error = S.Error.make(…)
Run pnpm install && pnpm --filter=app rescript build.
Actual output
packages/app/src/Demo.gen.ts:
import type {error as S_error} from './S.gen'; // ❌ relative — no such file next to Demo.gen.ts
tsc --noEmit reports:
Demo.gen.ts(…,…): error TS2307: Cannot find module './S.gen' or its corresponding type declarations.
Expected output
import type {error as S_error} from 'lib/src/S.gen';
(This was the behavior in earlier versions — the same repo has a committed Demo.gen.ts from a prior generation that used from 'lib/src/S.gen'.)
Context / investigation
app/lib/bs/.sourcedirs.jsoncorrectly lists["lib", "/abs/path/packages/lib"]under"pkgs", so the dependency is known to the build.- Poking at the
bsc.exestrings, the relevant logic lives incompiler/gentype/ModuleResolver.ml(resolve_module,import_path_for_reason_module_name,read_bs_dependencies_dirs) andcompiler/gentype/ImportPath.ml. - It looks like when the dep's source directory is reachable via a workspace path, the resolver adds
Sto the consumer's localmodule_name_mapand that takes precedence over the dep lookup, so the import is emitted relative. - No
gentypeconfigoption currently works around this:shimstreats its value as a shim-file path (emits./lib/src/S.gen.shim), and there's nopackageName/importPath/modulesMapoption documented in the bsc binary.
Workaround
Ship a shim next to the generated file that re-exports from the dep:
// packages/app/src/S.gen.ts
export type { error, t } from "lib/src/S.gen";
This keeps the relative ./S.gen import resolving, but is obviously a workaround.
Does it reproduce outside file: deps?
Not when lib is a real npm dependency (resolved under node_modules/lib) — that case emits 'lib/src/S.gen' correctly. Only workspace / file: installs hit this.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia da compiler/gentype/ModuleResolver.ml, in particolare da resolve_module, import_path_for_reason_module_name e read_bs_dependencies_dirs, quindi esamina compiler/gentype/ImportPath.ml. Riproduci il problema con il pnpm workspace descritto ed esegui tsc --noEmit. È completato quando l’import generato usa il percorso lib/src/S.gen qualificato dal package per le dipendenze file: e il controllo dei tipi passa senza uno shim.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- node.js, ocaml, typescript
- Ambito
- build-system, compilers
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Tranquilla
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 58/100