Skip to content

Commit 9ef2938

Browse files
authored
Keep test-only source out of the published build (#218)
* fix: keep test-only source out of the published build (#217) The tsconfig exclude pointed at a stale path (src/server/tools/test-helpers.ts), so the real file (src/core/server/tools/test-helpers.ts) and the *.compile-test.ts brand guards were compiled into dist/ and shipped in the package. Split the build config from the typecheck config: tsconfig.build.json excludes all test code by pattern (won't rot if files move), while the base tsconfig still type-checks the compile-test guards. build/build:watch now use -p tsconfig.build.json. Adds a regression test that asks tsc which files the build config compiles and fails if any test module survives. * docs: note that the exclude patterns and TEST_CODE regexes must stay in sync Cross-reference tsconfig.build.json's exclude and the TEST_CODE regexes in build-excludes-test-code.test.ts so a new test-only suffix gets added in both.
1 parent ac3d3e1 commit 9ef2938

4 files changed

Lines changed: 66 additions & 3 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@
5050
},
5151
"scripts": {
5252
"clean": "node -e \"const fs=require('fs'); fs.rmSync('dist',{recursive:true,force:true});\"",
53-
"build": "npm run clean && npx tsc",
54-
"build:watch": "tsc --watch",
53+
"build": "npm run clean && npx tsc -p tsconfig.build.json",
54+
"build:watch": "tsc -p tsconfig.build.json --watch",
5555
"dev": "tsx watch src/index.ts",
5656
"start": "node dist/index.js",
5757
"smoke": "npm run build && node dist/index.js --help",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { execFileSync } from 'node:child_process';
2+
import path from 'node:path';
3+
import { fileURLToPath } from 'node:url';
4+
import { describe, expect, it } from 'vitest';
5+
6+
/**
7+
* Guards against test-only source leaking into the published build (#217).
8+
*
9+
* The stale `tsconfig.json` exclude pointed at a path that no longer matched
10+
* `test-helpers.ts`, so it (and the `.compile-test.ts` brand guards) shipped
11+
* into `dist/`. `tsconfig.build.json` now excludes test code by pattern; this
12+
* test asks tsc which files that config would compile and fails if any test
13+
* module is still in the program.
14+
*/
15+
16+
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
17+
const tscEntry = path.join(repoRoot, 'node_modules', 'typescript', 'bin', 'tsc');
18+
19+
function buildProgramSrcFiles(): string[] {
20+
const out = execFileSync(
21+
process.execPath,
22+
[tscEntry, '-p', 'tsconfig.build.json', '--listFilesOnly'],
23+
{ cwd: repoRoot, encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 }
24+
);
25+
return out
26+
.split('\n')
27+
.map((line) => line.trim())
28+
.filter(Boolean)
29+
.map((abs) => path.relative(repoRoot, abs).split(path.sep).join('/'))
30+
.filter((rel) => rel.startsWith('src/'));
31+
}
32+
33+
// Mirrors tsconfig.build.json's exclude — add any new test-only suffix to both.
34+
const TEST_CODE = [
35+
/\.test\.ts$/,
36+
/\.compile-test\.ts$/,
37+
/(^|\/)test-helpers\.ts$/,
38+
/(^|\/)__tests__\//,
39+
];
40+
41+
describe('build output excludes test code (#217)', () => {
42+
it('the build tsconfig compiles no test-only modules from src', () => {
43+
const files = buildProgramSrcFiles();
44+
// Guard against a vacuous pass: if the build config ever compiled nothing,
45+
// `leaked` would be empty while the real build is broken.
46+
expect(files).toContain('src/index.ts');
47+
const leaked = files.filter((f) => TEST_CODE.some((re) => re.test(f)));
48+
expect(leaked).toEqual([]);
49+
}, 60_000);
50+
});

tsconfig.build.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
// New test-only suffixes must also go in TEST_CODE in
4+
// src/__tests__/build-excludes-test-code.test.ts, which guards this list.
5+
"exclude": [
6+
"node_modules",
7+
"dist",
8+
"**/*.test.ts",
9+
"**/*.compile-test.ts",
10+
"**/test-helpers.ts",
11+
"**/__tests__/**"
12+
]
13+
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020
"typeRoots": ["./node_modules/@types"]
2121
},
2222
"include": ["src/**/*"],
23-
"exclude": ["node_modules", "dist", "**/*.test.ts", "src/server/tools/test-helpers.ts"]
23+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
2424
}

0 commit comments

Comments
 (0)