nx/packages/react/src/utils/version-utils.ts
Colum Ferry a468d72c7f
feat(react): add support for React 19 for new Workspaces (#29286)
## Current Behavior
We currently have no support for React 19, generating only React 18
applications.

## Expected Behavior
Add utils to determine what version of React is installed in the
workspace.
If React 18 is the main version of react installed, continue to generate
React 18 projects.
If React 19 is the main version of react installed, generate React 19
projects.
If no React version is installed or can be determined, generate React 19
projects.
2025-01-17 15:14:48 +00:00

83 lines
2.3 KiB
TypeScript

import { type Tree, readJson, createProjectGraphAsync } from '@nx/devkit';
import { clean, coerce, major } from 'semver';
import {
reactDomV18Version,
reactIsV18Version,
reactV18Version,
reactVersion,
typesReactDomV18Version,
typesReactIsV18Version,
typesReactV18Version,
reactDomVersion,
reactIsVersion,
typesReactVersion,
typesReactDomVersion,
typesReactIsVersion,
} from './versions';
type ReactDependenciesVersions = {
react: string;
'react-dom': string;
'react-is': string;
'@types/react': string;
'@types/react-dom': string;
'@types/react-is': string;
};
export async function getReactDependenciesVersionsToInstall(
tree: Tree
): Promise<ReactDependenciesVersions> {
if (await isReact18(tree)) {
return {
react: reactV18Version,
'react-dom': reactDomV18Version,
'react-is': reactIsV18Version,
'@types/react': typesReactV18Version,
'@types/react-dom': typesReactDomV18Version,
'@types/react-is': typesReactIsV18Version,
};
} else {
return {
react: reactVersion,
'react-dom': reactDomVersion,
'react-is': reactIsVersion,
'@types/react': typesReactVersion,
'@types/react-dom': typesReactDomVersion,
'@types/react-is': typesReactIsVersion,
};
}
}
export async function isReact18(tree: Tree) {
let installedReactVersion = await getInstalledReactVersionFromGraph();
if (!installedReactVersion) {
installedReactVersion = getInstalledReactVersion(tree);
}
return major(installedReactVersion) === 18;
}
export function getInstalledReactVersion(tree: Tree): string {
const pkgJson = readJson(tree, 'package.json');
const installedReactVersion =
pkgJson.dependencies && pkgJson.dependencies['react'];
if (
!installedReactVersion ||
installedReactVersion === 'latest' ||
installedReactVersion === 'next'
) {
return clean(reactVersion) ?? coerce(reactVersion).version;
}
return clean(installedReactVersion) ?? coerce(installedReactVersion).version;
}
export async function getInstalledReactVersionFromGraph() {
const graph = await createProjectGraphAsync();
const reactDep = graph.externalNodes?.['npm:react'];
if (!reactDep) {
return undefined;
}
return clean(reactDep.data.version) ?? coerce(reactDep.data.version).version;
}