Skip to content

Commit 9db028c

Browse files
authoredMar 6, 2025··
fix(nx-plugin): add check for nx version inside generator for Vite/Vitest (#1635)
1 parent 4242fbc commit 9db028c

File tree

5 files changed

+222
-13
lines changed

5 files changed

+222
-13
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import { Tree, addProjectConfiguration, writeJson } from '@nx/devkit';
2+
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
3+
import setupVitestGenerator from './generator';
4+
import {
5+
V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
6+
V19_X_ANALOG_JS_VITEST_ANGULAR,
7+
V19_X_JSDOM,
8+
V19_X_VITE_TSCONFIG_PATHS,
9+
V19_X_VITEST,
10+
V19_X_VITE,
11+
NX_X_LATEST_VITE,
12+
NX_X_LATEST_VITEST,
13+
} from '../../utils/versions/ng_19_X/versions';
14+
15+
describe('setup-vitest generator', () => {
16+
let tree: Tree;
17+
18+
beforeEach(() => {
19+
tree = createTreeWithEmptyWorkspace();
20+
21+
// Setup mock Angular project
22+
addProjectConfiguration(tree, 'test-app', {
23+
root: 'test-app',
24+
sourceRoot: 'test-app/src',
25+
projectType: 'application',
26+
targets: {},
27+
});
28+
29+
// Add package.json with Angular dependencies
30+
writeJson(tree, 'package.json', {
31+
dependencies: {
32+
'@angular/core': '19.0.0',
33+
'@nx/angular': '20.0.0',
34+
nx: '20.0.0',
35+
},
36+
devDependencies: {},
37+
});
38+
39+
// Add Angular project files
40+
writeJson(tree, 'test-app/tsconfig.json', {
41+
compilerOptions: {
42+
types: [],
43+
},
44+
include: [],
45+
});
46+
});
47+
48+
it('should add the correct dev dependencies', async () => {
49+
await setupVitestGenerator(tree, {
50+
project: 'test-app',
51+
});
52+
53+
const packageJson = JSON.parse(tree.read('package.json', 'utf-8'));
54+
expect(packageJson.devDependencies).toMatchObject({
55+
'@analogjs/vite-plugin-angular': V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
56+
'@analogjs/vitest-angular': V19_X_ANALOG_JS_VITEST_ANGULAR,
57+
vitest: V19_X_VITEST,
58+
jsdom: V19_X_JSDOM,
59+
vite: V19_X_VITE,
60+
'vite-tsconfig-paths': V19_X_VITE_TSCONFIG_PATHS,
61+
});
62+
});
63+
64+
it('should modify project configuration', async () => {
65+
await setupVitestGenerator(tree, {
66+
project: 'test-app',
67+
});
68+
69+
const projectConfig = JSON.parse(
70+
tree.read('test-app/project.json', 'utf-8'),
71+
);
72+
73+
expect(projectConfig.targets.test).toBeDefined();
74+
expect(projectConfig.targets.test.executor).toBe(
75+
'@analogjs/vitest-angular:test',
76+
);
77+
});
78+
79+
it('should create vite.config.mts with correct content', async () => {
80+
await setupVitestGenerator(tree, {
81+
project: 'test-app',
82+
});
83+
84+
expect(tree.exists('test-app/vite.config.mts')).toBeTruthy();
85+
const vitestConfig = tree.read('test-app/vite.config.mts', 'utf-8');
86+
expect(vitestConfig).toEqual(
87+
[
88+
'/// <reference types="vitest" />',
89+
'',
90+
`import angular from '@analogjs/vite-plugin-angular';`,
91+
'',
92+
`import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';`,
93+
'',
94+
`import { defineConfig } from 'vite';`,
95+
'',
96+
'// https://vitejs.dev/config/',
97+
'export default defineConfig(({ mode }) => {',
98+
' return {',
99+
' plugins: [angular(), nxViteTsPaths()],',
100+
' test: {',
101+
' globals: true,',
102+
" environment: 'jsdom',",
103+
" setupFiles: ['src/test-setup.ts'],",
104+
" include: ['**/*.spec.ts'],",
105+
" reporters: ['default'],",
106+
' },',
107+
' define: {',
108+
" 'import.meta.vitest': mode !== 'production',",
109+
' },',
110+
' };',
111+
'});',
112+
'',
113+
].join('\n'),
114+
);
115+
});
116+
117+
it('should update tsconfig.spec.json', async () => {
118+
// Create initial tsconfig.spec.json without files property
119+
writeJson(tree, 'test-app/tsconfig.spec.json', {
120+
compilerOptions: {
121+
types: ['node'],
122+
module: 'commonjs',
123+
},
124+
});
125+
126+
await setupVitestGenerator(tree, {
127+
project: 'test-app',
128+
});
129+
130+
const tsconfig = JSON.parse(
131+
tree.read('test-app/tsconfig.spec.json', 'utf-8'),
132+
);
133+
134+
// Check all modifications made by updateTsConfig
135+
expect(tsconfig.compilerOptions.module).toBeUndefined();
136+
expect(tsconfig.compilerOptions.target).toBe('es2016');
137+
expect(tsconfig.compilerOptions.types).toEqual(['node', 'vitest/globals']);
138+
expect(tsconfig.files).toEqual(['src/test-setup.ts']);
139+
});
140+
141+
it('should add vite 6 when using nx 20.5', async () => {
142+
// Setup with Nx 20.5
143+
writeJson(tree, 'package.json', {
144+
dependencies: {
145+
'@angular/core': '19.0.0',
146+
'@nx/angular': '20.5.0',
147+
},
148+
devDependencies: {},
149+
});
150+
151+
await setupVitestGenerator(tree, {
152+
project: 'test-app',
153+
});
154+
155+
const packageJson = JSON.parse(tree.read('package.json', 'utf-8'));
156+
expect(packageJson.devDependencies.vite).toBe(NX_X_LATEST_VITE); // '^6.0.0'
157+
expect(packageJson.devDependencies.vitest).toBe(NX_X_LATEST_VITEST); // '^3.0.0'
158+
});
159+
160+
it('should create test-setup.ts with correct content', async () => {
161+
await setupVitestGenerator(tree, {
162+
project: 'test-app',
163+
});
164+
165+
expect(tree.exists('test-app/src/test-setup.ts')).toBeTruthy();
166+
167+
const setupContent = tree.read('test-app/src/test-setup.ts', 'utf-8');
168+
expect(setupContent).toEqual(
169+
[
170+
`import '@analogjs/vitest-angular/setup-zone';`,
171+
'',
172+
'import {',
173+
' BrowserDynamicTestingModule,',
174+
' platformBrowserDynamicTesting,',
175+
`} from '@angular/platform-browser-dynamic/testing';`,
176+
`import { getTestBed } from '@angular/core/testing';`,
177+
'',
178+
'getTestBed().initTestEnvironment(',
179+
' BrowserDynamicTestingModule,',
180+
' platformBrowserDynamicTesting(),',
181+
');',
182+
'',
183+
].join('\n'),
184+
);
185+
});
186+
});

‎packages/nx-plugin/src/generators/setup-vitest/generator.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ export async function setupVitestGenerator(
3838
options: SetupVitestGeneratorSchema,
3939
) {
4040
const angularVersion = getInstalledPackageVersion(tree, '@angular/core');
41+
const nxVersion = getInstalledPackageVersion(tree, 'nx');
4142

42-
addAnalogDependencies(tree, angularVersion);
43+
addAnalogDependencies(tree, angularVersion, nxVersion);
4344
updateTsConfig(tree, options);
4445
updateTestTarget(tree, options);
4546

‎packages/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import { addDependenciesToPackageJson, Tree } from '@nx/devkit';
22

33
import { getAnalogDevDependencies } from '../../../utils/versions/dev-dependencies';
44

5-
export function addAnalogDependencies(tree: Tree, angularVersion: string) {
6-
const devDependencies = getAnalogDevDependencies(angularVersion);
5+
export function addAnalogDependencies(
6+
tree: Tree,
7+
angularVersion: string,
8+
nxVersion: string,
9+
) {
10+
const devDependencies = getAnalogDevDependencies(angularVersion, nxVersion);
711

812
addDependenciesToPackageJson(tree, {}, devDependencies);
913
}

‎packages/nx-plugin/src/utils/versions/dev-dependencies.ts

+24-8
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import {
4545
V19_X_VITE_TSCONFIG_PATHS,
4646
V19_X_VITEST,
4747
V19_X_VITE,
48+
NX_X_LATEST_VITE,
49+
NX_X_LATEST_VITEST,
4850
} from './ng_19_X/versions';
4951

5052
const devDependencyKeys = [
@@ -60,21 +62,29 @@ export type AnalogDevDependency = (typeof devDependencyKeys)[number];
6062

6163
export const getAnalogDevDependencies = (
6264
ngVersion: string,
65+
nxVersion?: string,
6366
): Record<AnalogDevDependency, string> => {
6467
const escapedNgVersion = ngVersion.replace(/[~^]/, '');
68+
const escapedNxVersion = nxVersion ? nxVersion.replace(/[~^]/, '') : null;
6569

66-
const devDependencies = getDevDependencies(escapedNgVersion);
70+
const devDependencies = getDevDependencies(
71+
escapedNgVersion,
72+
escapedNxVersion,
73+
);
6774

6875
return { ...devDependencies };
6976
};
7077

71-
const getDevDependencies = (escapedAngularVersion: string) => {
72-
// fail out for versions <15.2.0
78+
const getDevDependencies = (
79+
escapedAngularVersion: string,
80+
escapedNxVersion: string | null,
81+
) => {
82+
// fail out for versions <15.0.0
7383
if (lt(escapedAngularVersion, '15.0.0')) {
7484
throw new Error(stripIndents`Angular v15.0.0 or newer is required.`);
7585
}
7686

77-
// install 15.x deps for versions <15.0.0
87+
// install 15.x deps for versions <16.0.0
7888
if (lt(escapedAngularVersion, '16.0.0')) {
7989
return {
8090
'@analogjs/platform': V15_X_ANALOG_JS_PLATFORM,
@@ -117,7 +127,7 @@ const getDevDependencies = (escapedAngularVersion: string) => {
117127
}
118128

119129
// install 18.x deps for versions <19.0.0
120-
if (lt(escapedAngularVersion, '18.0.0')) {
130+
if (lt(escapedAngularVersion, '19.0.0')) {
121131
return {
122132
'@analogjs/platform': V18_X_ANALOG_JS_PLATFORM,
123133
'@analogjs/vite-plugin-angular': V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
@@ -130,15 +140,21 @@ const getDevDependencies = (escapedAngularVersion: string) => {
130140
};
131141
}
132142

133-
// return latest 19.x deps for versions >19.0.0
143+
// return latest 19.x deps for versions >=19.0.0
134144
return {
135145
'@analogjs/platform': V19_X_ANALOG_JS_PLATFORM,
136146
'@analogjs/vite-plugin-angular': V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
137147
'@analogjs/vitest-angular': V19_X_ANALOG_JS_VITEST_ANGULAR,
138148
'@nx/vite': V19_X_NX_VITE,
139149
jsdom: V19_X_JSDOM,
140150
'vite-tsconfig-paths': V19_X_VITE_TSCONFIG_PATHS,
141-
vite: V19_X_VITE,
142-
vitest: V19_X_VITEST,
151+
vite:
152+
escapedNxVersion && lt(escapedNxVersion, '20.5.0')
153+
? V19_X_VITE
154+
: NX_X_LATEST_VITE,
155+
vitest:
156+
escapedNxVersion && lt(escapedNxVersion, '20.5.0')
157+
? V19_X_VITEST
158+
: NX_X_LATEST_VITEST,
143159
};
144160
};

‎packages/nx-plugin/src/utils/versions/ng_19_X/versions.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ export const V19_X_NX_ANGULAR = '^20.0.0';
1515
export const V19_X_NX_VITE = '^20.0.0';
1616
export const V19_X_JSDOM = '^22.0.0';
1717
export const V19_X_VITE_TSCONFIG_PATHS = '^4.2.0';
18-
export const V19_X_VITEST = '^3.0.0';
19-
export const V19_X_VITE = '^6.0.0';
18+
export const V19_X_VITEST = '^2.0.0';
19+
export const V19_X_VITE = '^5.0.0';
20+
export const NX_X_LATEST_VITE = '^6.0.0';
21+
export const NX_X_LATEST_VITEST = '^3.0.0';

0 commit comments

Comments
 (0)
Please sign in to comment.