Repository navigation
TypeScript transpiler breaks relative imports to sibling .ts files #438
Description
Context
We're dogfooding Testy as the test runner for a deterministic core we're building in TypeScript (see 10Pines/10p-internal-apps#162). A previous evaluation against @pmoo/testy@8.0.0 found the timeout-crash bug (#432, fixed in the 8.1.0 line — thanks for the quick turnaround!). Re-running the same evaluation against current main (commit ff0dad2) to confirm the fix, we found a new regression introduced by the TypeScript transpiler added since 8.0.0.
Bug
Any .ts test file that imports another .ts file with a relative path fails to load, even though the same test worked fine on 8.0.0 (which had no built-in transpiler and relied on Node's own type-stripping).
TypescriptTranspiler.generateTemporalJavascriptFromTypescript (lib/typescript/typescript_transpiler.js) transpiles the test file and writes the result to <cwd>/.testy-cache/<basename>.js, then TestFileLoader imports it from there. The transpiled code still contains the original relative import specifier (e.g. import { greet } from "./greet.ts"), but that path is now resolved relative to .testy-cache/, not to the original file's directory — so it doesn't exist there.
Repro
mkdir repro && cd repro
npm init -y && npm pkg set type=module
npm install github:ngarbezza/testy#ff0dad20d1f16851e3dd64d63a9bb9de1ea001a1
cat > greet.ts <<'EOF'
export function greet(name: string): string {
return `hello, ${name}`;
}
EOF
cat > greet_test.ts <<'EOF'
import { suite, test, assert } from "@pmoo/testy";
import { greet } from "./greet.ts";
suite("greet", () => {
test("says hello", () => {
assert.that(greet("world")).isEqualTo("hello, world");
});
});
EOF
cat > .testyrc.json <<'EOF'
{ "directory": ".", "filter": "greet_test\\.ts$" }
EOF
npx testy greet_test.ts
Observed
Error loading suite .../greet_test.ts!
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../.testy-cache/greet.ts'
imported from '.../.testy-cache/greet_test.ts.js'
Did you mean to import "../greet.ts"?
Expected
The test passes, same as it did on 8.0.0 (no transpiler involved, Node's native type stripping handled it directly and relative imports resolved normally).
Notes
- Confirmed this isn't specific to our setup: a minimal two-file repro (above) reproduces it, and the same two files pass fine when pinned to
@pmoo/testy@8.0.0. - Since Node (≥ 22, which is now the minimum per Raise minimum supported Node version to 22 and build on 22, 24 and 26 #435) already strips types from
.tsfiles natively, it's worth asking whether the new transpiler needs to run at all when native support is available — or, if it must run (e.g. for older/other runtimes), whether it should preserve the original file's directory when writing to.testy-cache(or write the temp file next to the original) so relative imports keep resolving correctly. - This blocks adopting Testy for any multi-file TypeScript project where a test imports the code under test, which is the common case.
Full write-up with all 4 adoption criteria re-evaluated: 10Pines/10p-internal-apps spike/core-ts/README.md (private repo, happy to share details if useful).
Activity
ngarbezza commentedon Oct 28, 2026
Esto quedó resuelto en #452 (mergeado en
main), que cerró el issue duplicado #450. El JS transpilado ahora se escribe junto al.tsoriginal, así que los imports relativos a archivos.tshermanos resuelven correctamente. Estará disponible en la próxima versión publicada.