UNPKG

@nx/jest

Version:

The Nx Plugin for Jest contains executors and generators allowing your workspace to use the powerful Jest testing capabilities.

87 lines (86 loc) 3.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = default_1; const devkit_1 = require("@nx/devkit"); const internal_1 = require("@nx/js/internal"); const jsonc_parser_1 = require("jsonc-parser"); const config_file_1 = require("../../utils/config/config-file"); const FORMATTING_OPTIONS = { formattingOptions: { keepLines: true, insertSpaces: true, tabSize: 2 }, }; // A jest config mentioning any of these uses swc/babel/angular (or is the root // aggregator), not ts-jest, so skip it. const NON_TS_JEST_MARKERS = [ '@swc/jest', 'babel-jest', 'jest-preset-angular', 'getJestProjectsAsync', ]; /** * NXC-4591: ts-jest 29.2+ uses `moduleResolution: node10` on the CommonJS path * for TypeScript < 6, which ignores package `exports` and breaks exports-only * workspace libs (TS2307). `isolatedModules: true` makes ts-jest transpile per * file, skipping that resolution. TS >= 6 is unaffected. */ async function default_1(tree) { // TS >= 6 resolves `exports` under bundler + commonjs; not affected. if ((0, internal_1.isTypescriptVersionAtLeast)(tree, '6.0.0')) { return; } // Path-based workspaces resolve via tsconfig `paths`, not `exports`; skip them. if (!(0, internal_1.isUsingTsSolutionSetup)(tree)) { return; } // Fresh ts-solution workspaces already enable this in the base config. if (rootEnablesIsolatedModules(tree)) { return; } let count = 0; for (const [, project] of (0, devkit_1.getProjects)(tree)) { const specPath = getTsJestSpecTsconfig(tree, project.root); if (specPath && setIsolatedModules(tree, specPath)) { count++; } } if (count > 0) { devkit_1.logger.info(`NXC-4591: set "isolatedModules": true in ${count} tsconfig.spec.json file(s) so ts-jest resolves exports-only workspace libraries on TypeScript < 6.`); } await (0, devkit_1.formatFiles)(tree); } function rootEnablesIsolatedModules(tree) { return (readCompilerOption(tree, 'tsconfig.base.json', 'isolatedModules') === true); } // The project's tsconfig.spec.json if it runs ts-jest, else null. function getTsJestSpecTsconfig(tree, root) { const jestConfig = (0, config_file_1.findJestConfig)(tree, root); if (!jestConfig) { return null; } const source = tree.read(jestConfig, 'utf-8') ?? ''; if (NON_TS_JEST_MARKERS.some((marker) => source.includes(marker))) { return null; } const specPath = (0, devkit_1.joinPathFragments)(root, 'tsconfig.spec.json'); return tree.exists(specPath) ? specPath : null; } function setIsolatedModules(tree, tsconfigPath) { if (readCompilerOption(tree, tsconfigPath, 'isolatedModules') === true) { return false; } const contents = tree.read(tsconfigPath, 'utf-8'); if (!contents) { return false; } const edits = (0, jsonc_parser_1.modify)(contents, ['compilerOptions', 'isolatedModules'], true, FORMATTING_OPTIONS); tree.write(tsconfigPath, (0, jsonc_parser_1.applyEdits)(contents, edits)); return true; } function readCompilerOption(tree, tsconfigPath, option) { const contents = tree.read(tsconfigPath, 'utf-8'); if (!contents) { return undefined; } const root = (0, jsonc_parser_1.parseTree)(contents); const node = root && (0, jsonc_parser_1.findNodeAtLocation)(root, ['compilerOptions', option]); return node ? (0, jsonc_parser_1.getNodeValue)(node) : undefined; }