build silently excludes any file path containing 'test' substring (Compiler.backendIgnoreFiles)
#15,341 opened on May 8, 2026
Repository metrics
- Stars
- (22,539 stars)
- PR merge metrics
- (Avg merge 10d 22h) (185 merged PRs in 30d)
Description
Summary
medusa build silently excludes any file whose path contains the substring test. The intent is clearly to skip directories like integration-tests/, test/, unit-tests/, but the implementation uses a naive String.includes() against the full path, so user-authored fixture/seed scripts with test in the filename (e.g. seed-test-accounts.ts, reset-test-vendor-password.ts) are dropped from the build with no warning.
Observed on @medusajs/framework@2.12.5 and @medusajs/medusa@2.12.5. Code path appears unchanged at the time of writing on latest (2.14.2).
Reproduction
-
In a Medusa app, add a script at
src/scripts/reset-test-vendor-password.ts:```ts import type { ExecArgs } from "@medusajs/framework/types" export default async function ({ container }: ExecArgs) { console.log("hello") } ```
-
Run `npx medusa build`.
-
Inspect `.medusa/server/src/scripts/` — `reset-test-vendor-password.js` is missing.
-
Rename to `reset-fixture-vendor-password.ts`, rebuild — file now appears.
-
Same outcome for `seed-test-x.ts`, `my-test-helper.ts`, etc.
Code citation
`@medusajs/framework/dist/build-tools/compiler.js`:
L54-59 — hardcoded ignore list: ```js __classPrivateFieldSet(this, _Compiler_backendIgnoreFiles, [ "integration-tests", "test", "unit-tests", "src/admin", ], "f"); ```
L398-402 — naive substring match against full path: ```js async function _Compiler_emitBuildOutput(tsConfig, chunksToIgnore, dist) { const ts = await ...; const filesToCompile = tsConfig.fileNames.filter((fileName) => { return !chunksToIgnore.some((chunk) => fileName.includes(`${chunk}`)); }); ```
Expected behavior
Skip files inside directories named `integration-tests/`, `test/`, `unit-tests/`, or `src/admin/` (matching path segments). Files named `test.ts` outside those directories should build normally.
Actual behavior
Any path containing the substring `test` anywhere — including in a filename — is filtered out. Affected our project today: 3 separate fixture/seed scripts had been tracked in the repo for weeks but never appeared in deployed builds.
Suggested fix
Match path segments rather than substrings. A few options:
- `fileName.includes(path.sep + chunk + path.sep)` — matches `/test/` directories but not `seed-test-x.ts`. Edge case: chunk at start/end of relative path needs separate handling.
- Compute segments via `path.relative(rootDir, fileName).split(path.sep)` and check `.includes(chunk)` against the array.
- Push the exclusion into `tsconfig.exclude` (proper glob semantics) instead of post-hoc filtering.
Impact
- Silent: no warning, no log. Files just don't appear in `.medusa/server/`.
- Non-obvious: user has to read `@medusajs/framework/dist/build-tools/compiler.js` to discover the cause.
- Real-world: 3 fixture/seed scripts in our app, including one that had been in the repo for ~2 months across 700+ commits without anyone noticing it never reached production.
Workaround
Rename any `test.ts` files to drop the `test` substring (we used `fixture.ts`).