vscode-jest
vscode-jest copied to clipboard
Support monorepos
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.
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
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.
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",
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:
- 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...
- 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.
- problem 1: there are many config file chunks reported back during the
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.
We have a much simpler setup with only React components, no TypeScript or any extra layer. The approach I mentioned in https://github.com/orta/vscode-jest/issues/129#issuecomment-316704770 works for us, nothing else is in place other than those .vscode/settings.json
configs.
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...
Indeed, we are using the same preset/rules/patterns for all our packages. Best of luck with your setup 👍
ok, finally get the jest to work for our environment via command line. vscode-jest is still having quite a few problems:
- 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. - 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.
- vscode-jest do not show failed tests in the problem inspector until you open some test files.
- (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...
^ These are great ideas 👍
@connectdotz can you please share with me your setup? i'm having the same issue Thanks!
@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.
@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
@Bnaya that is correct
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.
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.
I'll help you build it if you can help with an example repo and Jest setup @wldcordeiro.
@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.
Sometimes I lose a state in __tests__
and I need to resave test file to get UI changes. Anyone knows how to fix it?
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.
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
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.
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.
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);
// ....
}
}
for people with monorepo projects, multi-root support has finally arrived, feel free to give it a try: 3.0.0-preRelease ...
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.
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.
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
...
I can confirm that the solution provided by @connectdotz does work for a collection of create-react-app
s 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"
}
}
Goal
My goal is to get this vscode-jest "Debug" button to work with yarn workspaces and VS Code workspaces.
<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
- Add a default jest launch configuration
- 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,
}
]
}
@amoshydra You saved my day !!!