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

Support monorepos #129

Closed
Pajn opened this issue Jul 19, 2017 · 34 comments · Fixed by #907
Closed

Support monorepos #129

Pajn opened this issue Jul 19, 2017 · 34 comments · Fixed by #907

Comments

@Pajn
Copy link

Pajn commented Jul 19, 2017

It would be great if this plugin supported monorepos. Either by passing the --projects option to jest or by starting a jest process for every subproject (folder with package.json file in it). In the case of multiple Jest processes the current setting paths should be relative from each subproject.

@orta
Copy link
Member

orta commented Jul 19, 2017

As you can customise the command used to trigger jest (jest.pathToJest) then I think specific support for projects probably doesn't need to go in

@Pajn
Copy link
Author

Pajn commented Jul 19, 2017

I have tried adding a script to the root package.json with all projects specified with --projects and specifying yarn test -- as jest.pathToJest but then there are no changes detected even though the same command in the terminal detects changes and run just fine.

@glambert
Copy link

It does support monorepos, we have it working here for one of our projects using lerna. Jest resides at the root of your monorepo, correct? We added this to our .vscode/settings.json file:

"jest.pathToConfig": "./jest.config.js",
"jest.pathToJest": "./node_modules/.bin/jest",

@connectdotz
Copy link
Collaborator

connectdotz commented Sep 24, 2017

we also have a lot of problems with vscode-jest for our lerna managed monorepo.

we would like to have the root vscode workspace able to watch for all file changes in the packages, report test failures on the problems inspector and update test decorators just like in the single project case.

We have tried both approaches:

  1. use jest's monoreport support, i.e. use the projects in jest configuration.
    • problem 1: during "--showConfig", jest report different config file format that includes all package's config into "configs" (instead of "config" for single project), therefore vscode-jest failed to parse the config output and will fallback to the default settings, which currently only looking for js(x) pattern.
    • problem 2: if the combo config data exceed 8K, the data received in the child_process.spawn is truncated for some reason, at least on Mac.
    • problem 3: this is not vscode-jest issue, but jest didn't seem to be able to run jest --watch for monoreport, it got stuck at the first package, so this approach might simply not feasible at this point...
  2. use lerna's test support, i.e. "jest.pathToJest": "lerna run --parallel test --",
    • problem 1: there are many config file chunks reported back during the --showConfig, which vscode-jest didn't seem to know how to handle, so again it fallback to the default settings.
    • problem 2: the jest runner used the --outputFile with a tmp file when running the tests, lerna will just copy this command to every package, therefore they keep override each other's test result.
    • problem 3: lerna will prefix every output with the package name, which confuses vscode-jest many string based lookup, such as stringValue.startsWith("Test results written to")... in Runner.js.

To further complicate the issue, our packages are not uniformed, i.e. there are typescript, javascript, react and react-native, therefore the default settings, which only look for js(x) patterns, doesn't work for us.

approach 2 is working, as far as running jest with --watch, but vscode-jest simply can't parse the result and update the editor accordingly. approach 1, as mentioned above, is not working with or without vscode-jest.

Maybe we are missing something obvious, @ls-guillaume-lambert, do you mind sharing with us how you get it to work? Thx.

@glambert
Copy link

glambert commented Sep 25, 2017

We have a much simpler setup with only React components, no TypeScript or any extra layer. The approach I mentioned in #129 (comment) works for us, nothing else is in place other than those .vscode/settings.json configs.

@connectdotz
Copy link
Collaborator

thanks @ls-guillaume-lambert, so looks like you just run jest on the root project and has it watch and run for all tests below with the same jest config file. Yes that should work if all the tests are "uniform", i.e. same preset, rules, patterns etc. However, many monorepo projects are cross-platform and languages, it will be nice for vscode-jest to support a true "multi-jest" style monorepo...

@glambert
Copy link

Indeed, we are using the same preset/rules/patterns for all our packages. Best of luck with your setup 👍

@connectdotz
Copy link
Collaborator

ok, finally get the jest to work for our environment via command line. vscode-jest is still having quite a few problems:

  1. the jest 21.0.0+ has changed the output format in --showConfig, therefore, vscode-jest failed to parse the config. looks like there is already a PR but hasn't been accepted yet.
  2. vscode-jest doesn't report the failed test "suite", just the failed tests. So the tests in failed sub packages can be left out silently.
  3. vscode-jest do not show failed tests in the problem inspector until you open some test files.
  4. (feature) when vscode-jest first start up, it should run a full tests and report any test/test-suite failures in the problem inspector, then go into the watch mode. In addition to the bug mentioned above, vscode-jest just run jest in watch mode which will not guarantee to run all the tests initially. So maybe a 2 phase approach? run all tests once then go into the watch mode...

I will submit PR to address some of these issues...

@orta
Copy link
Member

orta commented Sep 27, 2017

^ These are great ideas 👍

@Bnaya
Copy link

Bnaya commented Dec 30, 2017

@connectdotz can you please share with me your setup? i'm having the same issue
Thanks!

@connectdotz
Copy link
Collaborator

@Bnaya sorry for the delay, basically you need a superset jest config with instructions for all of your packages.

Here is my jest config on the root/project level that will run jest for all packages including react-native package:

// jest.config.js
module.exports = {
  transform: {
    ".(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js",
    "^.+\\.js$": "<rootDir>/node_modules/babel-jest"
  },
  mapCoverage: true,
  bail: false,
  verbose: true,
  collectCoverageFrom: ["src/**/*.ts[x]?", "!src/**/*.test.ts[x]?", "!src/**/*.d.ts"],
  coveragePathIgnorePatterns: ["/__tests__/", "/node_modules/"],
  testEnvironment: "node",
  testRegex: "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js|jsx)$",
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "core", "node"],
  cacheDirectory: ".jest/cache",
  coverageDirectory: "coverage",
  coverageReporters: ["text-summary", "html"],
  testPathIgnorePatterns: [
    "/node_modules/",
    "/lib/",
    "/dist/",
    "/integration-tests/",
    "\\.snap$",
    "/build/",
    "/coverage/",
    "/packages/.*/build",
    "/packages/.*/dist",
    "/packages/.*/lib"
  ],
  modulePathIgnorePatterns: [
    "./packages/ites/node_modules/react-native/.*",
    "./packages/ites/node_modules/react-native/Libraries/react-native/"
  ],

  transformIgnorePatterns: ["node_modules/(?!(jest-)?react-native|react-clone-referenced-element|react-navigation)"],
  moduleNameMapper: {
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
      "<rootDir>/__mocks__/fileMock.js",
    "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
    "^React$": "<rootDir>/node_modules/react"
  },
  projects: ["<rootDir>/packages/*"],
  // hacking because jest couldn't find the react-native preset under packages/ites
  // copied from react-native/jest-preset.json
  haste: {
    defaultPlatform: "ios",
    platforms: ["android", "ios", "native"],
    providesModuleNodeModules: ["react-native"]
  },
  setupFiles: ["<rootDir>/packages/ites/node_modules/react-native/jest/setup.js"]
};

and my tsconfig.json for completion:

{
  "compilerOptions": {
    "jsx": "react",
    "outDir": "./lib",
    "experimentalDecorators": true,
    "module": "commonjs",
    "target": "es5",
    "lib": [
      "es6",
      "dom"
    ],
    "emitDecoratorMetadata": true,
    "sourceMap": true,
    "declaration": true,
    "rootDir": "src",
    "removeComments": false,
    "noUnusedLocals": true,
    "noUnusedParameters": true
  },
  "include": [
    "src/**/*",
    "packages/*/src/**/*"
  ],
  "exclude": [
    "node_modules",
    "build",
    "dist",
    "acceptance-tests",
    "webpack",
    "jest",
    "coverage",
    "src/setupTests.ts"
  ]
}

hope it help... good luck.

@Bnaya
Copy link

Bnaya commented Jan 4, 2018

@connectdotz Thanks!
So if i got it correctly, it does not support different setup/config for each package?
Like separate tsconfig.json when using ts-jest and

@connectdotz
Copy link
Collaborator

@Bnaya that is correct

@MaxboDev
Copy link

Would just like to add my name to the list of people who would love this feature. We have a monorepo and currently the only way for us to debug tests is to have a different instance of vs code open for each package.

@wldcordeiro
Copy link

A note that while this issue is about mono-repos the --projects argument isn't just for that and is also used for custom runners like jest-runner-eslint, jest-runner-stylelint, it'd be great to just see enhanced support for the projects feature where discovery of projects arrays in config or as argument lists for the command get output filtering like a dropdown that lets you pick which project to run.

@seanpoulter
Copy link
Member

seanpoulter commented May 25, 2018

I'll help you build it if you can help with an example repo and Jest setup @wldcordeiro.

@wldcordeiro
Copy link

@seanpoulter I don't have a repo on hand but I think we could make one with this as a starting point.

https://gist.github.com/wldcordeiro/6dc2eb97a26a52d548ed4aa86f2fc5c0

I pretty much lifted those as is from a real project.

@XBeg9
Copy link

XBeg9 commented Nov 22, 2018

Sometimes I lose a state in __tests__ and I need to resave test file to get UI changes. Anyone knows how to fix it?

@seanpoulter
Copy link
Member

Those symptoms sound familiar @XBeg9. That used to happen when Jest ran in watch mode and there were no changes. I'd suggest running the extension locally and setting a conditional breakpoint to fire when we're getting the data back from Jest and it's empty.

@XBeg9
Copy link

XBeg9 commented Nov 23, 2018

Sorry, not sure I understand this :) I'd suggest running the extension locally and setting a conditional breakpoint to fire when we're getting the data back from Jest and it's empty. @seanpoulter

@jsphstls
Copy link

This issue is pretty cold but as a new monorepo and vscode-jest user, this problem became evident fairly quick with no immediate solution. I really want to avoid extra files in the repo as a workaround.

@seanpoulter
Copy link
Member

Speaking for myself here, it's not clear that "we the maintainers" have much bandwidth these days. If you're motivated to move this forward @jsphstls, we could probably nudge @connectdotz and @ls-guillaume-lambert to weigh in on their experience and how we'd need to update the extension. From what I can gather from skimming the issue, the "solution" was to add extra setup per project.

@apiel
Copy link

apiel commented May 13, 2019

What's about to do something like that? (I didn't look at your code yet, but this would be an idea to get the root folder for the current active file)

import * as pkgUp from 'pkg-up';

async function getRootFolder(document: vscode.TextDocument) {
	const pkg = await pkgUp({ cwd: document.fileName });
	if (pkg) {
		const rootFolder = dirname(pkg);
		return rootFolder;
	}
}

export function activate(context: vscode.ExtensionContext) {
      // ... some code
		if (vscode.window.activeTextEditor) {
			const rootFolder = getRootFolder(vscode.window.activeTextEditor.document);
                        // ....
		}
}

@connectdotz
Copy link
Collaborator

for people with monorepo projects, multi-root support has finally arrived, feel free to give it a try: 3.0.0-preRelease ...

@borekb
Copy link

borekb commented Oct 1, 2019

The workspace feature didn't help in my case.

I have tests that contain JSX and are written in TypeScript, and here are two "manual" examples of how to possibly run the tests:

✅ This works:

yarn workspace @example/lib test

🚫 This doesn't work:

node_modules/.bin/jest packages/example/src/Test.tsx

The extension probably invokes the test close to the second example as I get the same, well-known error:

Jest encountered an unexpected token. This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

@schmod
Copy link

schmod commented Oct 23, 2019

Same – the workspace feature doesn't help me either. My only workspace root is the root of my monorepo. My individual packages are just in a packages directory.

If I set up an instance of vscode with my package as the workspace root, vscode-jest can't find Jest, because it's installed above the individual package.

@connectdotz
Copy link
Collaborator

this plugin does some simple "guess" of how to run your tests with jest, while it is right for most simple cases, it most likely will not be able to cover the more sophisticated use cases, and that is where jest.pathToJest customization comes in...

for your workspace folders (the directory under "packages" for most monorepo setup), you might need to customize the jest.pathToJest to tell this plugin how do you run your tests there.

For example, if you have a React package, most likely you are running yarn test or npm test there, you can add jest.pathTojest in vscode's folder setting accordingly; If all of your packages are running yarn test, then you only need to set up jest.pathToJest once in your workspace settings. (see here for vscode multi-root workspace settings). The setting you wangt to add will be something like this:

"jest.pathToJest": "yarn test",

As long as you can run your tests from your package, you can construct this plug in to do the same via the custom settings provided, such as jest.pathToJest...

@jsphstls
Copy link

I can confirm that the solution provided by @connectdotz does work for a collection of create-react-apps without typescript.

Bit of some-monorepo.code-workspace:

{
  "settings": {
    "jest.pathToJest": "yarn run jest", // the "jest" command exists in each package
    "jest.disabledWorkspaceFolders": ["Root"] // contains everything, would duplicate test runs
  },
  "folders": [
    {
      "name": "Root",
      "path": "."
    },
    {
      "name": "SomePackage",
      "path": "packages/some-package/"
    }
}

Bit of some-package/package.json:

{
  "name": "@namespace/some-package",
  "private": true,
  "scripts": {
    "jest": "react-scripts test"
  },
  "devDependencies": {
    "react-scripts": "^3.1.1"
  }
}

@amoshydra
Copy link

Goal

My goal is to get this vscode-jest "Debug" button to work with yarn workspaces and VS Code workspaces.

image

<root>/package.json

This is my yarn workspace configuration. The jest dependencies for my packages is installed in <root>/node_modules/jest. The dependencies DOES NOT live inside <root>/packages/@organization/**/node_modules

{
  "name": "project-name",
  "version": "0.0.0",
  "private": true,
  "workspaces": {
    "packages": [
      "packages/**"
    ]
  },

Solution that works for me

I manage to get it working with these configuration

<root>/project-name.code-workspace

{
  "folders": [
    {
      "name": "root",
      "path": "."
    },
    {
      "name": "@organization/project-abc",
      "path": "./packages/@organization/project-abc"
    }
  ],

  "settings": {
    "jest.pathToJest": "node_modules/.bin/jest",
    "jest.pathToConfig": "./jest.config.js",
  },
}

<root>/packages/@organization/project-abc/.vscode/launch.json

  1. Add a default jest launch configuration
    image
  2. Edit its program path to reference the root folder
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "name": "vscode-jest-tests",
      "request": "launch",
      "program": "${workspaceFolder}/../../../node_modules/jest/bin/jest"
      "args": [
        "--runInBand"
      ],
      "cwd": "${workspaceFolder}",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "disableOptimisticBPs": true,
    }
  ]
}

@lwyj123
Copy link

lwyj123 commented Jul 14, 2020

@amoshydra You saved my day !!!

@jasonwilliams
Copy link

jasonwilliams commented Sep 24, 2020

The activationEvents in this extension don't support monorepos: https://github.com/jest-community/vscode-jest/blob/master/package.json#L32-L38

    "workspaceContains:jest.config.js",
    "workspaceContains:jest.json",
    "workspaceContains:node_modules/.bin/jest",
    "workspaceContains:node_modules/react-scripts/node_modules/.bin/jest",
    "workspaceContains:node_modules/react-native-scripts",
    "onCommand:io.orta.jest.start"

should instead be

    "workspaceContains:**/jest.config.js",
    "workspaceContains:**/jest.json",
    "workspaceContains:**/node_modules/.bin/jest",
    "workspaceContains:**/node_modules/react-scripts/node_modules/.bin/jest",
    "workspaceContains:**/node_modules/react-native-scripts",
    "onCommand:io.orta.jest.start"

this should be a backwards compatible change as it will still work for files at the top level.

Whilst on the subject, I'm not 100% sure workspaceContains works for directories that are in .gitignore, so it might be worth getting rid of the /node_modules/ ones, and just work with the jest configs. microsoft/vscode#34711 (comment) microsoft/vscode#48674 (comment)

@sonic1981
Copy link

For those digging around looking for the actual solution to this, it is documented here

How to use the extension with monorepo projects?

@davidlbudiman
Copy link

Hello, I'm trying to setup for monorepo, but couldn't find the option to setup monorepo in Setup Tools.

Screenshot attached
image

@connectdotz
Copy link
Collaborator

connectdotz commented Dec 3, 2022

@davidlbudiman sorry for the late reply, that feature is in v5 pre-release, feel free to give it a spin and let us know how it works for you. Thanks.

legend1202 pushed a commit to legend1202/vscode-jest that referenced this issue Jun 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.