Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jest.config.js extension errors in a typescript monorepo #11399

Closed
dimitropoulos opened this issue May 11, 2021 · 7 comments
Closed

jest.config.js extension errors in a typescript monorepo #11399

dimitropoulos opened this issue May 11, 2021 · 7 comments

Comments

@dimitropoulos
Copy link
Contributor

dimitropoulos commented May 11, 2021

🐛 Bug Report

In the context of a TypeScript monorepo, TypeScript throws error ts(6059) when extending jest configs as recommended.

To Reproduce

see this codesandbox to view the error:
https://codesandbox.io/s/nostalgic-architecture-k5eob?file=/packages/client/jest.config.js:187-206

Expected behavior

no error when extending jest configs

Link to repl or repo (highly encouraged)

see this codesandbox to view the error:
https://codesandbox.io/s/nostalgic-architecture-k5eob?file=/packages/client/jest.config.js:187-206

envinfo

see this codesandbox to view the error:
https://codesandbox.io/s/nostalgic-architecture-k5eob?file=/packages/client/jest.config.js:187-206

Problem

In TypeScript monorepo projects, extending the jest.config.js like

├─┬ packages
│ ├─┬ client
│ │ ├── jest.config.js    // (! errors) extends ../../jest.config.js
│ │ └── tsconfig.json     // extends ../../tsconfig.base.json
│ └─┬ server
│   ├── jest.config.js    // uses JSON hack, no error
│   └── tsconfig.json     // extends ../../tsconfig.base.json
├── jest.config.js
└── tsconfig.base.json    // only contains `compilerOptions`

Where both tsconfig.jsons look like

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": ".",
  },
  "include": [
    "src",
    "jest.config.js"
  ]
}

The following error occurs in the client jest config

// Throws Error: "File '/sandbox/jest.config.js' is not under 'rootDir' '/sandbox/packages/server'. 'rootDir' is expected to contain all source files.ts(6059)"
const baseConfig = require("../../jest.config");

/** @type { import('@jest/types').Config.InitialOptions } */
module.exports = {
  ...baseConfig,

  // extensions of the base config go here, for example:
  collectCoverage: false
};

Workaround (hacky)

The only way I have found to work around this is to exploit an exception to the rules regarding rootDir that was made for json files (microsoft/TypeScript#9858 (comment)) and write the config like this:

const { readFileSync } = require("fs");

/** @type { import('@jest/types').Config.InitialOptions } */
const baseConfig = JSON.parse(
  readFileSync("../../jest.config.json").toString()
);

/** @type { import('@jest/types').Config.InitialOptions } */
module.exports = {
  ...baseConfig,

  // extensions of the base config go here, for example:
  collectCoverage: false
};

Other things I tried

I looked at every jest.config.js in this project to see if there's any other way, but non replicate this scenario.

I read through #10991 and #3564 and others but didn't see someone reporting this error.

Proposed Solution

What I am requesting is that instead of the above, I could simply write:

/** @type { import('@jest/types').Config.InitialOptions } */
module.exports = {
  extends: '../../jest.config.js',

  // extensions of the base config go here, for example:
  collectCoverage: false
};

Prior Art

@ahnpnl
Copy link
Contributor

ahnpnl commented May 11, 2021

Have you tried to extend jest config using presets? A practical example you can follow is looking at how Nrwl Nx does https://github.com/nrwl/nx-examples/blob/master/libs/products/home-page/jest.config.js

@dimitropoulos
Copy link
Contributor Author

This appears... to work. Thank you for the concrete example. So many of the things I'm using this for were explicitly listed as not working by a prior issue (with no correction) so I had wrongly assumed this use-case would present the same problems, but lo-and-behold many (all?) of them have since been fixed. Thanks!

I left some comments here #3564 (comment) that apply to this conversation (but, maybe moreso to that one).

@dimitropoulos
Copy link
Contributor Author

dimitropoulos commented May 13, 2021

So, I implemented this and it works for every package in our monorepo... except one. I can't seem to figure out why. Jest returns:

Preset ../../jest-preset.js not found.

For that one package (in packages/insomnia-app). The solution worked for all other packages and as far as I can tell the situation is identical... but apparently it isn't.

To demo this you can clone the repo, run npm run boostrap followed by npm run test.

If this is not related to the present GitHub issue, lemme know and I'll open up another issue for whatever is going on with this here.

@ahnpnl
Copy link
Contributor

ahnpnl commented May 15, 2021

I think the code sandbox example isn’t updated with your failed scenario.

@dimitropoulos
Copy link
Contributor Author

dimitropoulos commented May 16, 2021

I wish I could, but I don't know of a way to strictly reproduce this with codesandbox.

You can, however, reproduce it by cloning insomnia (https://github.com/Kong/insomnia/tree/develop) and looking at the jest-config in insonmia-app: https://github.com/Kong/insomnia/blob/develop/packages/insomnia-app/jest.config.js#L3

Uncomment line 3 to see the problem in action. You may need to run npm run bootstrap first, then run npm run test from the insomnia-app directory, or run npm run test from the root.

@dimitropoulos
Copy link
Contributor Author

I solved the issue I was having. Only too 10 days short of a year to see why.

So I have a project structure like this

- jest-preset.js
  - packages/
    - my-package/
      - src/
      - jest.config.js

and in my jest.config.js I had been specifying preset: '../../jest-preset.js'. The thing that drove me crazy is that I have other packages that do EXACTLY the same thing with the same project structure and they all work fine.

Well today I noticed (while debugging what has been a very painful jest 27 (now attempted jest 28) upgrade) that if I do ../../../jest-preset.js (adding the extra ../) that it suddenly works.

How could that be???

Well, I looked into it a little deeper and I noticed another line in my jest.config.js: rootDir: 'src'.

as it turns out. It looks like the rootDir can affect the path resolution of the preset.

Mystery solved.

I'll add a PR to the documentation to make this a little clearer.

@github-actions
Copy link

github-actions bot commented Jun 6, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants