fix(jest): stricter regex for 'server-only' in default config (#77588)
NextJest default `moduleNameMapper` configuration for `server-only`
matches any string that contains this substring, causing mocks of
matching dependencies to overwrite each others and the empty mock for
`import 'server-only';`. This changes makes the regex for the module
name more strict to ensure only the full string `server-only` is a
match.
### Why?
On my project, we thought it'd be a good idea to store our server-only
files under the directory `@/app/lib/server-only`. Unfortunately, this
made testing with Jest difficult due to `nextJest`'s default
configuration for `server-only`. Given a test file with:
```typescript
jest.mock('@/app/lib/server-only/one, () => ({
fnOne: jest.fn(),
}));
jest.mock('@/app/lib/server-only/two, () => ({
fnTwo: jest.fn(),
}));
```
The mocks for the dependency `@/app/lib/server-only/two` would overwrite
the mock of `@/app/lib/server-only/one` (that was overwriting the empty
mock for `server-only`) and thus `fnOne` would be `undefined`.
In our project, we've currently fixed the issue by patching the
configuration generated by `nextJest` using the stricter regexp in this
PR:
```typescript
// ...At the end of jest.config.ts
module.exports = async () => {
const jestConfig = await createJestConfig(config)();
if (
typeof jestConfig.moduleNameMapper !== 'undefined' &&
'server-only' in jestConfig.moduleNameMapper
) {
const value = jestConfig.moduleNameMapper['server-only'];
jestConfig.moduleNameMapper['^server-only$'] = value;
delete jestConfig.moduleNameMapper['server-only'];
}
return jestConfig;
};
```
## Verifications
I've checked that `pnpm build` and `pnpm test-unit` were unaffected.
This is the result of `pnpm test-unit`:
```
Test Suites: 199 passed, 199 total
Tests: 2 skipped, 1312 passed, 1314 total
Snapshots: 188 passed, 188 total
Time: 11.697 s
Ran all test suites matching /test\/unit\/|packages\/next\/|packages\/font/i.
```