@nx/jest 23.1.0-beta.1 → 23.1.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/generators/configuration/files/common/tsconfig.spec.json__tmpl__ +2 -1
- package/dist/src/generators/configuration/lib/create-files.js +13 -6
- package/dist/src/migrations/update-23-1-0/set-ts-jest-isolated-modules.d.ts +8 -0
- package/dist/src/migrations/update-23-1-0/set-ts-jest-isolated-modules.js +86 -0
- package/dist/src/migrations/update-23-1-0/set-ts-jest-isolated-modules.md +41 -0
- package/migrations.json +9 -0
- package/package.json +5 -4
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"outDir": "<%= outDir %>",<% if (module) { %>
|
|
5
5
|
"module": "<%= module %>",<% } if (module === 'commonjs') { %>
|
|
6
|
-
"moduleResolution": "<%= moduleResolution %>",<% } if (
|
|
6
|
+
"moduleResolution": "<%= moduleResolution %>",<% } if (isolatedModules) { %>
|
|
7
|
+
"isolatedModules": true,<% } if (supportTsx) { %>
|
|
7
8
|
"jsx": "react-jsx",<% } %>"types": ["jest", "node"]
|
|
8
9
|
},<% if(setupFile !== 'none') { %>
|
|
9
10
|
"files": ["src/test-setup.ts"],<% } %>
|
|
@@ -46,6 +46,16 @@ function createFiles(tree, options, presetExt) {
|
|
|
46
46
|
const coverageDirectory = options.isTsSolutionSetup
|
|
47
47
|
? `test-output/jest/coverage`
|
|
48
48
|
: `${rootOffset}coverage/${projectRoot}`;
|
|
49
|
+
const usesTsJestModuleSettings = !options.isTsSolutionSetup || transformer === 'ts-jest';
|
|
50
|
+
const moduleResolution = usesTsJestModuleSettings
|
|
51
|
+
? (0, internal_1.getTsConfigModuleResolution)(tree)
|
|
52
|
+
: undefined;
|
|
53
|
+
// ts-jest forces `moduleResolution: node10` on the CommonJS path for
|
|
54
|
+
// TypeScript < 6, and node10 ignores package `exports`. Transpiling per file
|
|
55
|
+
// keeps exports-only workspace libraries resolvable. See NXC-4591.
|
|
56
|
+
const isolatedModules = options.isTsSolutionSetup &&
|
|
57
|
+
transformer === 'ts-jest' &&
|
|
58
|
+
moduleResolution === 'node10';
|
|
49
59
|
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, commonFilesFolder), projectConfig.root, {
|
|
50
60
|
tmpl: '',
|
|
51
61
|
...options,
|
|
@@ -64,12 +74,9 @@ function createFiles(tree, options, presetExt) {
|
|
|
64
74
|
outDir: options.isTsSolutionSetup
|
|
65
75
|
? `./out-tsc/jest`
|
|
66
76
|
: `${rootOffset}dist/out-tsc`,
|
|
67
|
-
module:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
moduleResolution: !options.isTsSolutionSetup || transformer === 'ts-jest'
|
|
71
|
-
? (0, internal_1.getTsConfigModuleResolution)(tree)
|
|
72
|
-
: undefined,
|
|
77
|
+
module: usesTsJestModuleSettings ? 'commonjs' : undefined,
|
|
78
|
+
moduleResolution,
|
|
79
|
+
isolatedModules,
|
|
73
80
|
});
|
|
74
81
|
if (options.setupFile !== 'angular') {
|
|
75
82
|
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, options.isTsSolutionSetup
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* NXC-4591: ts-jest 29.2+ uses `moduleResolution: node10` on the CommonJS path
|
|
4
|
+
* for TypeScript < 6, which ignores package `exports` and breaks exports-only
|
|
5
|
+
* workspace libs (TS2307). `isolatedModules: true` makes ts-jest transpile per
|
|
6
|
+
* file, skipping that resolution. TS >= 6 is unaffected.
|
|
7
|
+
*/
|
|
8
|
+
export default function (tree: Tree): Promise<void>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = default_1;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const internal_1 = require("@nx/js/internal");
|
|
6
|
+
const jsonc_parser_1 = require("jsonc-parser");
|
|
7
|
+
const config_file_1 = require("../../utils/config/config-file");
|
|
8
|
+
const FORMATTING_OPTIONS = {
|
|
9
|
+
formattingOptions: { keepLines: true, insertSpaces: true, tabSize: 2 },
|
|
10
|
+
};
|
|
11
|
+
// A jest config mentioning any of these uses swc/babel/angular (or is the root
|
|
12
|
+
// aggregator), not ts-jest, so skip it.
|
|
13
|
+
const NON_TS_JEST_MARKERS = [
|
|
14
|
+
'@swc/jest',
|
|
15
|
+
'babel-jest',
|
|
16
|
+
'jest-preset-angular',
|
|
17
|
+
'getJestProjectsAsync',
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* NXC-4591: ts-jest 29.2+ uses `moduleResolution: node10` on the CommonJS path
|
|
21
|
+
* for TypeScript < 6, which ignores package `exports` and breaks exports-only
|
|
22
|
+
* workspace libs (TS2307). `isolatedModules: true` makes ts-jest transpile per
|
|
23
|
+
* file, skipping that resolution. TS >= 6 is unaffected.
|
|
24
|
+
*/
|
|
25
|
+
async function default_1(tree) {
|
|
26
|
+
// TS >= 6 resolves `exports` under bundler + commonjs; not affected.
|
|
27
|
+
if ((0, internal_1.isTypescriptVersionAtLeast)(tree, '6.0.0')) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// Path-based workspaces resolve via tsconfig `paths`, not `exports`; skip them.
|
|
31
|
+
if (!(0, internal_1.isUsingTsSolutionSetup)(tree)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Fresh ts-solution workspaces already enable this in the base config.
|
|
35
|
+
if (rootEnablesIsolatedModules(tree)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
let count = 0;
|
|
39
|
+
for (const [, project] of (0, devkit_1.getProjects)(tree)) {
|
|
40
|
+
const specPath = getTsJestSpecTsconfig(tree, project.root);
|
|
41
|
+
if (specPath && setIsolatedModules(tree, specPath)) {
|
|
42
|
+
count++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (count > 0) {
|
|
46
|
+
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.`);
|
|
47
|
+
}
|
|
48
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
49
|
+
}
|
|
50
|
+
function rootEnablesIsolatedModules(tree) {
|
|
51
|
+
return (readCompilerOption(tree, 'tsconfig.base.json', 'isolatedModules') === true);
|
|
52
|
+
}
|
|
53
|
+
// The project's tsconfig.spec.json if it runs ts-jest, else null.
|
|
54
|
+
function getTsJestSpecTsconfig(tree, root) {
|
|
55
|
+
const jestConfig = (0, config_file_1.findJestConfig)(tree, root);
|
|
56
|
+
if (!jestConfig) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const source = tree.read(jestConfig, 'utf-8') ?? '';
|
|
60
|
+
if (NON_TS_JEST_MARKERS.some((marker) => source.includes(marker))) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const specPath = (0, devkit_1.joinPathFragments)(root, 'tsconfig.spec.json');
|
|
64
|
+
return tree.exists(specPath) ? specPath : null;
|
|
65
|
+
}
|
|
66
|
+
function setIsolatedModules(tree, tsconfigPath) {
|
|
67
|
+
if (readCompilerOption(tree, tsconfigPath, 'isolatedModules') === true) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const contents = tree.read(tsconfigPath, 'utf-8');
|
|
71
|
+
if (!contents) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const edits = (0, jsonc_parser_1.modify)(contents, ['compilerOptions', 'isolatedModules'], true, FORMATTING_OPTIONS);
|
|
75
|
+
tree.write(tsconfigPath, (0, jsonc_parser_1.applyEdits)(contents, edits));
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
function readCompilerOption(tree, tsconfigPath, option) {
|
|
79
|
+
const contents = tree.read(tsconfigPath, 'utf-8');
|
|
80
|
+
if (!contents) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const root = (0, jsonc_parser_1.parseTree)(contents);
|
|
84
|
+
const node = root && (0, jsonc_parser_1.findNodeAtLocation)(root, ['compilerOptions', option]);
|
|
85
|
+
return node ? (0, jsonc_parser_1.getNodeValue)(node) : undefined;
|
|
86
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#### Set isolatedModules for ts-jest below TypeScript 6
|
|
2
|
+
|
|
3
|
+
The jest 30 path of `@nx/jest` bumps ts-jest to 29.4.x.
|
|
4
|
+
On the CommonJS jest path, ts-jest 29.2+ uses `moduleResolution: node10` when `bundler` is invalid alongside the forced `module: commonjs`, which is the case below TypeScript 6.
|
|
5
|
+
`node10` does not read package `exports` maps, so a workspace library that exposes types only through `exports` fails to resolve during the ts-jest type check:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
error TS2307: Cannot find module '@my-org/some-lib' or its corresponding type declarations.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The migration sets `isolatedModules: true` in each affected `tsconfig.spec.json`, so ts-jest transpiles each file independently and skips the cross-file type resolution that was failing.
|
|
12
|
+
This matches the `isolatedModules: true` that fresh ts-solution workspaces already set in `tsconfig.base.json`.
|
|
13
|
+
Type checking stays on each project's dedicated typecheck target.
|
|
14
|
+
|
|
15
|
+
The migration runs only below TypeScript 6, in ts-solution workspaces that do not already enable `isolatedModules`.
|
|
16
|
+
TypeScript 6 and above resolves `exports` under `bundler` with `commonjs`, so those workspaces are left unchanged.
|
|
17
|
+
|
|
18
|
+
#### Sample code changes
|
|
19
|
+
|
|
20
|
+
##### Before
|
|
21
|
+
|
|
22
|
+
```json title="tsconfig.spec.json"
|
|
23
|
+
{
|
|
24
|
+
"extends": "../../tsconfig.base.json",
|
|
25
|
+
"compilerOptions": {
|
|
26
|
+
"types": ["jest", "node"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
##### After
|
|
32
|
+
|
|
33
|
+
```json title="tsconfig.spec.json" {4}
|
|
34
|
+
{
|
|
35
|
+
"extends": "../../tsconfig.base.json",
|
|
36
|
+
"compilerOptions": {
|
|
37
|
+
"isolatedModules": true,
|
|
38
|
+
"types": ["jest", "node"]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
package/migrations.json
CHANGED
|
@@ -77,6 +77,15 @@
|
|
|
77
77
|
"description": "Rename imports of `createNodesV2` from `@nx/jest/plugin` to the canonical `createNodes` export.",
|
|
78
78
|
"implementation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes",
|
|
79
79
|
"documentation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes.md"
|
|
80
|
+
},
|
|
81
|
+
"set-ts-jest-isolated-modules": {
|
|
82
|
+
"version": "23.1.0-beta.3",
|
|
83
|
+
"requires": {
|
|
84
|
+
"ts-jest": ">=29.2.0"
|
|
85
|
+
},
|
|
86
|
+
"description": "Set `isolatedModules: true` in `tsconfig.spec.json` for ts-jest projects on TypeScript < 6. ts-jest 29.2+ forces `moduleResolution: node10` on the CommonJS path, which ignores package `exports` maps and breaks (TS2307) resolution of exports-only workspace libraries; transpiling per file avoids the type-resolution failure.",
|
|
87
|
+
"implementation": "./dist/src/migrations/update-23-1-0/set-ts-jest-isolated-modules",
|
|
88
|
+
"documentation": "./dist/src/migrations/update-23-1-0/set-ts-jest-isolated-modules.md"
|
|
80
89
|
}
|
|
81
90
|
},
|
|
82
91
|
"packageJsonUpdates": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/jest",
|
|
3
|
-
"version": "23.1.0-beta.
|
|
3
|
+
"version": "23.1.0-beta.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"files": [
|
|
@@ -110,17 +110,18 @@
|
|
|
110
110
|
"jest-config": "^30.0.2",
|
|
111
111
|
"jest-resolve": "^30.0.2",
|
|
112
112
|
"jest-util": "^30.0.2",
|
|
113
|
+
"jsonc-parser": "^3.2.0",
|
|
113
114
|
"minimatch": "10.2.5",
|
|
114
115
|
"picocolors": "^1.1.0",
|
|
115
116
|
"resolve.exports": "2.0.3",
|
|
116
117
|
"semver": "^7.6.3",
|
|
117
118
|
"tslib": "^2.3.0",
|
|
118
119
|
"yargs-parser": "21.1.1",
|
|
119
|
-
"@nx/
|
|
120
|
-
"@nx/
|
|
120
|
+
"@nx/devkit": "23.1.0-beta.3",
|
|
121
|
+
"@nx/js": "23.1.0-beta.3"
|
|
121
122
|
},
|
|
122
123
|
"devDependencies": {
|
|
123
|
-
"nx": "23.1.0-beta.
|
|
124
|
+
"nx": "23.1.0-beta.3"
|
|
124
125
|
},
|
|
125
126
|
"publishConfig": {
|
|
126
127
|
"access": "public"
|