Skip to content

Commit

Permalink
feat(vite): nodes for build, serve, test, preview targets
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini committed Nov 8, 2023
1 parent 304a6d1 commit 7deda84
Show file tree
Hide file tree
Showing 19 changed files with 633 additions and 162 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
5 changes: 5 additions & 0 deletions packages/vite/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
"version": "17.1.0-beta.2",
"description": "Move target defaults",
"implementation": "./src/migrations/update-17-1-0/move-target-defaults"
},
"add-vite-plugin": {
"version": "17.2.0-beta.0",
"description": "Add @nx/vite/plugin",
"implementation": "./src/migrations/update-17-2-0/add-vite-plugin"
}
},
"packageJsonUpdates": {
Expand Down
3 changes: 2 additions & 1 deletion packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
"migrations": "./migrations.json"
},
"dependencies": {
"@nx/devkit": "file:../devkit",
"@phenomnomnominal/tsquery": "~5.0.1",
"@swc/helpers": "~0.5.0",
"enquirer": "~2.3.6",
"@nx/devkit": "file:../devkit",
"@nx/js": "file:../js",
"tsconfig-paths": "^4.1.2"
},
Expand All @@ -45,6 +45,7 @@
},
"exports": {
".": "./index.js",
"./plugin": "./plugin.js",
"./package.json": "./package.json",
"./migrations.json": "./migrations.json",
"./generators.json": "./generators.json",
Expand Down
1 change: 1 addition & 0 deletions packages/vite/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { createNodes, VitePluginOptions } from './src/plugins/plugin';
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
126 changes: 11 additions & 115 deletions packages/vite/src/generators/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,122 +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;

// Do not install latest version if vitest already exists
// because version 0.32 and newer versions break nuxt-vitest
// https://github.com/vitest-dev/vitest/issues/3540
// https://github.com/danielroe/nuxt-vitest/issues/213#issuecomment-1588728111
if (
!packageJson.dependencies['vitest'] &&
!packageJson.devDependencies['vitest']
) {
devDependencies['vitest'] = vitestVersion;
}
if (
!packageJson.dependencies['@vitest/ui'] &&
!packageJson.devDependencies['@vitest/ui']
) {
devDependencies['@vitest/ui'] = vitestVersion;
}

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 @@ -130,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
145 changes: 145 additions & 0 deletions packages/vite/src/generators/init/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
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;

// Do not install latest version if vitest already exists
// because version 0.32 and newer versions break nuxt-vitest
// https://github.com/vitest-dev/vitest/issues/3540
// https://github.com/danielroe/nuxt-vitest/issues/213#issuecomment-1588728111
if (
!packageJson.dependencies['vitest'] &&
!packageJson.devDependencies['vitest']
) {
devDependencies['vitest'] = vitestVersion;
}
if (
!packageJson.dependencies['@vitest/ui'] &&
!packageJson.devDependencies['@vitest/ui']
) {
devDependencies['@vitest/ui'] = vitestVersion;
}

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: {
buildTargetName: 'build',
previewTargetName: 'preview',
testTargetName: 'test',
serveTargetName: 'serve',
},
});
updateNxJson(tree, nxJson);
}
Loading

0 comments on commit 7deda84

Please sign in to comment.