NX → Vue & Jest Support

NX → Vue & Jest Support

Table of contents

NX → Vue & Jest Support

Some monorepos are having issues when trying to test and use jest among all the other technologies we choose for our project..

This solution fixes:

  • Disable some ionic/stencil packages to be transformed.
  • NX libraries supporting vue
  • NX-plus/vue resolving nx dynamic paths.
  • Typescript and ES issues from jest

All issues are described here:

https://github.com/ZachJW34/nx-plus/issues/245

https://github.com/nrwl/nx/issues/10100

https://github.com/ionic-team/ionic-framework/issues/25325

Steps to solve it:

  • Under your package.json make sure you have at least the next versions installed
    • List of requirements (especially "@nrwl/web": "^14.1.9")
"@nrwl/cli": "12.10.1",
"@nrwl/cypress": "^12.10.1",
"@nrwl/eslint-plugin-nx": "12.10.1",
"@nrwl/jest": "^12.10.1",
"@nrwl/linter": "^12.10.1",
"@nrwl/tao": "12.10.1",
**"@nrwl/web": "^14.1.9",**
"@nrwl/workspace": "12.10.1",
"@nx-plus/vue": "^12.2.0",
"@types/jest": "^27.0.2",
"@types/node": "14.14.33",
  • Edit your tsconfig.base.json to de able to declare and composite the file, also is important specify the targets(es2015), module(esnext) and allowJs to true.

    • Your tsconfig.base.json should have all this properties under compilerOptions

      {
        [....], 
        "compilerOptions": {
                "rootDir": ".",
            "sourceMap": true,
            "declaration": true,
            "composite": true,
            "moduleResolution": "node",
            "emitDecoratorMetadata": true,
            "esModuleInterop": true,
            "allowJs": true,
            "importHelpers": true,
            "target": "es2015",
            "module": "esnext",
            "lib": ["es2017", "dom"],
        }
      }
      
  • Edit your jest.config.ts file

    • Please, take specific attention to transformIgnorePatterns, here is where we solves the ionic issue.

      const { getJestProjects } = require('@nrwl/jest');
      
      module.exports = {
      projects: getJestProjects(),
      transformIgnorePatterns: ['/node_modules/(?!@ionic/core|@stencil/core|ionicons|swiper|ssr-window|dom7)'],
      preset: 'ts-jest',
      };
      
  • Create a babel root config

    • babel.config.json

        {
          "babelrcRoots": ["*"]
        }
      
  • Check your jest preset is the next one and change the file extension to cjs if required

      const nxPreset = require('@nrwl/jest/preset');
    
      module.exports = { ...nxPreset };
    
  • make sure your nx project declaration is pointing to your correct jest config file (could be workspase.json on the root or project.json under each lib or app)

  • Create a svg transformer file to avoid SVG transformations when testing
    • jestSVGTransform.js file will be placed at the root level.
module.exports = {
  process() {
    return 'module.exports = {};';
  },
  getCacheKey() {
    // The output is always the same.
    return 'svgTransform';
  },
};

After this editions, we need to make sure each of our libraries will understand what is going un in order to run the tests..

so, here are the steps

  • Make sure your library has these 2 files and its content looks like the described:

    • tsconfig.json

      {
      "extends": "../../tsconfig.base.json", // * PATH TO YOUR ROOT 
      "files": [],
      "include": [],
      "references": [
        {
          "path": "./tsconfig.lib.json"
        },
        {
          "path": "./tsconfig.spec.json"
        }
      ],
      "compilerOptions": {
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true
      }
      }
      
    • tsconfig.lib.json

      {
      "extends": "./tsconfig.json",
      "compilerOptions": {
        "outDir": "../../dist/out-tsc",
        "declaration": true,
        "types": []
      },
      "include": ["**/*.ts"],
      "exclude": ["jest.config.ts", "**/*.spec.ts"]
      }
      
    • tsconfig.spec.json

      {
      "extends": "./tsconfig.json",
      "compilerOptions": {
        "outDir": "../../dist/out-tsc",
        "module": "commonjs",
        "types": ["jest", "node"]
      },
      "include": [
        "jest.config.ts",
        "**/*.test.ts",
        "**/*.spec.ts",
        "**/*.test.tsx",
        "**/*.spec.tsx",
        "**/*.test.js",
        "**/*.spec.js",
        "**/*.test.jsx",
        "**/*.spec.jsx",
        "**/*.d.ts"
      ]
      }
      
  • Remove babel.config.json and create a new one called .babelrc

    • {
      "presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]]
      }
      
  • Edit your jest.config.ts

      export default {
        displayName: 'sample-lib',
        preset: '../../../jest.preset.cjs',
        testEnvironment: 'jsdom',
        globals: {
          'ts-jest': {
            tsconfig: '<rootDir>/tsconfig.spec.json',
          },
        },
        transform: {
            '^.+\\.[tj]sx?$': 'ts-jest',
          '^.+.vue$': 'vue3-jest',
          "^.+\\.svg$": "../../../jestSVGTransform.js"
        },
        moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
        coverageDirectory: '../../coverage/libs/sample-lib',
        transformIgnorePatterns: ['/node_modules/(?!@ionic/core|@stencil/core|ionicons|swiper|ssr-window|dom7)'],
      };
    

And that should be all you need to start running your tests ;)

I hope that helps you as much as it did to me ;)