Setup Jest Debug with a monorepo Create-React-App with TypeScript and VSCode

Viewed 1544

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

enter image description here

These are some of the methods that I've tried:

Here are some of the links that I've visited and tried.

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
    }
  ]
}
0 Answers
Related