Skip to content

Commit

Permalink
feat(vite): build, serve, test, preview targets
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini committed Nov 7, 2023
1 parent 76b19ba commit e3b29d8
Show file tree
Hide file tree
Showing 14 changed files with 394 additions and 161 deletions.
2 changes: 1 addition & 1 deletion docs/generated/packages/vite/generators/vitest.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"coverageProvider": {
"type": "string",
"enum": ["v8", "c8", "istanbul"],
"enum": ["v8", "c8", "custom"],
"default": "v8",
"description": "Coverage provider to use."
},
Expand Down
1 change: 1 addition & 0 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
"exports": {
".": "./index.js",
"./plugin": "./plugin.js",
"./package.json": "./package.json",
"./migrations.json": "./migrations.json",
"./generators.json": "./generators.json",
Expand Down
11 changes: 8 additions & 3 deletions packages/vite/src/executors/test/vitest.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,18 @@ async function getSettings(
const packageJson = existsSync(packageJsonPath)
? readJsonFile(packageJsonPath)
: undefined;
let provider: 'v8' | 'c8' = 'v8';

let provider: 'c8' | 'istanbul' | 'custom';

if (
packageJson?.dependencies?.['@vitest/coverage-c8'] ||
packageJson?.devDependencies?.['@vitest/coverage-c8']
packageJson?.dependencies?.['@vitest/coverage-istanbul'] ||
packageJson?.devDependencies?.['@vitest/coverage-istanbul']
) {
provider = 'istanbul';
} else {
provider = 'c8';
}

const offset = relative(workspaceRoot, context.cwd);
// if reportsDirectory is not provided vitest will remove all files in the project root
// when coverage is enabled in the vite.config.ts
Expand Down
27 changes: 18 additions & 9 deletions packages/vite/src/generators/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
formatFiles,
GeneratorCallback,
joinPathFragments,
readNxJson,
readProjectConfiguration,
runTasksInSerial,
Tree,
Expand Down Expand Up @@ -163,19 +164,27 @@ export async function viteConfigurationGenerator(
});
tasks.push(initTask);

if (!projectAlreadyHasViteTargets.build) {
addOrChangeBuildTarget(tree, schema, buildTargetName);
}
const nxJson = readNxJson(tree);
const hasPlugin = nxJson.plugins?.some((p) =>
typeof p === 'string'
? p === '@nx/vite/plugin'
: p.plugin === '@nx/vite/plugin'
);

if (!schema.includeLib) {
if (!projectAlreadyHasViteTargets.serve) {
addOrChangeServeTarget(tree, schema, serveTargetName);
if (!hasPlugin) {
if (!projectAlreadyHasViteTargets.build) {
addOrChangeBuildTarget(tree, schema, buildTargetName);
}
if (!projectAlreadyHasViteTargets.preview) {
addPreviewTarget(tree, schema, serveTargetName);

if (!schema.includeLib) {
if (!projectAlreadyHasViteTargets.serve) {
addOrChangeServeTarget(tree, schema, serveTargetName);
}
if (!projectAlreadyHasViteTargets.preview) {
addPreviewTarget(tree, schema, serveTargetName);
}
}
}

if (projectType === 'library') {
// update tsconfig.lib.json to include vite/client
updateJson(tree, joinPathFragments(root, 'tsconfig.lib.json'), (json) => {
Expand Down
111 changes: 11 additions & 100 deletions packages/vite/src/generators/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,107 +1,14 @@
import {
addDependenciesToPackageJson,
logger,
readJson,
readNxJson,
runTasksInSerial,
Tree,
updateJson,
updateNxJson,
} from '@nx/devkit';
import { Tree, runTasksInSerial } from '@nx/devkit';

import { initGenerator as jsInitGenerator } from '@nx/js';

import {
edgeRuntimeVmVersion,
happyDomVersion,
jsdomVersion,
nxVersion,
vitePluginDtsVersion,
vitePluginReactSwcVersion,
vitePluginReactVersion,
vitestUiVersion,
vitestVersion,
viteVersion,
} from '../../utils/versions';
import { InitGeneratorSchema } from './schema';

function checkDependenciesInstalled(host: Tree, schema: InitGeneratorSchema) {
const packageJson = readJson(host, 'package.json');
const devDependencies = {};
const dependencies = {};
packageJson.dependencies = packageJson.dependencies || {};
packageJson.devDependencies = packageJson.devDependencies || {};

// base deps
devDependencies['@nx/vite'] = nxVersion;
devDependencies['vite'] = viteVersion;
devDependencies['vitest'] = vitestVersion;
devDependencies['@vitest/ui'] = vitestUiVersion;

if (schema.testEnvironment === 'jsdom') {
devDependencies['jsdom'] = jsdomVersion;
} else if (schema.testEnvironment === 'happy-dom') {
devDependencies['happy-dom'] = happyDomVersion;
} else if (schema.testEnvironment === 'edge-runtime') {
devDependencies['@edge-runtime/vm'] = edgeRuntimeVmVersion;
} else if (schema.testEnvironment !== 'node' && schema.testEnvironment) {
logger.info(
`A custom environment was provided: ${schema.testEnvironment}. You need to install it manually.`
);
}

if (schema.uiFramework === 'react') {
if (schema.compiler === 'swc') {
devDependencies['@vitejs/plugin-react-swc'] = vitePluginReactSwcVersion;
} else {
devDependencies['@vitejs/plugin-react'] = vitePluginReactVersion;
}
}

if (schema.includeLib) {
devDependencies['vite-plugin-dts'] = vitePluginDtsVersion;
}

return addDependenciesToPackageJson(host, dependencies, devDependencies);
}

function moveToDevDependencies(tree: Tree) {
updateJson(tree, 'package.json', (packageJson) => {
packageJson.dependencies = packageJson.dependencies || {};
packageJson.devDependencies = packageJson.devDependencies || {};

if (packageJson.dependencies['@nx/vite']) {
packageJson.devDependencies['@nx/vite'] =
packageJson.dependencies['@nx/vite'];
delete packageJson.dependencies['@nx/vite'];
}
return packageJson;
});
}

export function createVitestConfig(tree: Tree) {
const nxJson = readNxJson(tree);

const productionFileSet = nxJson.namedInputs?.production;
if (productionFileSet) {
productionFileSet.push(
'!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)',
'!{projectRoot}/tsconfig.spec.json'
);

nxJson.namedInputs.production = Array.from(new Set(productionFileSet));
}

nxJson.targetDefaults ??= {};
nxJson.targetDefaults['@nx/vite:test'] ??= {};
nxJson.targetDefaults['@nx/vite:test'].cache ??= true;
nxJson.targetDefaults['@nx/vite:test'].inputs ??= [
'default',
productionFileSet ? '^production' : '^default',
];

updateNxJson(tree, nxJson);
}
import {
addPlugin,
checkDependenciesInstalled,
createVitestConfig,
moveToDevDependencies,
} from './lib/utils';

export async function initGenerator(tree: Tree, schema: InitGeneratorSchema) {
moveToDevDependencies(tree);
Expand All @@ -115,6 +22,10 @@ export async function initGenerator(tree: Tree, schema: InitGeneratorSchema) {
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
})
);
const addPlugins = process.env.NX_PCV3 === 'true';
if (addPlugins) {
addPlugin(tree);
}

tasks.push(checkDependenciesInstalled(tree, schema));
return runTasksInSerial(...tasks);
Expand Down
127 changes: 127 additions & 0 deletions packages/vite/src/generators/init/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import {
addDependenciesToPackageJson,
logger,
readJson,
readNxJson,
Tree,
updateJson,
updateNxJson,
} from '@nx/devkit';

import {
edgeRuntimeVmVersion,
happyDomVersion,
jsdomVersion,
nxVersion,
vitePluginDtsVersion,
vitePluginReactSwcVersion,
vitePluginReactVersion,
vitestUiVersion,
vitestVersion,
viteVersion,
} from '../../../utils/versions';
import { InitGeneratorSchema } from '../schema';

export function checkDependenciesInstalled(
host: Tree,
schema: InitGeneratorSchema
) {
const packageJson = readJson(host, 'package.json');
const devDependencies = {};
const dependencies = {};
packageJson.dependencies = packageJson.dependencies || {};
packageJson.devDependencies = packageJson.devDependencies || {};

// base deps
devDependencies['@nx/vite'] = nxVersion;
devDependencies['vite'] = viteVersion;
devDependencies['vitest'] = vitestVersion;
devDependencies['@vitest/ui'] = vitestUiVersion;

if (schema.testEnvironment === 'jsdom') {
devDependencies['jsdom'] = jsdomVersion;
} else if (schema.testEnvironment === 'happy-dom') {
devDependencies['happy-dom'] = happyDomVersion;
} else if (schema.testEnvironment === 'edge-runtime') {
devDependencies['@edge-runtime/vm'] = edgeRuntimeVmVersion;
} else if (schema.testEnvironment !== 'node' && schema.testEnvironment) {
logger.info(
`A custom environment was provided: ${schema.testEnvironment}. You need to install it manually.`
);
}

if (schema.uiFramework === 'react') {
if (schema.compiler === 'swc') {
devDependencies['@vitejs/plugin-react-swc'] = vitePluginReactSwcVersion;
} else {
devDependencies['@vitejs/plugin-react'] = vitePluginReactVersion;
}
}

if (schema.includeLib) {
devDependencies['vite-plugin-dts'] = vitePluginDtsVersion;
}

return addDependenciesToPackageJson(host, dependencies, devDependencies);
}

export function moveToDevDependencies(tree: Tree) {
updateJson(tree, 'package.json', (packageJson) => {
packageJson.dependencies = packageJson.dependencies || {};
packageJson.devDependencies = packageJson.devDependencies || {};

if (packageJson.dependencies['@nx/vite']) {
packageJson.devDependencies['@nx/vite'] =
packageJson.dependencies['@nx/vite'];
delete packageJson.dependencies['@nx/vite'];
}
return packageJson;
});
}

export function createVitestConfig(tree: Tree) {
const nxJson = readNxJson(tree);

const productionFileSet = nxJson.namedInputs?.production;
if (productionFileSet) {
productionFileSet.push(
'!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)',
'!{projectRoot}/tsconfig.spec.json'
);

nxJson.namedInputs.production = Array.from(new Set(productionFileSet));
}

nxJson.targetDefaults ??= {};
nxJson.targetDefaults['@nx/vite:test'] ??= {};
nxJson.targetDefaults['@nx/vite:test'].cache ??= true;
nxJson.targetDefaults['@nx/vite:test'].inputs ??= [
'default',
productionFileSet ? '^production' : '^default',
];

updateNxJson(tree, nxJson);
}

export function addPlugin(tree: Tree) {
const nxJson = readNxJson(tree);
nxJson.plugins ??= [];

for (const plugin of nxJson.plugins) {
if (
typeof plugin === 'string'
? plugin === '@nx/vite/plugin'
: plugin.plugin === '@nx/vite/plugin'
) {
return;
}
}

nxJson.plugins.push({
plugin: '@nx/vite/plugin',
options: {
targetName: 'build',
},
});
updateNxJson(tree, nxJson);
}
2 changes: 1 addition & 1 deletion packages/vite/src/generators/vitest/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export interface VitestGeneratorSchema {
project: string;
uiFramework: 'react' | 'none';
coverageProvider: 'v8' | 'c8' | 'istanbul';
coverageProvider: 'c8' | 'istanbul' | 'custom';
inSourceTests?: boolean;
skipViteConfig?: boolean;
testTarget?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/generators/vitest/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
},
"coverageProvider": {
"type": "string",
"enum": ["v8", "c8", "istanbul"],
"enum": ["v8", "c8", "custom"],
"default": "v8",
"description": "Coverage provider to use."
},
Expand Down

0 comments on commit e3b29d8

Please sign in to comment.