From c031e5a1e8fa91309a96a2e1f897530e060499a2 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 19 Aug 2026 15:48:09 +0900 Subject: [PATCH] docs: add cjs support status in common errors (#11002) Co-authored-by: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Co-authored-by: OpenCode --- docs/config/injectcjsglobals.md | 2 +- docs/guide/common-errors.md | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/config/injectcjsglobals.md b/docs/config/injectcjsglobals.md index 8119828de..f5fecc307 100644 --- a/docs/config/injectcjsglobals.md +++ b/docs/config/injectcjsglobals.md @@ -43,5 +43,5 @@ ReferenceError: __dirname is not defined ::: warning This option doesn't affect externalized modules which are always executed by the native runtime. Node.js provides CommonJS variables to externalized CommonJS modules on its own. -Note that inlined CommonJS modules are not processed by Vite plugins even when this option is enabled: `require` calls always leave the module runner, so features like mocking do not apply to them. +Note that inlined CommonJS modules are not processed by Vite plugins even when this option is enabled: `require` calls always leave the module runner, so features like mocking do not apply to them. See [CommonJS source code is not fully supported](/guide/common-errors#commonjs-source-code-is-not-fully-supported) for configuration alternatives. ::: diff --git a/docs/guide/common-errors.md b/docs/guide/common-errors.md index 0e7025450..7bfffd058 100644 --- a/docs/guide/common-errors.md +++ b/docs/guide/common-errors.md @@ -217,3 +217,43 @@ export default defineConfig({ }, }) ``` + +## CommonJS source code is not fully supported + +Vitest is ESM-first. By default, source files run in Vite's [module runner](/config/experimental#experimental-vitemodulerunner), which provides CommonJS variables such as `require`, `module`, and `exports` for compatibility but does not reproduce Node.js CommonJS semantics completely. + +Calls to `require()` always use Node.js directly and leave the module runner. As a result: + +- Vite plugins, aliases, transforms, and module mocks do not apply to required files +- requiring TypeScript or other files that Node.js cannot execute is not supported +- importing and requiring the same file can evaluate it twice, which can break singleton state, object identity, or `instanceof` checks + +If your project uses CommonJS and doesn't need Vite transforms, set [`experimental.viteModuleRunner`](/config/experimental#experimental-vitemodulerunner) to `false` so the whole module graph is loaded by the native runtime: + +```ts [vitest.config.ts] +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + experimental: { + viteModuleRunner: false, + }, + }, +}) +``` + +If the application uses ESM source but imports a CommonJS package from the same monorepo, you can instead use [`server.deps.external`](/config/server#server-deps-external) to externalize the complete CommonJS package. This keeps its entry points and internal `require()` calls in the same native module cache. For example: + +```ts [vitest.config.ts] +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + server: { + deps: { + external: [/\/packages\/legacy-cjs\//], + }, + }, + }, +}) +``` -- 2.51.2