CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nx--jest

Nx plugin for Jest testing with executors, generators, and configuration utilities for monorepo testing workflows.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

multi-project.mddocs/

Multi-Project Support

Utilities for working with Jest multi-project configurations in Nx workspaces. This functionality enables running Jest with multiple project configurations simultaneously, supporting complex monorepo testing scenarios.

Capabilities

Jest Projects Discovery

Automatically discover and collect Jest project configurations across the workspace.

/**
 * Get a list of paths to all Jest configuration files using Nx Jest executor
 * and @nx/run-commands executor running Jest. Used to configure Jest multi-project support.
 * @returns Promise resolving to array of Jest configuration file paths
 */
function getJestProjectsAsync(): Promise<string[]>;

Usage Examples:

import { getJestProjectsAsync } from "@nx/jest";

// Get all Jest project configurations
const jestProjects = await getJestProjectsAsync();
console.log(jestProjects);
// Output: [
//   '<rootDir>/apps/web-app/jest.config.ts',
//   '<rootDir>/libs/shared-ui/jest.config.ts',
//   '<rootDir>/libs/api-client/jest.config.ts'
// ]

// Use in root Jest configuration for multi-project setup
export default async () => ({
  projects: await getJestProjectsAsync()
});

// Add additional custom projects
export default async () => ({
  projects: [
    ...(await getJestProjectsAsync()),
    '<rootDir>/tools/custom-testing/jest.config.ts'
  ]
});

Multi-Project Configuration

The function integrates with Nx project graph to discover Jest configurations:

// Root jest.config.ts example using getJestProjectsAsync
import { getJestProjectsAsync } from '@nx/jest';

export default async () => ({
  projects: await getJestProjectsAsync(),
  // Global configuration for all projects
  coverageReporters: ['html', 'lcov', 'text-summary'],
  collectCoverageFrom: [
    '**/*.{js,jsx,ts,tsx}',
    '!**/*.d.ts',
    '!**/node_modules/**',
  ],
});

Project Detection Logic

The function discovers Jest projects by analyzing:

  1. Nx Jest Executor: Projects using @nx/jest:jest or @nrwl/jest:jest executor
  2. Run Commands Executor: Projects using nx:run-commands executor that run Jest
  3. Configuration Files: Direct analysis of Jest configuration file paths

Detection Examples:

// Detected from project.json with Jest executor
{
  "targets": {
    "test": {
      "executor": "@nx/jest:jest",
      "options": {
        "jestConfig": "apps/my-app/jest.config.ts"
      }
    }
  }
}

// Detected from run-commands executor
{
  "targets": {
    "test": {
      "executor": "nx:run-commands",
      "options": {
        "command": "jest --config=apps/my-app/jest.config.ts"
      }
    }
  }
}

Path Resolution

The function returns configuration paths in Jest-compatible format:

// Internal path processing
function getJestConfigProjectPath(projectJestConfigPath: string): string {
  return join('<rootDir>', projectJestConfigPath);
}

// Example transformation:
// Input: "apps/web-app/jest.config.ts"
// Output: "<rootDir>/apps/web-app/jest.config.ts"

Integration with Nx Project Graph

The function leverages Nx's project graph for efficient project discovery:

interface ProjectGraph {
  nodes: Record<string, ProjectGraphNode>;
  dependencies: Record<string, ProjectGraphDependency[]>;
}

interface ProjectGraphNode {
  name: string;
  type: string;
  data: ProjectConfiguration;
}

Project Graph Integration:

// Internal implementation pattern
export async function getJestProjectsAsync() {
  const graph = await createProjectGraphAsync({
    exitOnError: false,
    resetDaemonClient: true,
  });
  
  const jestConfigurations = new Set<string>();
  
  for (const node of Object.values(graph.nodes)) {
    const projectConfig = node.data;
    if (!projectConfig.targets) continue;
    
    for (const targetConfiguration of Object.values(projectConfig.targets)) {
      // Process Jest executors and run-commands
      if (targetConfiguration.executor === '@nx/jest:jest') {
        collectJestConfigFromJestExecutor(targetConfiguration, jestConfigurations);
      } else if (targetConfiguration.executor === 'nx:run-commands') {
        collectJestConfigFromRunCommandsExecutor(
          targetConfiguration,
          projectConfig.root,
          jestConfigurations
        );
      }
    }
  }
  
  return Array.from(jestConfigurations);
}

Command Parsing for Run Commands

For nx:run-commands executors, the function parses Jest commands to extract configuration paths:

// Example run-commands target
{
  "executor": "nx:run-commands",
  "options": {
    "command": "jest --config libs/my-lib/jest.config.ts --passWithNoTests"
  }
}

// Parsed to extract: "libs/my-lib/jest.config.ts"

Common Multi-Project Patterns

Workspace-Wide Testing

// jest.config.ts at workspace root
import { getJestProjectsAsync } from '@nx/jest';

export default async () => ({
  projects: await getJestProjectsAsync(),
  // Global settings apply to all projects
  verbose: false,
  collectCoverageFrom: [
    '**/*.{js,jsx,ts,tsx}',
    '!**/*.d.ts',
  ],
  coverageReporters: ['text-summary', 'html'],
  coverageDirectory: 'coverage'
});

Selective Project Testing

// Filter projects based on specific criteria
export default async () => {
  const allProjects = await getJestProjectsAsync();
  
  // Only include library projects
  const libProjects = allProjects.filter(path => 
    path.includes('/libs/')
  );
  
  return {
    projects: libProjects
  };
};

Mixed Configuration

// Combine auto-discovered projects with manual configurations
export default async () => ({
  projects: [
    ...(await getJestProjectsAsync()),
    // Add custom test configurations
    '<rootDir>/tools/integration-tests/jest.config.ts',
    '<rootDir>/e2e/jest.config.ts'
  ],
  globalSetup: '<rootDir>/tools/jest-global-setup.ts',
  globalTeardown: '<rootDir>/tools/jest-global-teardown.ts'
});

Performance Considerations

  • Caching: Project graph is cached for performance
  • Lazy Evaluation: Projects are discovered only when needed
  • Error Handling: Failed project graph creation doesn't block execution
  • Deduplication: Duplicate configuration paths are automatically removed

Migration Support

The function supports migration from legacy patterns:

// Legacy manual project list
export default {
  projects: [
    '<rootDir>/apps/app1/jest.config.ts',
    '<rootDir>/apps/app2/jest.config.ts',
    '<rootDir>/libs/lib1/jest.config.ts'
  ]
};

// Migrated to automatic discovery
export default async () => ({
  projects: await getJestProjectsAsync()
});

Error Handling

The function includes robust error handling:

  • Graph Creation Errors: Continues execution with empty project list
  • Invalid Configurations: Skips malformed Jest configurations
  • Missing Files: Handles references to non-existent configuration files
  • Permission Errors: Gracefully handles file system access issues

TypeScript Support

Full TypeScript support with proper type definitions:

import type { Config } from 'jest';
import { getJestProjectsAsync } from '@nx/jest';

const config: Config = {
  projects: await getJestProjectsAsync(),
  // Additional configuration with full type safety
};

export default config;

Install with Tessl CLI

npx tessl i tessl/npm-nx--jest

docs

config-management.md

index.md

multi-project.md

plugin-system.md

preset-config.md

project-configuration.md

test-execution.md

tile.json