fix(vite): improve vite configuration (#13978)
This commit is contained in:
parent
c51c178923
commit
6c6fd7ce1d
@ -941,7 +941,10 @@ describe('app', () => {
|
|||||||
|
|
||||||
it('should create correct tsconfig compilerOptions', () => {
|
it('should create correct tsconfig compilerOptions', () => {
|
||||||
const tsconfigJson = readJson(viteAppTree, '/apps/my-app/tsconfig.json');
|
const tsconfigJson = readJson(viteAppTree, '/apps/my-app/tsconfig.json');
|
||||||
expect(tsconfigJson.compilerOptions.types).toMatchObject(['vite/client']);
|
expect(tsconfigJson.compilerOptions.types).toMatchObject([
|
||||||
|
'vite/client',
|
||||||
|
'vitest',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create index.html and vite.config file at the root of the app', () => {
|
it('should create index.html and vite.config file at the root of the app', () => {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ export function createTsConfig(
|
|||||||
style?: string;
|
style?: string;
|
||||||
bundler?: string;
|
bundler?: string;
|
||||||
rootProject?: boolean;
|
rootProject?: boolean;
|
||||||
|
unitTestRunner?: string;
|
||||||
},
|
},
|
||||||
relativePathToRootTsConfig: string
|
relativePathToRootTsConfig: string
|
||||||
) {
|
) {
|
||||||
@ -36,7 +37,10 @@ export function createTsConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.bundler === 'vite') {
|
if (options.bundler === 'vite') {
|
||||||
json.compilerOptions.types = ['vite/client'];
|
json.compilerOptions.types =
|
||||||
|
options.unitTestRunner === 'vitest'
|
||||||
|
? ['vite/client', 'vitest']
|
||||||
|
: ['vite/client'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// inline tsconfig.base.json into the project
|
// inline tsconfig.base.json into the project
|
||||||
|
|||||||
@ -36,7 +36,7 @@ describe('@nrwl/storybook:configuration for workspaces with Root project', () =>
|
|||||||
skipLibCheck: true,
|
skipLibCheck: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
target: 'ESNext',
|
target: 'ESNext',
|
||||||
types: ['vite/client'],
|
types: ['vite/client', 'vitest'],
|
||||||
useDefineForClassFields: true,
|
useDefineForClassFields: true,
|
||||||
noImplicitOverride: true,
|
noImplicitOverride: true,
|
||||||
noPropertyAccessFromIndexSignature: true,
|
noPropertyAccessFromIndexSignature: true,
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
exports[`@nrwl/vite:configuration library mode should add config for building library 1`] = `
|
exports[`@nrwl/vite:configuration library mode should add config for building library 1`] = `
|
||||||
"
|
"
|
||||||
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
@ -49,7 +48,6 @@ import { join } from 'path';
|
|||||||
|
|
||||||
exports[`@nrwl/vite:configuration library mode should set up non buildable library correctly 1`] = `
|
exports[`@nrwl/vite:configuration library mode should set up non buildable library correctly 1`] = `
|
||||||
"
|
"
|
||||||
/// <reference types=\\"vitest\\" />
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
@ -295,7 +293,8 @@ exports[`@nrwl/vite:configuration transform React app to use Vite by providing c
|
|||||||
\\"builder\\": \\"@nrwl/vite:dev-server\\",
|
\\"builder\\": \\"@nrwl/vite:dev-server\\",
|
||||||
\\"defaultConfiguration\\": \\"development\\",
|
\\"defaultConfiguration\\": \\"development\\",
|
||||||
\\"options\\": {
|
\\"options\\": {
|
||||||
\\"buildTarget\\": \\"my-test-mixed-react-app:build\\"
|
\\"buildTarget\\": \\"my-test-mixed-react-app:build\\",
|
||||||
|
\\"hmr\\": true
|
||||||
},
|
},
|
||||||
\\"configurations\\": {
|
\\"configurations\\": {
|
||||||
\\"development\\": {
|
\\"development\\": {
|
||||||
@ -339,7 +338,6 @@ exports[`@nrwl/vite:configuration transform React app to use Vite by providing c
|
|||||||
|
|
||||||
exports[`@nrwl/vite:configuration transform React app to use Vite should create vite.config file at the root of the app 1`] = `
|
exports[`@nrwl/vite:configuration transform React app to use Vite should create vite.config file at the root of the app 1`] = `
|
||||||
"
|
"
|
||||||
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
@ -429,7 +427,8 @@ exports[`@nrwl/vite:configuration transform React app to use Vite should transfo
|
|||||||
\\"builder\\": \\"@nrwl/vite:dev-server\\",
|
\\"builder\\": \\"@nrwl/vite:dev-server\\",
|
||||||
\\"defaultConfiguration\\": \\"development\\",
|
\\"defaultConfiguration\\": \\"development\\",
|
||||||
\\"options\\": {
|
\\"options\\": {
|
||||||
\\"buildTarget\\": \\"my-test-react-app:build\\"
|
\\"buildTarget\\": \\"my-test-react-app:build\\",
|
||||||
|
\\"hmr\\": true
|
||||||
},
|
},
|
||||||
\\"configurations\\": {
|
\\"configurations\\": {
|
||||||
\\"development\\": {
|
\\"development\\": {
|
||||||
@ -473,7 +472,6 @@ exports[`@nrwl/vite:configuration transform React app to use Vite should transfo
|
|||||||
|
|
||||||
exports[`@nrwl/vite:configuration transform Web app to use Vite should create vite.config file at the root of the app 1`] = `
|
exports[`@nrwl/vite:configuration transform Web app to use Vite should create vite.config file at the root of the app 1`] = `
|
||||||
"
|
"
|
||||||
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
@ -597,7 +595,6 @@ exports[`@nrwl/vite:configuration transform Web app to use Vite should transform
|
|||||||
|
|
||||||
exports[`@nrwl/vite:configuration vitest should create a vitest configuration if "includeVitest" is true 1`] = `
|
exports[`@nrwl/vite:configuration vitest should create a vitest configuration if "includeVitest" is true 1`] = `
|
||||||
"
|
"
|
||||||
/// <reference types=\\"vitest\\" />
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import {
|
|||||||
handleUnsupportedUserProvidedTargets,
|
handleUnsupportedUserProvidedTargets,
|
||||||
handleUnknownExecutors,
|
handleUnknownExecutors,
|
||||||
UserProvidedTargetName,
|
UserProvidedTargetName,
|
||||||
|
TargetFlags,
|
||||||
} from '../../utils/generator-utils';
|
} from '../../utils/generator-utils';
|
||||||
|
|
||||||
import initGenerator from '../init/init';
|
import initGenerator from '../init/init';
|
||||||
@ -39,6 +40,7 @@ export async function viteConfigurationGenerator(tree: Tree, schema: Schema) {
|
|||||||
* This is for when we are convering an existing project
|
* This is for when we are convering an existing project
|
||||||
* to use the vite executors.
|
* to use the vite executors.
|
||||||
* */
|
* */
|
||||||
|
let projectAlreadyHasViteTargets: TargetFlags;
|
||||||
if (!schema.newProject) {
|
if (!schema.newProject) {
|
||||||
const userProvidedTargetName: UserProvidedTargetName = {
|
const userProvidedTargetName: UserProvidedTargetName = {
|
||||||
build: schema.buildTarget,
|
build: schema.buildTarget,
|
||||||
@ -50,8 +52,9 @@ export async function viteConfigurationGenerator(tree: Tree, schema: Schema) {
|
|||||||
validFoundTargetName,
|
validFoundTargetName,
|
||||||
projectContainsUnsupportedExecutor,
|
projectContainsUnsupportedExecutor,
|
||||||
userProvidedTargetIsUnsupported,
|
userProvidedTargetIsUnsupported,
|
||||||
|
alreadyHasNxViteTargets,
|
||||||
} = findExistingTargetsInProject(targets, userProvidedTargetName);
|
} = findExistingTargetsInProject(targets, userProvidedTargetName);
|
||||||
|
projectAlreadyHasViteTargets = alreadyHasNxViteTargets;
|
||||||
/**
|
/**
|
||||||
* This means that we only found unsupported build targets in that project.
|
* This means that we only found unsupported build targets in that project.
|
||||||
* The only way that buildTarget is defined, means that it is supported.
|
* The only way that buildTarget is defined, means that it is supported.
|
||||||
@ -68,6 +71,20 @@ export async function viteConfigurationGenerator(tree: Tree, schema: Schema) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
alreadyHasNxViteTargets.build &&
|
||||||
|
(alreadyHasNxViteTargets.serve ||
|
||||||
|
(!alreadyHasNxViteTargets.serve && projectType === 'library')) &&
|
||||||
|
alreadyHasNxViteTargets.test
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`The project ${schema.project} is aready configured to use the @nrwl/vite executors.
|
||||||
|
Please try a different project, or remove the existing targets
|
||||||
|
and re-run this generator to reset the existing Vite Configuration.
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This means that we did not find any supported executors
|
* This means that we did not find any supported executors
|
||||||
* so we don't have any valid target names.
|
* so we don't have any valid target names.
|
||||||
@ -84,7 +101,7 @@ export async function viteConfigurationGenerator(tree: Tree, schema: Schema) {
|
|||||||
!validFoundTargetName.serve &&
|
!validFoundTargetName.serve &&
|
||||||
!validFoundTargetName.test
|
!validFoundTargetName.test
|
||||||
) {
|
) {
|
||||||
await handleUnknownExecutors();
|
await handleUnknownExecutors(schema.project);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,13 +144,15 @@ export async function viteConfigurationGenerator(tree: Tree, schema: Schema) {
|
|||||||
});
|
});
|
||||||
tasks.push(initTask);
|
tasks.push(initTask);
|
||||||
|
|
||||||
|
if (!projectAlreadyHasViteTargets?.build) {
|
||||||
addOrChangeBuildTarget(tree, schema, buildTargetName);
|
addOrChangeBuildTarget(tree, schema, buildTargetName);
|
||||||
|
}
|
||||||
|
|
||||||
if (!schema.includeLib) {
|
if (!schema.includeLib && !projectAlreadyHasViteTargets?.serve) {
|
||||||
addOrChangeServeTarget(tree, schema, serveTargetName);
|
addOrChangeServeTarget(tree, schema, serveTargetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
createOrEditViteConfig(tree, schema);
|
createOrEditViteConfig(tree, schema, false, projectAlreadyHasViteTargets);
|
||||||
|
|
||||||
if (schema.includeVitest) {
|
if (schema.includeVitest) {
|
||||||
const vitestTask = await vitestGenerator(tree, {
|
const vitestTask = await vitestGenerator(tree, {
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
exports[`vitest generator insourceTests should add the insourceSource option in the vite config 1`] = `
|
exports[`vitest generator insourceTests should add the insourceSource option in the vite config 1`] = `
|
||||||
"
|
"
|
||||||
/// <reference types=\\"vitest\\" />
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
@ -37,7 +36,6 @@ exports[`vitest generator insourceTests should add the insourceSource option in
|
|||||||
|
|
||||||
exports[`vitest generator vite.config should create correct vite.config.ts file for apps 1`] = `
|
exports[`vitest generator vite.config should create correct vite.config.ts file for apps 1`] = `
|
||||||
"
|
"
|
||||||
/// <reference types=\\"vitest\\" />
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
@ -70,7 +68,6 @@ exports[`vitest generator vite.config should create correct vite.config.ts file
|
|||||||
|
|
||||||
exports[`vitest generator vite.config should create correct vite.config.ts file for non buildable libs 1`] = `
|
exports[`vitest generator vite.config should create correct vite.config.ts file for non buildable libs 1`] = `
|
||||||
"
|
"
|
||||||
/// <reference types=\\"vitest\\" />
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|||||||
@ -96,6 +96,17 @@ function updateTsConfig(
|
|||||||
path: './tsconfig.spec.json',
|
path: './tsconfig.spec.json',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!json.compilerOptions?.types?.includes('vitest')) {
|
||||||
|
if (json.compilerOptions?.types) {
|
||||||
|
json.compilerOptions.types.push('vitest');
|
||||||
|
} else {
|
||||||
|
if (!json.compilerOptions) {
|
||||||
|
json.compilerOptions = {};
|
||||||
|
}
|
||||||
|
json.compilerOptions.types = ['vitest'];
|
||||||
|
}
|
||||||
|
}
|
||||||
return json;
|
return json;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,54 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`generator utils ensureBuildOptionsInViteConfig should add build options if build options don't exist 1`] = `
|
exports[`ensureBuildOptionsInViteConfig should add build and test options if defineConfig is empty 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({
|
||||||
|
|
||||||
|
// 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',
|
||||||
|
name: 'my-app',
|
||||||
|
fileName: 'index',
|
||||||
|
// Change this to the formats you want to support.
|
||||||
|
// Don't forgot to update your package.json as well.
|
||||||
|
formats: ['es', 'cjs']
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
// External packages that should not be bundled into your library.
|
||||||
|
external: [\\"'react', 'react-dom', 'react/jsx-runtime'\\"]
|
||||||
|
}
|
||||||
|
},plugins: [
|
||||||
|
dts({
|
||||||
|
tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
|
||||||
|
// Faster builds by skipping tests. Set this to false to enable type checking.
|
||||||
|
skipDiagnostics: true,
|
||||||
|
}),
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
test: {
|
||||||
|
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 option but not update test option if test already setup 1`] = `
|
||||||
"import dts from 'vite-plugin-dts';
|
"import dts from 'vite-plugin-dts';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
@ -52,11 +100,10 @@ import { defineConfig } from 'vite';
|
|||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`generator utils ensureBuildOptionsInViteConfig should add build options if defineConfig is empty 1`] = `
|
exports[`ensureBuildOptionsInViteConfig should add build options if build options don't exist 1`] = `
|
||||||
"import dts from 'vite-plugin-dts';
|
"import dts from 'vite-plugin-dts';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
@ -79,21 +126,33 @@ import { join } from 'path';
|
|||||||
external: [\\"'react', 'react-dom', 'react/jsx-runtime'\\"]
|
external: [\\"'react', 'react-dom', 'react/jsx-runtime'\\"]
|
||||||
}
|
}
|
||||||
},plugins: [
|
},plugins: [
|
||||||
dts({
|
...[
|
||||||
tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
|
|
||||||
// Faster builds by skipping tests. Set this to false to enable type checking.
|
|
||||||
skipDiagnostics: true,
|
|
||||||
}),
|
|
||||||
react(),
|
react(),
|
||||||
viteTsConfigPaths({
|
viteTsConfigPaths({
|
||||||
root: '../../',
|
root: '../../',
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
dts({
|
||||||
|
tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
|
||||||
|
// Faster builds by skipping tests. Set this to false to enable type checking.
|
||||||
|
skipDiagnostics: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../../node_modules/.vitest',
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`generator utils ensureBuildOptionsInViteConfig should add build options if defineConfig is not used 1`] = `
|
exports[`ensureBuildOptionsInViteConfig should add build options if defineConfig is not used 1`] = `
|
||||||
"import dts from 'vite-plugin-dts';
|
"import dts from 'vite-plugin-dts';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
@ -117,6 +176,13 @@ import { defineConfig } from 'vite';
|
|||||||
// External packages that should not be bundled into your library.
|
// External packages that should not be bundled into your library.
|
||||||
external: [\\"'react', 'react-dom', 'react/jsx-runtime'\\"]
|
external: [\\"'react', 'react-dom', 'react/jsx-runtime'\\"]
|
||||||
}
|
}
|
||||||
|
},test: {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../node_modules/.vitest'
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
...[
|
...[
|
||||||
@ -135,7 +201,7 @@ import { defineConfig } from 'vite';
|
|||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`generator utils ensureBuildOptionsInViteConfig should add build options if it is using conditional config 1`] = `
|
exports[`ensureBuildOptionsInViteConfig should add build options if it is using conditional config - do nothing for test 1`] = `
|
||||||
"
|
"
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
export default defineConfig(({ command, mode, ssrBuild }) => {
|
export default defineConfig(({ command, mode, ssrBuild }) => {
|
||||||
@ -157,7 +223,7 @@ exports[`generator utils ensureBuildOptionsInViteConfig should add build options
|
|||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`generator utils ensureBuildOptionsInViteConfig should add new build options if some build options already exist 1`] = `
|
exports[`ensureBuildOptionsInViteConfig should add new build options if some build options already exist 1`] = `
|
||||||
"import dts from 'vite-plugin-dts';
|
"import dts from 'vite-plugin-dts';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
@ -199,4 +265,93 @@ import { defineConfig } from 'vite';
|
|||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`generator utils ensureBuildOptionsInViteConfig should not do anything if cannot understand syntax of vite config 1`] = `"console.log('Unknown syntax')"`;
|
exports[`ensureBuildOptionsInViteConfig 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';
|
||||||
|
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.
|
||||||
|
skipDiagnostics: true,
|
||||||
|
}),
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
// 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',
|
||||||
|
name: 'pure-libs-react-vite',
|
||||||
|
fileName: 'index',
|
||||||
|
// Change this to the formats you want to support.
|
||||||
|
// Don't forgot to update your package.json as well.
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
// External packages that should not be bundled into your library.
|
||||||
|
external: ['react', 'react-dom', 'react/jsx-runtime'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
test: {
|
||||||
|
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`] = `
|
||||||
|
"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: [
|
||||||
|
...[
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
dts({
|
||||||
|
tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
|
||||||
|
// Faster builds by skipping tests. Set this to false to enable type checking.
|
||||||
|
skipDiagnostics: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
test: {
|
||||||
|
...{
|
||||||
|
my: 'option',
|
||||||
|
},
|
||||||
|
...{\\"globals\\":true,\\"cache\\":{\\"dir\\":\\"../node_modules/.vitest\\"},\\"environment\\":\\"jsdom\\",\\"include\\":[\\"src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\\"]}
|
||||||
|
},
|
||||||
|
|
||||||
|
build: {
|
||||||
|
...{
|
||||||
|
my: 'option',
|
||||||
|
},
|
||||||
|
...{\\"lib\\":{\\"entry\\":\\"src/index.ts\\",\\"name\\":\\"my-app\\",\\"fileName\\":\\"index\\",\\"formats\\":[\\"es\\",\\"cjs\\"]},\\"rollupOptions\\":{\\"external\\":[\\"'react', 'react-dom', 'react/jsx-runtime'\\"]}}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import { VitestExecutorOptions } from '../executors/test/schema';
|
|||||||
import { Schema } from '../generators/configuration/schema';
|
import { Schema } from '../generators/configuration/schema';
|
||||||
import { ensureBuildOptionsInViteConfig } from './vite-config-edit-utils';
|
import { ensureBuildOptionsInViteConfig } from './vite-config-edit-utils';
|
||||||
|
|
||||||
export interface UserProvidedTargetIsUnsupported {
|
export interface TargetFlags {
|
||||||
build?: boolean;
|
build?: boolean;
|
||||||
serve?: boolean;
|
serve?: boolean;
|
||||||
test?: boolean;
|
test?: boolean;
|
||||||
@ -41,7 +41,8 @@ export function findExistingTargetsInProject(
|
|||||||
): {
|
): {
|
||||||
validFoundTargetName: ValidFoundTargetName;
|
validFoundTargetName: ValidFoundTargetName;
|
||||||
projectContainsUnsupportedExecutor?: boolean;
|
projectContainsUnsupportedExecutor?: boolean;
|
||||||
userProvidedTargetIsUnsupported?: UserProvidedTargetIsUnsupported;
|
userProvidedTargetIsUnsupported?: TargetFlags;
|
||||||
|
alreadyHasNxViteTargets?: TargetFlags;
|
||||||
} {
|
} {
|
||||||
let validFoundBuildTarget: string | undefined,
|
let validFoundBuildTarget: string | undefined,
|
||||||
validFoundServeTarget: string | undefined,
|
validFoundServeTarget: string | undefined,
|
||||||
@ -49,7 +50,10 @@ export function findExistingTargetsInProject(
|
|||||||
projectContainsUnsupportedExecutor: boolean | undefined,
|
projectContainsUnsupportedExecutor: boolean | undefined,
|
||||||
unsupportedUserProvidedTargetBuild: boolean | undefined,
|
unsupportedUserProvidedTargetBuild: boolean | undefined,
|
||||||
unsupportedUserProvidedTargetServe: boolean | undefined,
|
unsupportedUserProvidedTargetServe: boolean | undefined,
|
||||||
unsupportedUserProvidedTargetTest: boolean | undefined;
|
unsupportedUserProvidedTargetTest: boolean | undefined,
|
||||||
|
alreadyHasNxViteTargetBuild: boolean | undefined,
|
||||||
|
alreadyHasNxViteTargetServe: boolean | undefined,
|
||||||
|
alreadyHasNxViteTargetTest: boolean | undefined;
|
||||||
|
|
||||||
const arrayOfSupportedBuilders = [
|
const arrayOfSupportedBuilders = [
|
||||||
'@nxext/vite:build',
|
'@nxext/vite:build',
|
||||||
@ -82,6 +86,12 @@ export function findExistingTargetsInProject(
|
|||||||
'@nrwl/js:tsc',
|
'@nrwl/js:tsc',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const arrayOfNxViteExecutors = [
|
||||||
|
'@nrwl/vite:build',
|
||||||
|
'@nrwl/vite:dev-server',
|
||||||
|
'@nrwl/vite:test',
|
||||||
|
];
|
||||||
|
|
||||||
// First, we check if the user has provided a target
|
// First, we check if the user has provided a target
|
||||||
// If they have, we check if the executor the target is using is supported
|
// If they have, we check if the executor the target is using is supported
|
||||||
// If it's not supported, then we set the unsupported flag to true for that target
|
// If it's not supported, then we set the unsupported flag to true for that target
|
||||||
@ -134,6 +144,17 @@ export function findExistingTargetsInProject(
|
|||||||
) {
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targets[target].executor === '@nrwl/vite:build') {
|
||||||
|
alreadyHasNxViteTargetBuild = true;
|
||||||
|
}
|
||||||
|
if (targets[target].executor === '@nrwl/vite:dev-server') {
|
||||||
|
alreadyHasNxViteTargetServe = true;
|
||||||
|
}
|
||||||
|
if (targets[target].executor === '@nrwl/vite:test') {
|
||||||
|
alreadyHasNxViteTargetTest = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!validFoundBuildTarget &&
|
!validFoundBuildTarget &&
|
||||||
arrayOfSupportedBuilders.includes(targets[target].executor)
|
arrayOfSupportedBuilders.includes(targets[target].executor)
|
||||||
@ -152,7 +173,10 @@ export function findExistingTargetsInProject(
|
|||||||
) {
|
) {
|
||||||
validFoundTestTarget = target;
|
validFoundTestTarget = target;
|
||||||
}
|
}
|
||||||
if (arrayofUnsupportedExecutors.includes(targets[target].executor)) {
|
if (
|
||||||
|
!arrayOfNxViteExecutors.includes(targets[target].executor) &&
|
||||||
|
arrayofUnsupportedExecutors.includes(targets[target].executor)
|
||||||
|
) {
|
||||||
projectContainsUnsupportedExecutor = true;
|
projectContainsUnsupportedExecutor = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,6 +193,11 @@ export function findExistingTargetsInProject(
|
|||||||
serve: unsupportedUserProvidedTargetServe,
|
serve: unsupportedUserProvidedTargetServe,
|
||||||
test: unsupportedUserProvidedTargetTest,
|
test: unsupportedUserProvidedTargetTest,
|
||||||
},
|
},
|
||||||
|
alreadyHasNxViteTargets: {
|
||||||
|
build: alreadyHasNxViteTargetBuild,
|
||||||
|
serve: alreadyHasNxViteTargetServe,
|
||||||
|
test: alreadyHasNxViteTargetTest,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,6 +299,9 @@ export function addOrChangeServeTarget(
|
|||||||
}
|
}
|
||||||
project.targets[target].options = {
|
project.targets[target].options = {
|
||||||
...serveOptions,
|
...serveOptions,
|
||||||
|
https: project.targets[target].options?.https,
|
||||||
|
hmr: project.targets[target].options?.hmr,
|
||||||
|
open: project.targets[target].options?.open,
|
||||||
};
|
};
|
||||||
project.targets[target].executor = '@nrwl/vite:dev-server';
|
project.targets[target].executor = '@nrwl/vite:dev-server';
|
||||||
} else {
|
} else {
|
||||||
@ -308,6 +340,7 @@ export function editTsConfig(tree: Tree, options: Schema) {
|
|||||||
config.compilerOptions = {
|
config.compilerOptions = {
|
||||||
target: 'ESNext',
|
target: 'ESNext',
|
||||||
useDefineForClassFields: true,
|
useDefineForClassFields: true,
|
||||||
|
module: 'ESNext',
|
||||||
lib: ['DOM', 'DOM.Iterable', 'ESNext'],
|
lib: ['DOM', 'DOM.Iterable', 'ESNext'],
|
||||||
allowJs: false,
|
allowJs: false,
|
||||||
skipLibCheck: true,
|
skipLibCheck: true,
|
||||||
@ -315,13 +348,14 @@ export function editTsConfig(tree: Tree, options: Schema) {
|
|||||||
allowSyntheticDefaultImports: true,
|
allowSyntheticDefaultImports: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
forceConsistentCasingInFileNames: true,
|
forceConsistentCasingInFileNames: true,
|
||||||
module: 'ESNext',
|
|
||||||
moduleResolution: 'Node',
|
moduleResolution: 'Node',
|
||||||
resolveJsonModule: true,
|
resolveJsonModule: true,
|
||||||
isolatedModules: true,
|
isolatedModules: true,
|
||||||
noEmit: true,
|
noEmit: true,
|
||||||
jsx: 'react-jsx',
|
jsx: 'react-jsx',
|
||||||
types: ['vite/client'],
|
types: options.includeVitest
|
||||||
|
? ['vite/client', 'vitest']
|
||||||
|
: ['vite/client'],
|
||||||
};
|
};
|
||||||
config.include = [...config.include, 'src'];
|
config.include = [...config.include, 'src'];
|
||||||
break;
|
break;
|
||||||
@ -331,17 +365,19 @@ export function editTsConfig(tree: Tree, options: Schema) {
|
|||||||
useDefineForClassFields: true,
|
useDefineForClassFields: true,
|
||||||
module: 'ESNext',
|
module: 'ESNext',
|
||||||
lib: ['ESNext', 'DOM'],
|
lib: ['ESNext', 'DOM'],
|
||||||
moduleResolution: 'Node',
|
skipLibCheck: true,
|
||||||
|
esModuleInterop: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
|
moduleResolution: 'Node',
|
||||||
resolveJsonModule: true,
|
resolveJsonModule: true,
|
||||||
isolatedModules: true,
|
isolatedModules: true,
|
||||||
esModuleInterop: true,
|
|
||||||
noEmit: true,
|
noEmit: true,
|
||||||
noUnusedLocals: true,
|
noUnusedLocals: true,
|
||||||
noUnusedParameters: true,
|
noUnusedParameters: true,
|
||||||
noImplicitReturns: true,
|
noImplicitReturns: true,
|
||||||
skipLibCheck: true,
|
types: options.includeVitest
|
||||||
types: ['vite/client'],
|
? ['vite/client', 'vitest']
|
||||||
|
: ['vite/client'],
|
||||||
};
|
};
|
||||||
config.include = [...config.include, 'src'];
|
config.include = [...config.include, 'src'];
|
||||||
break;
|
break;
|
||||||
@ -418,7 +454,8 @@ export function moveAndEditIndexHtml(
|
|||||||
export function createOrEditViteConfig(
|
export function createOrEditViteConfig(
|
||||||
tree: Tree,
|
tree: Tree,
|
||||||
options: Schema,
|
options: Schema,
|
||||||
onlyVitest?: boolean
|
onlyVitest?: boolean,
|
||||||
|
projectAlreadyHasViteTargets?: TargetFlags
|
||||||
) {
|
) {
|
||||||
const projectConfig = readProjectConfiguration(tree, options.project);
|
const projectConfig = readProjectConfiguration(tree, options.project);
|
||||||
|
|
||||||
@ -484,9 +521,6 @@ export function createOrEditViteConfig(
|
|||||||
}
|
}
|
||||||
},`
|
},`
|
||||||
: '';
|
: '';
|
||||||
const vitestTypes = options.includeVitest
|
|
||||||
? `/// <reference types="vitest" />`
|
|
||||||
: '';
|
|
||||||
|
|
||||||
const defineOption = options.inSourceTests
|
const defineOption = options.inSourceTests
|
||||||
? `define: {
|
? `define: {
|
||||||
@ -529,13 +563,15 @@ export function createOrEditViteConfig(
|
|||||||
buildOption,
|
buildOption,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
offsetFromRoot(projectConfig.root),
|
||||||
|
projectAlreadyHasViteTargets
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
viteConfigContent = `
|
viteConfigContent = `
|
||||||
${vitestTypes}
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
${reactPluginImportLine}
|
${reactPluginImportLine}
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
@ -588,7 +624,7 @@ export function getViteConfigPathForProject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function handleUnsupportedUserProvidedTargets(
|
export async function handleUnsupportedUserProvidedTargets(
|
||||||
userProvidedTargetIsUnsupported: UserProvidedTargetIsUnsupported,
|
userProvidedTargetIsUnsupported: TargetFlags,
|
||||||
userProvidedTargetName: UserProvidedTargetName,
|
userProvidedTargetName: UserProvidedTargetName,
|
||||||
validFoundTargetName: ValidFoundTargetName
|
validFoundTargetName: ValidFoundTargetName
|
||||||
) {
|
) {
|
||||||
@ -654,10 +690,10 @@ async function handleUnsupportedUserProvidedTargetsErrors(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handleUnknownExecutors() {
|
export async function handleUnknownExecutors(projectName: string) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`
|
`
|
||||||
We could not find any targets in your project that use executors which
|
We could not find any targets in project ${projectName} that use executors which
|
||||||
can be converted to the @nrwl/vite executors.
|
can be converted to the @nrwl/vite executors.
|
||||||
|
|
||||||
This either means that your project may not have a target
|
This either means that your project may not have a target
|
||||||
@ -691,8 +727,15 @@ function handleViteConfigFileExists(
|
|||||||
buildOption: string,
|
buildOption: string,
|
||||||
dtsPlugin: string,
|
dtsPlugin: string,
|
||||||
dtsImportLine: string,
|
dtsImportLine: string,
|
||||||
pluginOption: string
|
pluginOption: string,
|
||||||
|
testOption: string,
|
||||||
|
offsetFromRoot: string,
|
||||||
|
projectAlreadyHasViteTargets?: TargetFlags
|
||||||
) {
|
) {
|
||||||
|
if (projectAlreadyHasViteTargets.build && projectAlreadyHasViteTargets.test) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
logger.info(`vite.config.ts already exists for project ${options.project}.`);
|
logger.info(`vite.config.ts already exists for project ${options.project}.`);
|
||||||
const buildOptionObject = {
|
const buildOptionObject = {
|
||||||
lib: {
|
lib: {
|
||||||
@ -709,6 +752,16 @@ function handleViteConfigFileExists(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const testOptionObject = {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: `${offsetFromRoot}node_modules/.vitest`,
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
};
|
||||||
|
|
||||||
const changed = ensureBuildOptionsInViteConfig(
|
const changed = ensureBuildOptionsInViteConfig(
|
||||||
tree,
|
tree,
|
||||||
viteConfigPath,
|
viteConfigPath,
|
||||||
@ -716,7 +769,10 @@ function handleViteConfigFileExists(
|
|||||||
buildOptionObject,
|
buildOptionObject,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
projectAlreadyHasViteTargets
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
@ -729,7 +785,7 @@ function handleViteConfigFileExists(
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
logger.info(`
|
logger.info(`
|
||||||
Vite configuration file (${viteConfigPath}) has been updated with the required settings for build.
|
Vite configuration file (${viteConfigPath}) has been updated with the required settings for the new target(s).
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
254
packages/vite/src/utils/test-files/test-vite-configs.ts
Normal file
254
packages/vite/src/utils/test-files/test-vite-configs.ts
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
export const noBuildOptions = `
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../../node_modules/.vitest',
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const someBuildOptions = `
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../../node_modules/.vitest',
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
},
|
||||||
|
|
||||||
|
build: {
|
||||||
|
my: 'option',
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const noContentDefineConfig = `
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default defineConfig({});
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const conditionalConfig = `
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
export default defineConfig(({ command, mode, ssrBuild }) => {
|
||||||
|
if (command === 'serve') {
|
||||||
|
return {
|
||||||
|
port: 4200,
|
||||||
|
host: 'localhost',
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// command === 'build'
|
||||||
|
return {
|
||||||
|
my: 'option',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const configNoDefineConfig = `
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const noBuildOptionsHasTestOption = `
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../../node_modules/.vitest',
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const someBuildOptionsSomeTestOption = `
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
test: {
|
||||||
|
my: 'option',
|
||||||
|
},
|
||||||
|
|
||||||
|
build: {
|
||||||
|
my: 'option',
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const hasEverything = `
|
||||||
|
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.
|
||||||
|
skipDiagnostics: true,
|
||||||
|
}),
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
// 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',
|
||||||
|
name: 'pure-libs-react-vite',
|
||||||
|
fileName: 'index',
|
||||||
|
// Change this to the formats you want to support.
|
||||||
|
// Don't forgot to update your package.json as well.
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
// External packages that should not be bundled into your library.
|
||||||
|
external: ['react', 'react-dom', 'react/jsx-runtime'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../../../node_modules/.vitest',
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const buildOption = `
|
||||||
|
// 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',
|
||||||
|
name: 'my-app',
|
||||||
|
fileName: 'index',
|
||||||
|
// Change this to the formats you want to support.
|
||||||
|
// Don't forgot to update your package.json as well.
|
||||||
|
formats: ['es', 'cjs']
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
// External packages that should not be bundled into your library.
|
||||||
|
external: ["'react', 'react-dom', 'react/jsx-runtime'"]
|
||||||
|
}
|
||||||
|
},`;
|
||||||
|
export const buildOptionObject = {
|
||||||
|
lib: {
|
||||||
|
entry: 'src/index.ts',
|
||||||
|
name: 'my-app',
|
||||||
|
fileName: 'index',
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: ["'react', 'react-dom', 'react/jsx-runtime'"],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const testOption = `test: {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../node_modules/.vitest'
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
},`;
|
||||||
|
|
||||||
|
export const testOptionObject = {
|
||||||
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: `../node_modules/.vitest`,
|
||||||
|
},
|
||||||
|
environment: 'jsdom',
|
||||||
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const dtsPlugin = `dts({
|
||||||
|
tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
|
||||||
|
// Faster builds by skipping tests. Set this to false to enable type checking.
|
||||||
|
skipDiagnostics: true,
|
||||||
|
}),`;
|
||||||
|
export const dtsImportLine = `import dts from 'vite-plugin-dts';\nimport { join } from 'path';`;
|
||||||
|
|
||||||
|
export const pluginOption = `
|
||||||
|
plugins: [
|
||||||
|
${dtsPlugin}
|
||||||
|
react(),
|
||||||
|
viteTsConfigPaths({
|
||||||
|
root: '../../',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
`;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { parseJson, Tree, writeJson } from '@nrwl/devkit';
|
import { Tree, writeJson } from '@nrwl/devkit';
|
||||||
import * as reactAppConfig from './test-files/react-project.config.json';
|
import * as reactAppConfig from './test-files/react-project.config.json';
|
||||||
import * as reactViteConfig from './test-files/react-vite-project.config.json';
|
import * as reactViteConfig from './test-files/react-vite-project.config.json';
|
||||||
import * as webAppConfig from './test-files/web-project.config.json';
|
import * as webAppConfig from './test-files/web-project.config.json';
|
||||||
@ -90,8 +90,7 @@ export function mockViteReactAppGenerator(tree: Tree): Tree {
|
|||||||
|
|
||||||
tree.write(
|
tree.write(
|
||||||
`apps/${appName}/vite.config.ts`,
|
`apps/${appName}/vite.config.ts`,
|
||||||
`/// <reference types="vitest" />
|
`import { defineConfig } from 'vite';
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
@ -534,9 +533,7 @@ export function mockReactLibNonBuildableVitestRunnerGenerator(
|
|||||||
|
|
||||||
tree.write(
|
tree.write(
|
||||||
`libs/${libName}/vite.config.ts`,
|
`libs/${libName}/vite.config.ts`,
|
||||||
`
|
`import { defineConfig } from 'vite';
|
||||||
/// <reference types="vitest" />
|
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
|||||||
@ -1,163 +1,32 @@
|
|||||||
import { Tree } from '@nrwl/devkit';
|
import { Tree } from '@nrwl/devkit';
|
||||||
import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing';
|
import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing';
|
||||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||||
|
import {
|
||||||
|
buildOption,
|
||||||
|
buildOptionObject,
|
||||||
|
conditionalConfig,
|
||||||
|
configNoDefineConfig,
|
||||||
|
dtsImportLine,
|
||||||
|
dtsPlugin,
|
||||||
|
hasEverything,
|
||||||
|
noBuildOptions,
|
||||||
|
noBuildOptionsHasTestOption,
|
||||||
|
noContentDefineConfig,
|
||||||
|
pluginOption,
|
||||||
|
someBuildOptions,
|
||||||
|
someBuildOptionsSomeTestOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
} from './test-files/test-vite-configs';
|
||||||
import { ensureBuildOptionsInViteConfig } from './vite-config-edit-utils';
|
import { ensureBuildOptionsInViteConfig } from './vite-config-edit-utils';
|
||||||
|
|
||||||
describe('generator utils', () => {
|
describe('ensureBuildOptionsInViteConfig', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tree = createTreeWithEmptyV1Workspace();
|
tree = createTreeWithEmptyV1Workspace();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ensureBuildOptionsInViteConfig', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
const buildOption = `
|
|
||||||
// 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',
|
|
||||||
name: 'my-app',
|
|
||||||
fileName: 'index',
|
|
||||||
// Change this to the formats you want to support.
|
|
||||||
// Don't forgot to update your package.json as well.
|
|
||||||
formats: ['es', 'cjs']
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
// External packages that should not be bundled into your library.
|
|
||||||
external: ["'react', 'react-dom', 'react/jsx-runtime'"]
|
|
||||||
}
|
|
||||||
},`;
|
|
||||||
const buildOptionObject = {
|
|
||||||
lib: {
|
|
||||||
entry: 'src/index.ts',
|
|
||||||
name: 'my-app',
|
|
||||||
fileName: 'index',
|
|
||||||
formats: ['es', 'cjs'],
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external: ["'react', 'react-dom', 'react/jsx-runtime'"],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const dtsPlugin = `dts({
|
|
||||||
tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
|
|
||||||
// Faster builds by skipping tests. Set this to false to enable type checking.
|
|
||||||
skipDiagnostics: true,
|
|
||||||
}),`;
|
|
||||||
const dtsImportLine = `import dts from 'vite-plugin-dts';\nimport { join } from 'path';`;
|
|
||||||
|
|
||||||
const pluginOption = `
|
|
||||||
plugins: [
|
|
||||||
${dtsPlugin}
|
|
||||||
react(),
|
|
||||||
viteTsConfigPaths({
|
|
||||||
root: '../../',
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
`;
|
|
||||||
|
|
||||||
const noBuildOptions = `
|
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
react(),
|
|
||||||
viteTsConfigPaths({
|
|
||||||
root: '../../',
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
|
|
||||||
test: {
|
|
||||||
globals: true,
|
|
||||||
cache: {
|
|
||||||
dir: '../../node_modules/.vitest',
|
|
||||||
},
|
|
||||||
environment: 'jsdom',
|
|
||||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
`;
|
|
||||||
|
|
||||||
const someBuildOptions = `
|
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
react(),
|
|
||||||
viteTsConfigPaths({
|
|
||||||
root: '../../',
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
|
|
||||||
test: {
|
|
||||||
globals: true,
|
|
||||||
cache: {
|
|
||||||
dir: '../../node_modules/.vitest',
|
|
||||||
},
|
|
||||||
environment: 'jsdom',
|
|
||||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
||||||
},
|
|
||||||
|
|
||||||
build: {
|
|
||||||
my: 'option',
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
`;
|
|
||||||
|
|
||||||
const noContentDefineConfig = `
|
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
|
||||||
|
|
||||||
export default defineConfig({});
|
|
||||||
`;
|
|
||||||
|
|
||||||
const conditionalConfig = `
|
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
export default defineConfig(({ command, mode, ssrBuild }) => {
|
|
||||||
if (command === 'serve') {
|
|
||||||
return {
|
|
||||||
port: 4200,
|
|
||||||
host: 'localhost',
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// command === 'build'
|
|
||||||
return {
|
|
||||||
my: 'option',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
`;
|
|
||||||
|
|
||||||
const configNoDefineConfig = `
|
|
||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
|
||||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
plugins: [
|
|
||||||
react(),
|
|
||||||
viteTsConfigPaths({
|
|
||||||
root: '../../',
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyV1Workspace();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should add build options if build options don't exist", () => {
|
it("should add build options if build options don't exist", () => {
|
||||||
tree.write('apps/my-app/vite.config.ts', noBuildOptions);
|
tree.write('apps/my-app/vite.config.ts', noBuildOptions);
|
||||||
ensureBuildOptionsInViteConfig(
|
ensureBuildOptionsInViteConfig(
|
||||||
@ -167,7 +36,10 @@ describe('generator utils', () => {
|
|||||||
buildOptionObject,
|
buildOptionObject,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: true, serve: false }
|
||||||
);
|
);
|
||||||
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
const file = tsquery.ast(appFileContent);
|
const file = tsquery.ast(appFileContent);
|
||||||
@ -188,7 +60,10 @@ describe('generator utils', () => {
|
|||||||
buildOptionObject,
|
buildOptionObject,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: true, serve: false }
|
||||||
);
|
);
|
||||||
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
const file = tsquery.ast(appFileContent);
|
const file = tsquery.ast(appFileContent);
|
||||||
@ -200,7 +75,7 @@ describe('generator utils', () => {
|
|||||||
expect(appFileContent).toMatchSnapshot();
|
expect(appFileContent).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add build options if defineConfig is empty', () => {
|
it('should add build and test options if defineConfig is empty', () => {
|
||||||
tree.write('apps/my-app/vite.config.ts', noContentDefineConfig);
|
tree.write('apps/my-app/vite.config.ts', noContentDefineConfig);
|
||||||
ensureBuildOptionsInViteConfig(
|
ensureBuildOptionsInViteConfig(
|
||||||
tree,
|
tree,
|
||||||
@ -209,7 +84,10 @@ describe('generator utils', () => {
|
|||||||
buildOptionObject,
|
buildOptionObject,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: false, serve: false }
|
||||||
);
|
);
|
||||||
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
const file = tsquery.ast(appFileContent);
|
const file = tsquery.ast(appFileContent);
|
||||||
@ -221,7 +99,7 @@ describe('generator utils', () => {
|
|||||||
expect(appFileContent).toMatchSnapshot();
|
expect(appFileContent).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add build options if it is using conditional config', () => {
|
it('should add build options if it is using conditional config - do nothing for test', () => {
|
||||||
tree.write('apps/my-app/vite.config.ts', conditionalConfig);
|
tree.write('apps/my-app/vite.config.ts', conditionalConfig);
|
||||||
ensureBuildOptionsInViteConfig(
|
ensureBuildOptionsInViteConfig(
|
||||||
tree,
|
tree,
|
||||||
@ -230,7 +108,10 @@ describe('generator utils', () => {
|
|||||||
buildOptionObject,
|
buildOptionObject,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: false, serve: false }
|
||||||
);
|
);
|
||||||
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
const file = tsquery.ast(appFileContent);
|
const file = tsquery.ast(appFileContent);
|
||||||
@ -251,7 +132,10 @@ describe('generator utils', () => {
|
|||||||
buildOptionObject,
|
buildOptionObject,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: false, serve: false }
|
||||||
);
|
);
|
||||||
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
const file = tsquery.ast(appFileContent);
|
const file = tsquery.ast(appFileContent);
|
||||||
@ -272,10 +156,66 @@ describe('generator utils', () => {
|
|||||||
buildOptionObject,
|
buildOptionObject,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: false, serve: false }
|
||||||
);
|
);
|
||||||
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
expect(appFileContent).toMatchSnapshot();
|
expect(appFileContent).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not do anything if project has everything setup already', () => {
|
||||||
|
tree.write('apps/my-app/vite.config.ts', hasEverything);
|
||||||
|
ensureBuildOptionsInViteConfig(
|
||||||
|
tree,
|
||||||
|
'apps/my-app/vite.config.ts',
|
||||||
|
buildOption,
|
||||||
|
buildOptionObject,
|
||||||
|
dtsPlugin,
|
||||||
|
dtsImportLine,
|
||||||
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: true, test: true, serve: true }
|
||||||
|
);
|
||||||
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
|
expect(appFileContent).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add build option but not update test option if test already setup', () => {
|
||||||
|
tree.write('apps/my-app/vite.config.ts', noBuildOptionsHasTestOption);
|
||||||
|
ensureBuildOptionsInViteConfig(
|
||||||
|
tree,
|
||||||
|
'apps/my-app/vite.config.ts',
|
||||||
|
buildOption,
|
||||||
|
buildOptionObject,
|
||||||
|
dtsPlugin,
|
||||||
|
dtsImportLine,
|
||||||
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: true, serve: true }
|
||||||
|
);
|
||||||
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
|
expect(appFileContent).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update both test and build options - keep existing settings', () => {
|
||||||
|
tree.write('apps/my-app/vite.config.ts', someBuildOptionsSomeTestOption);
|
||||||
|
ensureBuildOptionsInViteConfig(
|
||||||
|
tree,
|
||||||
|
'apps/my-app/vite.config.ts',
|
||||||
|
buildOption,
|
||||||
|
buildOptionObject,
|
||||||
|
dtsPlugin,
|
||||||
|
dtsImportLine,
|
||||||
|
pluginOption,
|
||||||
|
testOption,
|
||||||
|
testOptionObject,
|
||||||
|
{ build: false, test: false, serve: true }
|
||||||
|
);
|
||||||
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
||||||
|
expect(appFileContent).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,59 +2,77 @@ import { applyChangesToString, ChangeType, Tree } from '@nrwl/devkit';
|
|||||||
import { findNodes } from 'nx/src/utils/typescript';
|
import { findNodes } from 'nx/src/utils/typescript';
|
||||||
import ts = require('typescript');
|
import ts = require('typescript');
|
||||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||||
|
import { TargetFlags } from './generator-utils';
|
||||||
|
|
||||||
export function ensureBuildOptionsInViteConfig(
|
export function ensureBuildOptionsInViteConfig(
|
||||||
tree: Tree,
|
tree: Tree,
|
||||||
path: string,
|
path: string,
|
||||||
buildConfigContent: string,
|
buildConfigString: string,
|
||||||
buildConfigObject: {},
|
buildConfigObject: {},
|
||||||
dtsPlugin: string,
|
dtsPlugin: string,
|
||||||
dtsImportLine: string,
|
dtsImportLine: string,
|
||||||
pluginOption: string
|
pluginOption: string,
|
||||||
|
testConfigString: string,
|
||||||
|
testConfigObject: {},
|
||||||
|
projectAlreadyHasViteTargets?: TargetFlags
|
||||||
): boolean {
|
): boolean {
|
||||||
const fileContent = tree.read(path, 'utf-8');
|
const fileContent = tree.read(path, 'utf-8');
|
||||||
const file = tsquery.ast(fileContent);
|
|
||||||
const newContent = handlePluginNode(
|
let updatedContent = undefined;
|
||||||
file,
|
|
||||||
|
if (!projectAlreadyHasViteTargets?.test && testConfigString?.length) {
|
||||||
|
updatedContent = handleBuildOrTestNode(
|
||||||
fileContent,
|
fileContent,
|
||||||
|
testConfigString,
|
||||||
|
testConfigObject,
|
||||||
|
'test'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!projectAlreadyHasViteTargets?.build && buildConfigString?.length) {
|
||||||
|
updatedContent = handlePluginNode(
|
||||||
|
updatedContent ?? fileContent,
|
||||||
dtsPlugin,
|
dtsPlugin,
|
||||||
dtsImportLine,
|
dtsImportLine,
|
||||||
pluginOption
|
pluginOption
|
||||||
);
|
);
|
||||||
|
|
||||||
const buildUpdatedContent = handleBuildNode(
|
updatedContent = handleBuildOrTestNode(
|
||||||
newContent ?? fileContent,
|
updatedContent ?? fileContent,
|
||||||
buildConfigContent,
|
buildConfigString,
|
||||||
buildConfigObject
|
buildConfigObject,
|
||||||
|
'build'
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (buildUpdatedContent) {
|
if (updatedContent) {
|
||||||
tree.write(path, buildUpdatedContent);
|
tree.write(path, updatedContent);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBuildNode(
|
function handleBuildOrTestNode(
|
||||||
updatedFileContent: string,
|
updatedFileContent: string,
|
||||||
buildConfigContent: string,
|
configContentString: string,
|
||||||
buildConfigObject: {}
|
configContentObject: {},
|
||||||
|
name: 'build' | 'test'
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
const buildNode = tsquery.query(
|
const buildNode = tsquery.query(
|
||||||
updatedFileContent,
|
updatedFileContent,
|
||||||
'PropertyAssignment:has(Identifier[name="build"])'
|
`PropertyAssignment:has(Identifier[name="${name}"])`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (buildNode.length) {
|
if (buildNode.length) {
|
||||||
return tsquery.replace(
|
return tsquery.replace(
|
||||||
updatedFileContent,
|
updatedFileContent,
|
||||||
'PropertyAssignment:has(Identifier[name="build"])',
|
`PropertyAssignment:has(Identifier[name="${name}"])`,
|
||||||
(node: ts.Node) => {
|
(node: ts.Node) => {
|
||||||
const found = tsquery.query(node, 'ObjectLiteralExpression');
|
const found = tsquery.query(node, 'ObjectLiteralExpression');
|
||||||
return `build: {
|
return `${name}: {
|
||||||
...${found?.[0].getText()},
|
...${found?.[0].getText()},
|
||||||
...${JSON.stringify(buildConfigObject)}
|
...${JSON.stringify(configContentObject)}
|
||||||
}`;
|
}`;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -71,11 +89,16 @@ function handleBuildNode(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (conditionalConfig.length) {
|
if (conditionalConfig.length) {
|
||||||
|
if (name === 'build') {
|
||||||
return transformConditionalConfig(
|
return transformConditionalConfig(
|
||||||
conditionalConfig,
|
conditionalConfig,
|
||||||
updatedFileContent,
|
updatedFileContent,
|
||||||
buildConfigContent
|
configContentString
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// no test config in conditional config
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const propertyAssignments = tsquery.query(
|
const propertyAssignments = tsquery.query(
|
||||||
foundDefineConfig[0],
|
foundDefineConfig[0],
|
||||||
@ -87,7 +110,7 @@ function handleBuildNode(
|
|||||||
{
|
{
|
||||||
type: ChangeType.Insert,
|
type: ChangeType.Insert,
|
||||||
index: propertyAssignments[0].getStart(),
|
index: propertyAssignments[0].getStart(),
|
||||||
text: buildConfigContent,
|
text: configContentString,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
@ -95,7 +118,7 @@ function handleBuildNode(
|
|||||||
{
|
{
|
||||||
type: ChangeType.Insert,
|
type: ChangeType.Insert,
|
||||||
index: foundDefineConfig[0].getStart() + 14,
|
index: foundDefineConfig[0].getStart() + 14,
|
||||||
text: buildConfigContent,
|
text: configContentString,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -117,7 +140,7 @@ function handleBuildNode(
|
|||||||
{
|
{
|
||||||
type: ChangeType.Insert,
|
type: ChangeType.Insert,
|
||||||
index: startOfObject + 1,
|
index: startOfObject + 1,
|
||||||
text: buildConfigContent,
|
text: configContentString,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
} catch {
|
} catch {
|
||||||
@ -131,7 +154,6 @@ function transformCurrentBuildObject(
|
|||||||
index: number,
|
index: number,
|
||||||
returnStatements: ts.ReturnStatement[],
|
returnStatements: ts.ReturnStatement[],
|
||||||
appFileContent: string,
|
appFileContent: string,
|
||||||
|
|
||||||
buildConfigObject: {}
|
buildConfigObject: {}
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
if (!returnStatements?.[index]) {
|
if (!returnStatements?.[index]) {
|
||||||
@ -244,12 +266,12 @@ function transformConditionalConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handlePluginNode(
|
function handlePluginNode(
|
||||||
file: ts.SourceFile,
|
|
||||||
appFileContent: string,
|
appFileContent: string,
|
||||||
dtsPlugin: string,
|
dtsPlugin: string,
|
||||||
dtsImportLine: string,
|
dtsImportLine: string,
|
||||||
pluginOption: string
|
pluginOption: string
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
|
const file = tsquery.ast(appFileContent);
|
||||||
const pluginsNode = tsquery.query(
|
const pluginsNode = tsquery.query(
|
||||||
file,
|
file,
|
||||||
'PropertyAssignment:has(Identifier[name="plugins"])'
|
'PropertyAssignment:has(Identifier[name="plugins"])'
|
||||||
@ -341,16 +363,8 @@ function handlePluginNode(
|
|||||||
|
|
||||||
if (writeFile) {
|
if (writeFile) {
|
||||||
if (!appFileContent.includes(`import dts from 'vite-plugin-dts'`)) {
|
if (!appFileContent.includes(`import dts from 'vite-plugin-dts'`)) {
|
||||||
if (appFileContent.includes('/// <reference types="vitest" />')) {
|
|
||||||
return appFileContent.replace(
|
|
||||||
'/// <reference types="vitest" />',
|
|
||||||
`/// <reference types="vitest" />
|
|
||||||
${dtsImportLine}\n`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return dtsImportLine + '\n' + appFileContent;
|
return dtsImportLine + '\n' + appFileContent;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return appFileContent;
|
return appFileContent;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@ -160,7 +160,10 @@ describe('app', () => {
|
|||||||
path: './tsconfig.spec.json',
|
path: './tsconfig.spec.json',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(tsconfig.compilerOptions.types).toMatchObject(['vite/client']);
|
expect(tsconfig.compilerOptions.types).toMatchObject([
|
||||||
|
'vite/client',
|
||||||
|
'vitest',
|
||||||
|
]);
|
||||||
|
|
||||||
expect(tree.exists('apps/my-app-e2e/cypress.config.ts')).toBeTruthy();
|
expect(tree.exists('apps/my-app-e2e/cypress.config.ts')).toBeTruthy();
|
||||||
expect(tree.exists('apps/my-app/index.html')).toBeTruthy();
|
expect(tree.exists('apps/my-app/index.html')).toBeTruthy();
|
||||||
@ -563,7 +566,10 @@ describe('app', () => {
|
|||||||
|
|
||||||
it('should create correct tsconfig compilerOptions', () => {
|
it('should create correct tsconfig compilerOptions', () => {
|
||||||
const tsconfigJson = readJson(viteAppTree, '/apps/my-app/tsconfig.json');
|
const tsconfigJson = readJson(viteAppTree, '/apps/my-app/tsconfig.json');
|
||||||
expect(tsconfigJson.compilerOptions.types).toMatchObject(['vite/client']);
|
expect(tsconfigJson.compilerOptions.types).toMatchObject([
|
||||||
|
'vite/client',
|
||||||
|
'vitest',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create index.html and vite.config file at the root of the app', () => {
|
it('should create index.html and vite.config file at the root of the app', () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user