diff --git a/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap b/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap
index c6f479f6af860..80ac4eabd74b5 100644
--- a/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap
+++ b/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap
@@ -10,6 +10,7 @@ exports[`@nrwl/vite:configuration library mode should add config for building li
import { join } from 'path';
export default defineConfig({
+ cacheDir: '../node_modules/.vite/my-lib',
@@ -67,6 +68,7 @@ exports[`@nrwl/vite:configuration library mode should set up non buildable libra
import { join } from 'path';
export default defineConfig({
+ cacheDir: '../../node_modules/.vite/react-lib-nonb-jest',
@@ -190,7 +192,7 @@ import { defineConfig } from 'vite';
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
- build: {
+ cacheDir: '../../node_modules/.vite/react-lib-nonb-vitest',build: {
lib: {
// Could also be a dictionary or array of multiple entry points.
entry: 'src/index.ts',
@@ -382,6 +384,7 @@ exports[`@nrwl/vite:configuration transform React app to use Vite should create
export default defineConfig({
+ cacheDir: '../../node_modules/.vite/my-test-react-app',
server:{
port: 4200,
@@ -546,6 +549,7 @@ exports[`@nrwl/vite:configuration transform Web app to use Vite should create vi
export default defineConfig({
+ cacheDir: '../../node_modules/.vite/my-test-web-app',
server:{
port: 4200,
@@ -699,6 +703,7 @@ exports[`@nrwl/vite:configuration vitest should create a vitest configuration if
export default defineConfig({
+ cacheDir: '../../node_modules/.vite/my-test-react-app',
server:{
port: 4200,
diff --git a/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap b/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap
index b498c4ef5ecfe..f974d110cf105 100644
--- a/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap
+++ b/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap
@@ -9,6 +9,7 @@ exports[`vitest generator insourceTests should add the insourceSource option in
export default defineConfig({
+ cacheDir: '../../node_modules/.vite/my-test-react-app',
@@ -54,6 +55,7 @@ exports[`vitest generator vite.config should create correct vite.config.ts file
export default defineConfig({
+ cacheDir: '../../node_modules/.vite/my-test-react-app',
@@ -97,6 +99,7 @@ exports[`vitest generator vite.config should create correct vite.config.ts file
export default defineConfig({
+ cacheDir: '../../node_modules/.vite/react-lib-nonb-jest',
diff --git a/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap b/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap
index af488af0c5b0e..918d06fd87eff 100644
--- a/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap
+++ b/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`ensureBuildOptionsInViteConfig should add build and test options if defineConfig is empty 1`] = `
+exports[`ensureViteConfigIsCorrect should add build and test options if defineConfig is empty 1`] = `
"import dts from 'vite-plugin-dts';
import { join } from 'path';
@@ -49,7 +49,7 @@ import { join } from 'path';
"
`;
-exports[`ensureBuildOptionsInViteConfig should add build option but not update test option if test already setup 1`] = `
+exports[`ensureViteConfigIsCorrect should add build option but not update test option if test already setup 1`] = `
"import dts from 'vite-plugin-dts';
import { join } from 'path';
import { defineConfig } from 'vite';
@@ -89,6 +89,7 @@ import { defineConfig } from 'vite';
],
test: {
+ ...{
globals: true,
cache: {
dir: '../../node_modules/.vitest',
@@ -96,12 +97,14 @@ import { defineConfig } from 'vite';
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
+ ...{\\"globals\\":true,\\"cache\\":{\\"dir\\":\\"../node_modules/.vitest\\"},\\"environment\\":\\"jsdom\\",\\"include\\":[\\"src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\\"]}
+ },
});
"
`;
-exports[`ensureBuildOptionsInViteConfig should add build options if build options don't exist 1`] = `
+exports[`ensureViteConfigIsCorrect should add build options if build options don't exist 1`] = `
"import dts from 'vite-plugin-dts';
import { join } from 'path';
import { defineConfig } from 'vite';
@@ -141,6 +144,7 @@ import { defineConfig } from 'vite';
],
test: {
+ ...{
globals: true,
cache: {
dir: '../../node_modules/.vitest',
@@ -148,12 +152,14 @@ import { defineConfig } from 'vite';
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
+ ...{\\"globals\\":true,\\"cache\\":{\\"dir\\":\\"../node_modules/.vitest\\"},\\"environment\\":\\"jsdom\\",\\"include\\":[\\"src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\\"]}
+ },
});
"
`;
-exports[`ensureBuildOptionsInViteConfig should add build options if defineConfig is not used 1`] = `
+exports[`ensureViteConfigIsCorrect should add build options if defineConfig is not used 1`] = `
"import dts from 'vite-plugin-dts';
import { join } from 'path';
import { defineConfig } from 'vite';
@@ -202,7 +208,7 @@ import { defineConfig } from 'vite';
"
`;
-exports[`ensureBuildOptionsInViteConfig should add build options if it is using conditional config - do nothing for test 1`] = `
+exports[`ensureViteConfigIsCorrect should add build options if it is using conditional config - do nothing for test 1`] = `
"
///
import { defineConfig } from 'vite';
@@ -225,7 +231,7 @@ exports[`ensureBuildOptionsInViteConfig should add build options if it is using
"
`;
-exports[`ensureBuildOptionsInViteConfig should add new build options if some build options already exist 1`] = `
+exports[`ensureViteConfigIsCorrect should add new build options if some build options already exist 1`] = `
"import dts from 'vite-plugin-dts';
import { join } from 'path';
import { defineConfig } from 'vite';
@@ -248,6 +254,7 @@ import { defineConfig } from 'vite';
],
test: {
+ ...{
globals: true,
cache: {
dir: '../../node_modules/.vitest',
@@ -255,6 +262,8 @@ import { defineConfig } from 'vite';
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
+ ...{\\"globals\\":true,\\"cache\\":{\\"dir\\":\\"../node_modules/.vitest\\"},\\"environment\\":\\"jsdom\\",\\"include\\":[\\"src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\\"]}
+ },
build: {
...{
@@ -267,17 +276,18 @@ import { defineConfig } from 'vite';
"
`;
-exports[`ensureBuildOptionsInViteConfig should not do anything if cannot understand syntax of vite config 1`] = `"console.log('Unknown syntax')"`;
+exports[`ensureViteConfigIsCorrect should not do anything if cannot understand syntax of vite config 1`] = `"console.log('Unknown syntax')"`;
-exports[`ensureBuildOptionsInViteConfig should not do anything if project has everything setup already 1`] = `
-"
- ///
- import { defineConfig } from 'vite';
+exports[`ensureViteConfigIsCorrect should not do anything if project has everything setup already 1`] = `
+"import dts from 'vite-plugin-dts';
+import { join } from 'path';
+import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import viteTsConfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
plugins: [
+ ...[
dts({
tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
// Faster builds by skipping tests. Set this to false to enable type checking.
@@ -288,10 +298,17 @@ exports[`ensureBuildOptionsInViteConfig should not do anything if project has ev
root: '../../../',
}),
],
+ dts({
+ tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
+ // Faster builds by skipping tests. Set this to false to enable type checking.
+ skipDiagnostics: true,
+ }),
+ ],
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
build: {
+ ...{
lib: {
// Could also be a dictionary or array of multiple entry points.
entry: 'src/index.ts',
@@ -306,8 +323,11 @@ exports[`ensureBuildOptionsInViteConfig should not do anything if project has ev
external: ['react', 'react-dom', 'react/jsx-runtime'],
},
},
+ ...{\\"lib\\":{\\"entry\\":\\"src/index.ts\\",\\"name\\":\\"my-app\\",\\"fileName\\":\\"index\\",\\"formats\\":[\\"es\\",\\"cjs\\"]},\\"rollupOptions\\":{\\"external\\":[\\"'react', 'react-dom', 'react/jsx-runtime'\\"]}}
+ },
test: {
+ ...{
globals: true,
cache: {
dir: '../../../node_modules/.vitest',
@@ -315,11 +335,13 @@ exports[`ensureBuildOptionsInViteConfig should not do anything if project has ev
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
+ ...{\\"globals\\":true,\\"cache\\":{\\"dir\\":\\"../node_modules/.vitest\\"},\\"environment\\":\\"jsdom\\",\\"include\\":[\\"src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\\"]}
+ },
});
"
`;
-exports[`ensureBuildOptionsInViteConfig should update both test and build options - keep existing settings 1`] = `
+exports[`ensureViteConfigIsCorrect should update both test and build options - keep existing settings 1`] = `
"import dts from 'vite-plugin-dts';
import { join } from 'path';
import { defineConfig } from 'vite';
diff --git a/packages/vite/src/utils/generator-utils.ts b/packages/vite/src/utils/generator-utils.ts
index 21f626f281379..c8e4a4bc8041d 100644
--- a/packages/vite/src/utils/generator-utils.ts
+++ b/packages/vite/src/utils/generator-utils.ts
@@ -14,7 +14,7 @@ import { ViteDevServerExecutorOptions } from '../executors/dev-server/schema';
import { VitePreviewServerExecutorOptions } from '../executors/preview-server/schema';
import { VitestExecutorOptions } from '../executors/test/schema';
import { Schema } from '../generators/configuration/schema';
-import { ensureBuildOptionsInViteConfig } from './vite-config-edit-utils';
+import { ensureViteConfigIsCorrect } from './vite-config-edit-utils';
export type Target = 'build' | 'serve' | 'test' | 'preview';
export type TargetFlags = Partial>;
@@ -550,6 +550,10 @@ export function createOrEditViteConfig(
// ],
// },`;
+ const cacheDir = `cacheDir: '${offsetFromRoot(
+ projectConfig.root
+ )}node_modules/.vite/${options.project}',`;
+
if (tree.exists(viteConfigPath)) {
handleViteConfigFileExists(
tree,
@@ -560,6 +564,7 @@ export function createOrEditViteConfig(
dtsImportLine,
pluginOption,
testOption,
+ cacheDir,
offsetFromRoot(projectConfig.root),
projectAlreadyHasViteTargets
);
@@ -574,6 +579,7 @@ export function createOrEditViteConfig(
${dtsImportLine}
export default defineConfig({
+ ${cacheDir}
${devServerOption}
${previewServerOption}
${pluginOption}
@@ -725,6 +731,7 @@ function handleViteConfigFileExists(
dtsImportLine: string,
pluginOption: string,
testOption: string,
+ cacheDir: string,
offsetFromRoot: string,
projectAlreadyHasViteTargets?: TargetFlags
) {
@@ -757,7 +764,7 @@ function handleViteConfigFileExists(
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
};
- const changed = ensureBuildOptionsInViteConfig(
+ const changed = ensureViteConfigIsCorrect(
tree,
viteConfigPath,
buildOption,
@@ -767,6 +774,7 @@ function handleViteConfigFileExists(
pluginOption,
testOption,
testOptionObject,
+ cacheDir,
projectAlreadyHasViteTargets
);
diff --git a/packages/vite/src/utils/vite-config-edit-utils.spec.ts b/packages/vite/src/utils/vite-config-edit-utils.spec.ts
index 69aefaadc2707..f30247af9fe88 100644
--- a/packages/vite/src/utils/vite-config-edit-utils.spec.ts
+++ b/packages/vite/src/utils/vite-config-edit-utils.spec.ts
@@ -18,9 +18,9 @@ import {
testOption,
testOptionObject,
} from './test-files/test-vite-configs';
-import { ensureBuildOptionsInViteConfig } from './vite-config-edit-utils';
+import { ensureViteConfigIsCorrect } from './vite-config-edit-utils';
-describe('ensureBuildOptionsInViteConfig', () => {
+describe('ensureViteConfigIsCorrect', () => {
let tree: Tree;
beforeEach(() => {
@@ -29,7 +29,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it("should add build options if build options don't exist", () => {
tree.write('apps/my-app/vite.config.ts', noBuildOptions);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -53,7 +53,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should add new build options if some build options already exist', () => {
tree.write('apps/my-app/vite.config.ts', someBuildOptions);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -77,7 +77,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should add build and test options if defineConfig is empty', () => {
tree.write('apps/my-app/vite.config.ts', noContentDefineConfig);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -101,7 +101,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should add build options if it is using conditional config - do nothing for test', () => {
tree.write('apps/my-app/vite.config.ts', conditionalConfig);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -125,7 +125,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should add build options if defineConfig is not used', () => {
tree.write('apps/my-app/vite.config.ts', configNoDefineConfig);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -149,7 +149,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should not do anything if cannot understand syntax of vite config', () => {
tree.write('apps/my-app/vite.config.ts', `console.log('Unknown syntax')`);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -167,7 +167,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should not do anything if project has everything setup already', () => {
tree.write('apps/my-app/vite.config.ts', hasEverything);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -185,7 +185,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should add build option but not update test option if test already setup', () => {
tree.write('apps/my-app/vite.config.ts', noBuildOptionsHasTestOption);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
@@ -203,7 +203,7 @@ describe('ensureBuildOptionsInViteConfig', () => {
it('should update both test and build options - keep existing settings', () => {
tree.write('apps/my-app/vite.config.ts', someBuildOptionsSomeTestOption);
- ensureBuildOptionsInViteConfig(
+ ensureViteConfigIsCorrect(
tree,
'apps/my-app/vite.config.ts',
buildOption,
diff --git a/packages/vite/src/utils/vite-config-edit-utils.ts b/packages/vite/src/utils/vite-config-edit-utils.ts
index c007289a5475c..0d38b3e33c093 100644
--- a/packages/vite/src/utils/vite-config-edit-utils.ts
+++ b/packages/vite/src/utils/vite-config-edit-utils.ts
@@ -4,7 +4,7 @@ import ts = require('typescript');
import { tsquery } from '@phenomnomnominal/tsquery';
import { TargetFlags } from './generator-utils';
-export function ensureBuildOptionsInViteConfig(
+export function ensureViteConfigIsCorrect(
tree: Tree,
path: string,
buildConfigString: string,
@@ -14,6 +14,7 @@ export function ensureBuildOptionsInViteConfig(
pluginOption: string,
testConfigString: string,
testConfigObject: {},
+ cacheDir: string,
projectAlreadyHasViteTargets?: TargetFlags
): boolean {
const fileContent = tree.read(path, 'utf-8');
@@ -45,6 +46,12 @@ export function ensureBuildOptionsInViteConfig(
);
}
+ if (cacheDir?.length) {
+ updatedContent = handleCacheDirNode(
+ updatedContent ?? fileContent,
+ cacheDir
+ );
+ }
if (updatedContent) {
tree.write(path, updatedContent);
return true;
@@ -97,7 +104,7 @@ function handleBuildOrTestNode(
);
} else {
// no test config in conditional config
- return undefined;
+ return updatedFileContent;
}
} else {
const propertyAssignments = tsquery.query(
@@ -144,7 +151,7 @@ function handleBuildOrTestNode(
},
]);
} catch {
- return undefined;
+ return updatedFileContent;
}
}
}
@@ -229,11 +236,13 @@ function transformConditionalConfig(
if (serveExists && elseKeywordExists) {
// build options live inside the else block
- return transformCurrentBuildObject(
- returnStatements?.length - 1,
- returnStatements,
- appFileContent,
- buildConfigObject
+ return (
+ transformCurrentBuildObject(
+ returnStatements?.length - 1,
+ returnStatements,
+ appFileContent,
+ buildConfigObject
+ ) ?? appFileContent
);
} else {
// no build options exist yet
@@ -256,11 +265,13 @@ function transformConditionalConfig(
// it will be the return statement which lives
// at the buildExistsExpressionIndex
- return transformCurrentBuildObject(
- buildExistsExpressionIndex,
- returnStatements,
- appFileContent,
- buildConfigObject
+ return (
+ transformCurrentBuildObject(
+ buildExistsExpressionIndex,
+ returnStatements,
+ appFileContent,
+ buildConfigObject
+ ) ?? appFileContent
);
}
}
@@ -367,5 +378,78 @@ function handlePluginNode(
}
return appFileContent;
}
- return undefined;
+ return appFileContent;
+}
+
+function handleCacheDirNode(appFileContent: string, cacheDir: string): string {
+ const file = tsquery.ast(appFileContent);
+ const cacheDirNode = tsquery.query(
+ file,
+ 'PropertyAssignment:has(Identifier[name="cacheDir"])'
+ );
+
+ if (!cacheDirNode?.length || cacheDirNode?.length === 0) {
+ // cacheDir node does not exist yet
+ // So make one from scratch
+
+ const foundDefineConfig = tsquery.query(
+ file,
+ 'CallExpression:has(Identifier[name="defineConfig"])'
+ );
+
+ if (foundDefineConfig.length) {
+ const conditionalConfig = tsquery.query(
+ foundDefineConfig[0],
+ 'ArrowFunction'
+ );
+
+ if (conditionalConfig.length) {
+ // We are NOT transforming the conditional config
+ // with cacheDir
+ } else {
+ const propertyAssignments = tsquery.query(
+ foundDefineConfig[0],
+ 'PropertyAssignment'
+ );
+
+ if (propertyAssignments.length) {
+ appFileContent = applyChangesToString(appFileContent, [
+ {
+ type: ChangeType.Insert,
+ index: propertyAssignments[0].getStart(),
+ text: cacheDir,
+ },
+ ]);
+ } else {
+ appFileContent = applyChangesToString(appFileContent, [
+ {
+ type: ChangeType.Insert,
+ index: foundDefineConfig[0].getStart() + 14,
+ text: cacheDir,
+ },
+ ]);
+ }
+ }
+ } else {
+ // cacheDir option does not exist and defineConfig is not used
+ // could also potentially be invalid syntax, so try-catch
+ try {
+ const defaultExport = tsquery.query(file, 'ExportAssignment');
+ const found = tsquery?.query(
+ defaultExport?.[0],
+ 'ObjectLiteralExpression'
+ );
+ const startOfObject = found?.[0].getStart();
+ appFileContent = applyChangesToString(appFileContent, [
+ {
+ type: ChangeType.Insert,
+ index: startOfObject + 1,
+ text: cacheDir,
+ },
+ ]);
+ } catch {}
+ }
+ }
+
+ return appFileContent;
}