I've been hitting my head for about 7 hours now. But this is paramount as I can't afford not to develop tests within the app any further (Currently stuck debugging an Apollo React test)
I'm currently under a monorepo with a shared repository and 2 create-react app. I'm using CRACO (Create-React-App Configure Override), and I can't seem to execute a debugging statement using VScode. I've faced numerous issues: malformed jest commands, transformation problems (css modules not being parsed correctly), hung-up vscode, not found scripts, and many more. I'm stuck and I don't know what else to do.
The monorepo is setup using plain yarn workspaces (no Lerna nor bolt or pmp). It has a shared component (with storybook) and 2 create-react apps (app and home respectively). CRACO is used to apply the babel-loader to the shared component repo.
I'm able to run the tests with yarn: cross-env SKIP_PREFLIGHT_CHECK=true CI=true craco test --env=jest-environment-jsdom-sixteen --maxWorkers=4 --transformIgnorePatterns \"node_modules/(?!date-fns)/\", but I haven't been able to either use the traditional debugging or using The Jest Runner vscode extension which is what I want to run specific tests (currently only in the app folder).
Here's my monorepo structure
These are some of the methods that I've tried:
Here are some of the links that I've visited and tried.
- https://www.basefactor.com/using-visual-studio-code-to-debug-jest-based-unit-tests
- https://github.com/firsttris/vscode-jest-runner
- https://github.com/jest-community/vscode-jest/issues/129
- https://github.com/jest-community/vscode-jest/issues/244
- https://dev.to/shnydercom/monorepos-lerna-typescript-cra-and-storybook-combined-4hli
And many, many more.
I've also tried exporting the jest config using craco and pointing it to the path... nada.
Main (root) package.json
{
"name": "schon",
"version": "0.1.0",
"private": true,
"reactSnap": {
"inlineCss": true
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"dependencies": {
"@apollo/client": "^3.3.4",
"@auth0/auth0-react": "^1.2.0",
"@date-io/date-fns": "1.3.13",
"@material-ui/core": "4.11.1",
"@material-ui/icons": "4.9.1",
"@material-ui/lab": "^4.0.0-alpha.55",
"@material-ui/pickers": "^3.2.10",
"@material-ui/system": "4.9.14",
"@nivo/calendar": "0.67.0",
"@nivo/core": "0.67.0",
"@nivo/line": "0.67.0",
"@nivo/tooltip": "^0.67.0",
"@reach/router": "^1.3.3",
"@snowpack/app-scripts-react": "^2.0.0",
"auth0-js": "^9.13.2",
"aws-appsync-auth-link": "^2.0.3",
"aws-sdk": "^2.714.0",
"clsx": "^1.1.1",
"date-fns": "^2.14.0",
"dotenv": "^8.2.0",
"exceljs": "^4.2.0",
"file-saver": "^2.0.2",
"formik": "^2.1.4",
"formik-persist": "^1.1.0",
"graphql": "^15.0.0",
"immer": "^6.0.9",
"linkifyjs": "^2.1.9",
"lodash": "^4.17.15",
"logrocket": "^1.0.7",
"material-table": "^1.59.0",
"msw": "^0.24.2",
"randomcolor": "^0.6.2",
"react": "17.0.1",
"react-apollo": "^3.1.5",
"react-dom": "17.0.1",
"react-elastic-carousel": "^0.6.4",
"react-error-boundary": "^2.2.1",
"react-hook-form": "^6.3.0",
"react-loading-skeleton": "^2.1.1",
"react-prerendered-component": "^1.2.4",
"react-scripts": "4.0.1",
"snowpack": "^3.0.11",
"styled-components": "^5.2.1",
"suneditor": "^2.35.0",
"suneditor-react": "^2.13.1",
"sw-precache": "^5.2.1",
"tiny-slider-react": "^0.4.0",
"uglifyjs": "^2.4.11",
"uuid": "^8.2.0",
"validate-password": "^1.0.4",
"xlsx": "^0.16.1",
"yup": "^0.29.1"
},
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/helper-create-regexp-features-plugin": "^7.10.4",
"@craco/craco": "6.1.1",
"@react-theming/storybook-addon": "^1.0.3",
"@storybook/addon-actions": "^6.1.19",
"@storybook/addon-docs": "^6.1.19",
"@storybook/addon-essentials": "^6.1.19",
"@storybook/addon-knobs": "^6.1.19",
"@storybook/addon-links": "^6.1.19",
"@storybook/addon-storysource": "^6.1.19",
"@storybook/node-logger": "^6.1.19",
"@storybook/preset-create-react-app": "^3.1.6",
"@storybook/react": "^6.1.19",
"@testing-library/dom": "^7.29.0",
"@testing-library/jest-dom": "^5.11.1",
"@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.5.0",
"@types/auth0-js": "^9.13.1",
"@types/file-saver": "^2.0.1",
"@types/jest": "^26.0.16",
"@types/linkifyjs": "^2.1.3",
"@types/lodash": "^4.14.154",
"@types/memoize-one": "^5.1.2",
"@types/node": "^14.0.6",
"@types/randomcolor": "^0.5.5",
"@types/reach__router": "^1.3.5",
"@types/react": "17.0.0",
"@types/react-dom": "17.0.0",
"@types/tiny-slider-react": "^0.3.2",
"@types/uuid": "^8.0.0",
"@types/yup": "^0.29.1",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"bolt": "^0.24.5",
"cross-env": "^7.0.2",
"dynamic-cdn-webpack-plugin": "^5.0.0",
"eslint-config-airbnb-typescript": "^12.0.0",
"eslint-config-prettier": "^6.15.0",
"eslint-import-resolver-typescript": "^2.3.0",
"eslint-plugin-prettier": "^3.2.0",
"eslint-plugin-react": "^7.21.5",
"gulp": "^4.0.2",
"gulp-json-editor": "^2.5.4",
"gulp-replace": "^1.0.0",
"html-webpack-plugin": "^4.5.0",
"husky": "^4.3.0",
"jest-axe": "^3.4.0",
"jest-canvas-mock": "^2.3.0",
"jest-dom": "^4.0.0",
"jest-environment-jsdom-sixteen": "^1.0.3",
"lint-staged": "^10.5.2",
"microbundle": "^0.12.3",
"prettier": "2.0.5",
"react-is": "^16.13.1",
"react-snap": "^1.23.0",
"source-map-explorer": "^2.4.2",
"storybook-addon-material-ui": "^0.9.0-alpha.24",
"ts-jest": "^26.5.2",
"typescript": "4.1.2",
"uglify": "^0.1.5",
"webpack-cdn-plugin": "^3.3.1"
},
"bolt": {
"workspaces": [
"./app",
"./home",
"./components"
]
},
"workspaces": [
"./app",
"./home",
"./components"
]
}
app package.json:
{
"name": "app",
"version": "0.1.0",
"private": true,
"scripts": {
"circular-deps": "ts-node ccd.ts",
"analyze": "source-map-explorer 'build/static/js/*.js'",
"start-snowpack-not-working": "snowpack dev --config snowpack.config.js",
"start": "craco start --host 0.0.0.0",
"build": "cross-env SKIP_PREFLIGHT_CHECK=true NODE_OPTIONS=--max_old_space_size=4096 craco build && yarn run build-snap && yarn run enable-sw",
"build-snap": "react-snap && npm run generate-sw",
"enable-sw": "gulp snap-off",
"format": "prettier --write src/**/*.ts{,x}",
"lint": "eslint --ext .ts --ext .tsx src ",
"test:vscode": "cross-env SKIP_PREFLIGHT_CHECK=true craco --inspect-brk test",
"test": "cross-env SKIP_PREFLIGHT_CHECK=true CI=true craco test --env=jest-environment-jsdom-sixteen --maxWorkers=4 --transformIgnorePatterns \"node_modules/(?!date-fns)/\"",
"test:watch": "cross-env SKIP_PREFLIGHT_CHECK=true CI=true craco test --env=jest-environment-jsdom-sixteen --maxWorkers=4 --transformIgnorePatterns \"node_modules/(?!date-fns)/\" --watch",
"test:debug": "cross-env SKIP_PREFLIGHT_CHECK=true CI=true craco test --inspect-brk test --runInBand --no-cache --env=jest-environment-jsdom-sixteen --maxWorkers=4 --transformIgnorePatterns \"node_modules/(?!date-fns)/\"",
"eject": "react-scripts eject",
"generate-sw": "sw-precache --root=build --config scripts/sw-precache-config.js && uglifyjs build/service-worker.js -o build/service-worker.js"
},
"reactSnap": {
"inlineCss": true,
"puppeteerArgs": [
"--no-sandbox",
"--disable-setuid-sandbox"
]
},
"cracoConfig": "./craco.config.js",
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"dependencies": {
"@apollo/client": "^3.3.4",
"@auth0/auth0-react": "^1.2.0",
"@date-io/date-fns": "1.3.13",
"@material-ui/core": "4.11.1",
"@material-ui/icons": "4.9.1",
"@material-ui/lab": "^4.0.0-alpha.55",
"@material-ui/pickers": "^3.2.10",
"@material-ui/system": "4.9.14",
"@nivo/calendar": "0.67.0",
"@nivo/core": "0.67.0",
"@nivo/line": "0.67.0",
"@reach/router": "^1.3.3",
"@testing-library/jest-dom": "^5.11.1",
"aws-appsync-auth-link": "^2.0.3",
"aws-sdk": "^2.714.0",
"clsx": "^1.1.1",
"components": "*",
"date-fns": "^2.14.0",
"exceljs": "^3.9.0",
"file-saver": "^2.0.2",
"formik": "^2.1.4",
"formik-persist": "^1.1.0",
"graphql": "^15.0.0",
"immer": "^6.0.9",
"linkifyjs": "^2.1.9",
"lodash": "^4.17.15",
"logrocket": "^1.0.7",
"material-table": "^1.59.0",
"msw": "^0.24.2",
"randomcolor": "^0.6.2",
"react": "17.0.1",
"react-apollo": "^3.1.5",
"react-dom": "17.0.1",
"react-elastic-carousel": "^0.6.4",
"react-error-boundary": "^2.2.1",
"react-loading-skeleton": "^2.1.1",
"react-prerendered-component": "^1.2.4",
"react-scripts": "4.0.1",
"source-map-explorer": "^2.4.2",
"styled-components": "^5.2.1",
"suneditor-react": "^2.13.1",
"tiny-slider-react": "^0.4.0",
"uuid": "^8.2.0",
"validate-password": "^1.0.4",
"xlsx": "^0.16.1",
"yup": "^0.29.1"
},
"devDependencies": {
"uglify-js": "3.12.8",
"@craco/craco": "6.1.1",
"@testing-library/dom": "^7.29.0",
"@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.5.0",
"@types/auth0-js": "^9.13.1",
"@types/file-saver": "^2.0.1",
"@types/jest": "^26.0.16",
"@types/linkifyjs": "^2.1.3",
"@types/lodash": "^4.14.154",
"@types/node": "^14.0.6",
"@types/randomcolor": "^0.5.5",
"@types/reach__router": "^1.3.5",
"@types/react": "17.0.0",
"@types/react-dom": "17.0.0",
"@types/tiny-slider-react": "^0.3.2",
"@types/uuid": "^8.0.0",
"@types/yup": "^0.29.1",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"cross-env": "^7.0.2",
"dynamic-cdn-webpack-plugin": "^5.0.0",
"eslint-config-airbnb-typescript": "^12.0.0",
"eslint-config-prettier": "^6.15.0",
"eslint-import-resolver-typescript": "^2.3.0",
"eslint-plugin-prettier": "^3.2.0",
"eslint-plugin-react": "^7.21.5",
"gulp": "^4.0.2",
"gulp-json-editor": "^2.5.4",
"gulp-replace": "^1.0.0",
"html-webpack-plugin": "^4.5.0",
"husky": "^4.3.0",
"jest-axe": "^3.4.0",
"jest-canvas-mock": "^2.3.0",
"jest-dom": "^4.0.0",
"jest-environment-jsdom-sixteen": "^1.0.3",
"lint-staged": "^10.5.2",
"prettier": "2.0.5",
"react-snap": "^1.23.0",
"sw-precache": "^5.2.1",
"typescript": "4.1.2",
"webpack-cdn-plugin": "^3.3.1"
},
"resolutions": {
"apollo-client": "2.6.4"
}
}
The /app/craco.config.js file:
const path = require('path');
/**
* Allows us to edit create-react-app configuration
* without ejecting.
*
*
*/
const { getLoader, loaderByName } = require('@craco/craco');
const absolutePath = path.join(__dirname, '../components');
const schonComponents = path.join(
__dirname,
'./node_modules/@schon/components',
);
module.exports = {
webpack: {
configure: (webpackConfig, { env, paths }) => {
// https://medium.com/frontend-digest/using-create-react-app-in-a-monorepo-a4e6f25be7aa
const { isFound, match } = getLoader(
webpackConfig,
loaderByName('babel-loader'),
);
if (isFound) {
const include = Array.isArray(match.loader.include)
? match.loader.include
: [match.loader.include];
match.loader.include = include.concat(absolutePath, schonComponents);
}
return {
...webpackConfig,
optimization: {
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/,
)[1];
// npm package names are URL-safe, but some servers don't like @ symbols
return `npm.${packageName.replace('@', '')}`;
},
},
},
},
},
};
},
},
};
And some of the vscode test debugging configs:
{
"version": "0.2.0",
"configurations": [
// {
// "name": "Debug CRA Tests App",
// "type": "node",
// "request": "launch",
// "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/yarn",
// "args": ["workspace app test:debug"],
// "env": {
// "SKIP_PREFLIGHT_CHECK": "true"
// },
// "cwd": "${workspaceRoot}",
// "protocol": "inspector",
// "console": "integratedTerminal",
// "internalConsoleOptions": "neverOpen"
// },
{
"type": "node",
"name": "vscode-jest-tests",
"request": "launch",
"runtimeExecutable": "yarn",
"runtimeArgs": [
"workspace",
"app",
"test:vscode",
"--runInBand",
"--env=jest-environment-jsdom-sixteen",
"--transformIgnorePatterns \"node_modules/(?!date-fns)/\""
],
"args": [
// "--runInBand",
// "--fileDirname", // ADDING THE CURRENT FILENAME DIR FOR THE SCRIPT
// "${fileDirname}"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true
// "program": "${workspaceFolder}/tools/vscode-jest-tests/index.js" // THE SCRIPT
},
// {
// "name": "Debug CRA Tests",
// "type": "node",
// "request": "launch",
// "runtimeExecutable": "${workspaceRoot}/app/node_modules/.bin/craco",
// "runtimeArgs": [
// "test",
// "--config ${workspaceRoot}\\app\\craco.config.js",
// // "--runInBand",
// // "--no-cache",
// // "--env=jsdom",
// "--transformIgnorePatterns \"node_modules/(?!date-fns)/\"",
// "-t"
// ],
// "env": {
// "SKIP_PREFLIGHT_CHECK": "true"
// },
// "cwd": "${workspaceRoot}/app",
// "protocol": "inspector",
// "console": "integratedTerminal",
// "internalConsoleOptions": "neverOpen"
// }
{
"name": "Debug CRA Tests",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceRoot}/app/node_modules/.bin/react-scripts",
"args": [
"test",
"--runInBand",
"--no-cache",
"--watchAll=false",
"--config=jest.config.js"
],
"env": {
"CI": "true",
"SKIP_PREFLIGHT_CHECK": "true"
},
"cwd": "${workspaceRoot}/app",
"protocol": "inspector",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true
}
]
}
