Test a monorepo with projects
This guide runs the tests of several packages from the repository root with Jest’s projects option. Each package
keeps its own config and base preset. The root config holds the watch plugins, because Jest reads watchPlugins from
the root config only.
-
Give each package its own Jest config with a base preset (not a
-watchpreset):packages/a/jest.config.mjs export default {preset: '@repobuddy/jest/presets/ts-esm',}packages/b/jest.config.cjs module.exports = {preset: '@repobuddy/jest/presets/js-cjs',}A
-watchpreset inside a project adds nothing. In a scratch run with Jest 30,jest --showConfigshowed nowatchPluginswhen only a project usedts-esm-watch. -
Create the root config with the
watchpreset and the project list:jest.config.mjs export default {preset: '@repobuddy/jest/presets/watch',projects: ['<rootDir>/packages/*'],} -
Install the packages every project’s preset needs where Jest can resolve them from that project. Jest reports a missing one as
Module @swc/jest in the transform option was not found, with the project’s<rootDir>. -
If any project uses an ESM preset, run Jest with
NODE_OPTIONS=--experimental-vm-modules.
Detection runs in the working directory
Section titled “Detection runs in the working directory”The presets decide two things when Jest loads them, and both use the directory Jest runs in, not the project’s
rootDir:
- The source folder (
configSource()). Run from the root, a project whose tests live insource/still getsroots: ['<rootDir>/src']if the root has nosourcefolder. Jest then fails withDirectory .../packages/b/src in the roots[0] option was not found. - ESM or CommonJS for
ts,ts-watch,jsdom-ts, andjsdom-ts-watch. Run from a root with"type": "module", a CommonJS project that usestsgets the@swc/jest(ESM) config.
These results come from scratch runs with Jest 30. To avoid both cases:
-
Use the explicit presets (
ts-esm,ts-cjs,jsdom-ts-esm,jsdom-ts-cjs) in projects. -
Use the same source folder name in every project, or set
rootsandcollectCoverageFromin the project config withconfigs.configSource():packages/b/jest.config.mjs import { configs } from '@repobuddy/jest'export default {preset: '@repobuddy/jest/presets/js-cjs',...configs.configSource('source'),}configSource('source')with an argument does no detection, and<rootDir>resolves per project.
Running Jest inside one package (cd packages/b && jest) detects that package’s folder and package.json.
Finished config
Section titled “Finished config”export default { preset: '@repobuddy/jest/presets/watch', projects: ['<rootDir>/packages/*'],}export default { preset: '@repobuddy/jest/presets/ts-esm',}Verify
Section titled “Verify”NODE_OPTIONS=--experimental-vm-modules jestWith two packages, the summary ends with Ran all test suites in 2 projects.. To confirm the watch plugins are set,
run jest --showConfig and look for watchPlugins in globalConfig.
Related
Section titled “Related”watchextract.extractPackages(): reads inlineprojectsobjects.