Skip to content

Commit 596cd1f

Browse files
committed
test: cover __dirname, __filename, & require.cache in CJS TS file
## Problem Two closed bugs left the CJS-scope-globals contract untested: - [#694](#694) — Node 23.6+ began classifying `.ts` entrypoints as ESM in `type: "commonjs"` packages, breaking `__dirname` and `__filename` with `ReferenceError: __dirname is not defined in ES module scope`. Implicit fix landed in the 4.20/4.21 era; no paired regression test. - [#726](#726) — `require.cache` returned `undefined` in v4.20 after the loader refactor; the maintainer reverted in v4.20.3 and explicitly noted it should land as a test for the next release. A future refactor of the CJS-classification path could silently reintroduce either bug. ## Changes One new `commonjs-mode-contracts.ts` test, iterated through both `omitted type` and `explicit commonjs` package shapes (two process spawns total), asserts that a `.ts` entrypoint sees: - `__dirname` → fixture path - `__filename` → fixture entry path - `require.cache` → populated object after a sibling `require('./dep.cjs')`
1 parent 75d9bf0 commit 596cd1f

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

tests/specs/commonjs-mode-contracts.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
describe, test, onTestFail, expect,
33
} from 'manten';
44
import { createFixture } from 'fs-fixture';
5+
import { outdent } from 'outdent';
56
import type { NodeApis } from '../utils/tsx.js';
67
import {
78
createPackageJson,
@@ -148,6 +149,51 @@ export const commonJsModeContracts = (node: NodeApis) => describe('CommonJS mode
148149
}
149150
});
150151

152+
// Regression guard for two closed bugs that lacked paired tests:
153+
// - https://github.com/privatenumber/tsx/issues/694 -- Node 23.6+ classified
154+
// .ts entrypoints as ESM in CJS-shaped packages, breaking __dirname and
155+
// __filename ("not defined in ES module scope").
156+
// - https://github.com/privatenumber/tsx/issues/726 -- v4.20 returned undefined
157+
// for require.cache; reverted in v4.20.3 without a paired test.
158+
test('CJS-classified .ts entrypoint exposes __dirname, __filename, and require.cache', async () => {
159+
for (const { label, packageJson } of commonJsModes) {
160+
await using fixture = await createFixture({
161+
'package.json': createPackageJson(packageJson),
162+
'index.ts': outdent`
163+
require('./dep.cjs');
164+
console.log(JSON.stringify({
165+
dirname: __dirname,
166+
filename: __filename,
167+
requireCacheType: typeof require.cache,
168+
requireCacheHasKeys: Object.keys(require.cache).length > 0,
169+
}));
170+
`,
171+
'dep.cjs': 'module.exports = { loaded: true };',
172+
});
173+
174+
const result = await node.tsx(['index.ts'], fixture.path);
175+
onTestFail(() => {
176+
console.log(label, result);
177+
});
178+
179+
expect({
180+
failed: result.failed,
181+
exitCode: result.exitCode,
182+
stderr: result.stderr,
183+
}).toEqual({
184+
failed: false,
185+
exitCode: 0,
186+
stderr: '',
187+
});
188+
expect(JSON.parse(result.stdout)).toEqual({
189+
dirname: fixture.path,
190+
filename: fixture.getPath('index.ts'),
191+
requireCacheType: 'object',
192+
requireCacheHasKeys: true,
193+
});
194+
}
195+
});
196+
151197
// tsx is intentionally more lenient than Node for ambiguous-`type` and
152198
// explicit `"commonjs"` packages: a `.js`/`.ts` file that mixes ESM
153199
// `import`/`export` syntax with explicit `require()` calls still runs,

0 commit comments

Comments
 (0)