-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
vitest/coverage-istanbul crashes with TypeError: template is not a function when used with cloudflare/vitest-pool-workers #9935
Description
Describe the bug
When using vitest/[email protected] with cloudflare/[email protected], running tests with coverage fails immediately with:
TypeError: template is not a function
❯ requireVisitor node_modules/@vitest/coverage-istanbul/dist/provider.js:1024:40
❯ VitestModuleEvaluator._runInlinedModule node_modules/vitest/dist/module-evaluator.js:206:4
❯ ServerModuleRunner.directRequest node_modules/vite/dist/node/module-runner.js:1243:59
The error does not occur in a plain Vitest setup (without the Cloudflare Workers pool).
Root cause
The bundled provider.js imports babel/core via a default ESM import (import require$$0$3 from '@babel/core'), generated by rollup/plugin-commonjs during the build. When this import is resolved by Vite's ServerModuleRunner (used by cloudflare/vitest-pool-workers), it only detects CJS named exports declared via direct exports.X = ... assignments.
babel/core declares most of its exports (including template, parseSync, traverse) using Object.defineProperty(exports, ...) with lazy getters. These are invisible to Vite's CJS static analysis. Only 7 out of 34 exports are detected — the ones using direct assignment patterns.
The result: template is undefined on the imported object, and provider.js crashes when it tries to call it.
Used Package Manager
npm
Reproduction
Repo: temp-vitest-istanbul-repro
git clone https://github.com/mictian/temp-vitest-istanbul-repro
cd vitest-istanbul-repro
npm install
npm testThe repro contains:
- vitest.config.ts — uses cloudflareTest plugin + istanbul coverage
- wrangler.jsonc — minimal Cloudflare Workers config
- src/sum.ts + src/sum.test.ts — trivial test file
Suggested fix
In packages/coverage-istanbul/rollup.config.js, replace the ESM default import of babel/core with a createRequire call so it loads via Node's native CJS loader (which correctly handles Object.defineProperty exports).
I verified this locally by patching dist/provider.js:
- import require$$0$3 from '@babel/core';
+ import { createRequire as __createRequire } from 'node:module';
+ const __require = __createRequire(import.meta.url);
+ const require$$0$3 = __require('@babel/core');After patching, the coverage provider loads successfully with all 34 babel/core exports present.
A possible implementation in the rollup config would be a renderChunk plugin that rewrites the babel/core import to use createRequire.
System Info
System Info
- vitest: 4.1.0
- @vitest/coverage-istanbul: 4.1.0
- @cloudflare/vitest-pool-workers: 0.13.0
- Node: v22.x
- OS: macOSUsed Package Manager
npm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.