Skip to content

Commit

Permalink
fix(core): React workspaces that use pnpm & the new TS solution shoul…
Browse files Browse the repository at this point in the history
…d be declared correctly so that it can be referenced.
  • Loading branch information
ndcunningham committed Dec 5, 2024
1 parent e9a07da commit 47956db
Show file tree
Hide file tree
Showing 17 changed files with 481 additions and 278 deletions.
635 changes: 364 additions & 271 deletions e2e/react/src/react.test.ts

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions e2e/utils/create-project-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,12 @@ export function newProject({
name = uniq('proj'),
packageManager = getSelectedPackageManager(),
packages,
workspaces = false,
}: {
name?: string;
packageManager?: 'npm' | 'yarn' | 'pnpm' | 'bun';
readonly packages?: Array<NxPackage>;
workspaces?: boolean;
} = {}): string {
const newProjectStart = performance.mark('new-project:start');
try {
Expand All @@ -95,6 +97,7 @@ export function newProject({
runCreateWorkspace(projScope, {
preset: 'apps',
packageManager,
workspaces,
});
const createNxWorkspaceEnd = performance.mark('create-nx-workspace:end');
createNxWorkspaceMeasure = performance.measure(
Expand Down Expand Up @@ -228,6 +231,7 @@ export function runCreateWorkspace(
ssr,
framework,
prefix,
workspaces,
}: {
preset: string;
appName?: string;
Expand All @@ -249,13 +253,17 @@ export function runCreateWorkspace(
ssr?: boolean;
framework?: string;
prefix?: string;
workspaces?: boolean;
}
) {
projName = name;

const pm = getPackageManagerCommand({ packageManager });

preset = workspaces ? 'ts' : preset;

let command = `${pm.createWorkspace} ${name} --preset=${preset} --nxCloud=skip --no-interactive`;

if (appName) {
command += ` --appName=${appName}`;
}
Expand Down Expand Up @@ -327,6 +335,10 @@ export function runCreateWorkspace(
command += ` --prefix=${prefix}`;
}

if (workspaces) {
command += ` --workspaces`;
}

try {
const create = execSync(`${command}${isVerbose() ? ' --verbose' : ''}`, {
cwd,
Expand Down
8 changes: 8 additions & 0 deletions packages/expo/src/generators/application/application.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
detectPackageManager,
formatFiles,
GeneratorCallback,
joinPathFragments,
Expand All @@ -21,6 +22,7 @@ import { Schema } from './schema';
import { ensureDependencies } from '../../utils/ensure-dependencies';
import { initRootBabelConfig } from '../../utils/init-root-babel-config';
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
import { addProjectToTsSolutionWorkspace } from '@nx/react/src/utils/add-app-to-pnpm-workspace';

export async function expoApplicationGenerator(
host: Tree,
Expand Down Expand Up @@ -95,6 +97,12 @@ export async function expoApplicationGeneratorInternal(
: undefined
);

// If we are using the new TS solution
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
if (options.useTsSolution) {
addProjectToTsSolutionWorkspace(host, options.appProjectRoot);
}

if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/expo/src/generators/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { addBuildTargetDefaults } from '@nx/devkit/src/generators/target-default
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { addProjectToTsSolutionWorkspace } from '@nx/react/src/utils/add-app-to-pnpm-workspace';

export async function expoLibraryGenerator(
host: Tree,
Expand Down Expand Up @@ -130,6 +131,10 @@ export async function expoLibraryGeneratorInternal(
: undefined
);

if (options.isUsingTsSolutionConfig) {
addProjectToTsSolutionWorkspace(host, `${options.projectRoot}/*`);
}

if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
8 changes: 8 additions & 0 deletions packages/next/src/generators/application/application.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
addDependenciesToPackageJson,
detectPackageManager,
formatFiles,
GeneratorCallback,
joinPathFragments,
Expand Down Expand Up @@ -31,6 +32,7 @@ import { showPossibleWarnings } from './lib/show-possible-warnings';
import { tsLibVersion } from '../../utils/versions';
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
import { addProjectToTsSolutionWorkspace } from '@nx/react/src/utils/add-app-to-pnpm-workspace';

export async function applicationGenerator(host: Tree, schema: Schema) {
return await applicationGeneratorInternal(host, {
Expand Down Expand Up @@ -132,6 +134,12 @@ export async function applicationGeneratorInternal(host: Tree, schema: Schema) {
options.src ? 'src' : '.'
);

// If we are using the new TS solution
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
if (options.useTsSolution) {
addProjectToTsSolutionWorkspace(host, options.appProjectRoot);
}

if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/generators/library/lib/normalize-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import {
ensureProjectName,
} from '@nx/devkit/src/generators/project-name-and-root-utils';
import { Schema } from '../schema';
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';

export interface NormalizedSchema extends Schema {
importPath: string;
projectRoot: string;
isUsingTsSolutionConfig: boolean;
}

export async function normalizeOptions(
Expand Down Expand Up @@ -35,5 +37,6 @@ export async function normalizeOptions(
...options,
importPath,
projectRoot,
isUsingTsSolutionConfig: isUsingTsSolutionSetup(host),
};
}
5 changes: 5 additions & 0 deletions packages/next/src/generators/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Schema } from './schema';
import { normalizeOptions } from './lib/normalize-options';
import { eslintConfigNextVersion, tsLibVersion } from '../../utils/versions';
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
import { addProjectToTsSolutionWorkspace } from '@nx/react/src/utils/add-app-to-pnpm-workspace';

export async function libraryGenerator(host: Tree, rawOptions: Schema) {
return await libraryGeneratorInternal(host, {
Expand Down Expand Up @@ -154,6 +155,10 @@ export async function libraryGeneratorInternal(host: Tree, rawOptions: Schema) {
: undefined
);

if (options.isUsingTsSolutionConfig) {
addProjectToTsSolutionWorkspace(host, `${options.projectRoot}/*`);
}

if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
detectPackageManager,
formatFiles,
GeneratorCallback,
joinPathFragments,
Expand Down Expand Up @@ -26,6 +27,7 @@ import { ensureDependencies } from '../../utils/ensure-dependencies';
import { syncDeps } from '../../executors/sync-deps/sync-deps.impl';
import { PackageJson } from 'nx/src/utils/package-json';
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
import { addProjectToTsSolutionWorkspace } from '@nx/react/src/utils/add-app-to-pnpm-workspace';

export async function reactNativeApplicationGenerator(
host: Tree,
Expand Down Expand Up @@ -143,6 +145,12 @@ export async function reactNativeApplicationGeneratorInternal(
: undefined
);

// If we are using the new TS solution
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
if (options.useTsSolution) {
addProjectToTsSolutionWorkspace(host, options.appProjectRoot);
}

if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/react-native/src/generators/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
updateTsconfigFiles,
} from '@nx/js/src/utils/typescript/ts-solution-setup';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { addProjectToTsSolutionWorkspace } from '@nx/react/src/utils/add-app-to-pnpm-workspace';

export async function reactNativeLibraryGenerator(
host: Tree,
Expand Down Expand Up @@ -130,6 +131,10 @@ export async function reactNativeLibraryGeneratorInternal(
: undefined
);

if (options.isUsingTsSolutionConfig) {
addProjectToTsSolutionWorkspace(host, `${options.projectRoot}/*`);
}

if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"@nx/web": "file:../web",
"@nx/module-federation": "file:../module-federation",
"express": "^4.19.2",
"http-proxy-middleware": "^3.0.3"
"http-proxy-middleware": "^3.0.3",
"@zkochan/js-yaml": "0.0.7"
},
"publishConfig": {
"access": "public"
Expand Down
15 changes: 13 additions & 2 deletions packages/react/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { setDefaults } from './lib/set-defaults';
import { addStyledModuleDependencies } from '../../rules/add-styled-dependencies';
import {
addDependenciesToPackageJson,
detectPackageManager,
ensurePackage,
formatFiles,
GeneratorCallback,
Expand Down Expand Up @@ -41,7 +42,11 @@ import { initGenerator as jsInitGenerator } from '@nx/js';
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
import { setupTailwindGenerator } from '../setup-tailwind/setup-tailwind';
import { useFlatConfig } from '@nx/eslint/src/utils/flat-config';
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
import {
isUsingTsSolutionSetup,
updateTsconfigFiles,
} from '@nx/js/src/utils/typescript/ts-solution-setup';
import { addProjectToTsSolutionWorkspace } from '../../utils/add-app-to-pnpm-workspace';

async function addLinting(host: Tree, options: NormalizedSchema) {
const tasks: GeneratorCallback[] = [];
Expand Down Expand Up @@ -115,7 +120,7 @@ export async function applicationGeneratorInternal(
...schema,
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
skipFormat: true,
addTsPlugin: schema.useTsSolution,
addTsPlugin: isUsingTsSolutionSetup(host),
formatter: schema.formatter,
});
tasks.push(jsInitTask);
Expand Down Expand Up @@ -367,6 +372,12 @@ export async function applicationGeneratorInternal(
moduleResolution: 'bundler',
});

// If we are using the new TS solution
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
if (options.useTsSolution) {
addProjectToTsSolutionWorkspace(host, options.appProjectRoot);
}

if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
import { assertValidStyle } from '../../../utils/assertion';
import { NormalizedSchema, Schema } from '../schema';
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
import { promptWhenInteractive } from '@nx/devkit/src/generators/prompt';

export async function normalizeOptions(
host: Tree,
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/generators/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { installCommonDependencies } from './lib/install-common-dependencies';
import { setDefaults } from './lib/set-defaults';
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
import { ensureProjectIsExcludedFromPluginRegistrations } from '@nx/js/src/utils/typescript/plugin';
import { addProjectToTsSolutionWorkspace } from '../../utils/add-app-to-pnpm-workspace';

export async function libraryGenerator(host: Tree, schema: Schema) {
return await libraryGeneratorInternal(host, {
Expand Down Expand Up @@ -278,6 +279,9 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
: undefined
);

if (options.isUsingTsSolutionConfig) {
addProjectToTsSolutionWorkspace(host, `${options.projectRoot}/*`);
}
if (!options.skipFormat) {
await formatFiles(host);
}
Expand Down
33 changes: 33 additions & 0 deletions packages/react/src/utils/add-app-to-pnpm-workspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { detectPackageManager, readJson, Tree } from '@nx/devkit';

export function addProjectToTsSolutionWorkspace(
tree: Tree,
projectDir: string
) {
if (detectPackageManager() === 'pnpm') {
const { load, dump } = require('@zkochan/js-yaml');
if (tree.exists('pnpm-workspace.yaml')) {
const workspaceFile = tree.read('pnpm-workspace.yaml', 'utf-8');
const yamlData = load(workspaceFile);

if (!yamlData.packages) {
yamlData.packages = [];
}

if (!yamlData.packages.includes(projectDir)) {
yamlData.packages.push(projectDir);
tree.write('pnpm-workspace.yaml', dump(yamlData, { indent: 2 }));
}
}
} else {
// Update package.json
const packageJson = readJson(tree, 'package.json');
if (!packageJson.workspaces) {
packageJson.workspaces = [];
}
if (!packageJson.workspaces.includes(projectDir)) {
packageJson.workspaces.push(projectDir);
tree.write('package.json', JSON.stringify(packageJson, null, 2));
}
}
}
8 changes: 8 additions & 0 deletions packages/remix/src/generators/application/application.impl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
addProjectConfiguration,
detectPackageManager,
ensurePackage,
formatFiles,
generateFiles,
Expand Down Expand Up @@ -48,6 +49,7 @@ import {
isUsingTsSolutionSetup,
updateTsconfigFiles,
} from '@nx/js/src/utils/typescript/ts-solution-setup';
import { addProjectToTsSolutionWorkspace } from '@nx/react/src/utils/add-app-to-pnpm-workspace';

export function remixApplicationGenerator(
tree: Tree,
Expand Down Expand Up @@ -374,6 +376,12 @@ export default {...nxPreset};
'.'
);

// If we are using the new TS solution
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
if (options.useTsSolution) {
addProjectToTsSolutionWorkspace(tree, options.projectRoot);
}

tasks.push(() => {
logShowProjectCommand(options.projectName);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
const packageJson = tree.read('/proj/pnpm-workspace.yaml', 'utf-8');
expect(packageJson).toMatchInlineSnapshot(`
"packages:
- apps/**
- packages/**
- "apps/**"
- "packages/**"
"
`);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ function setUpWorkspacesInPackageJson(tree: Tree, options: NormalizedSchema) {
tree.write(
join(options.directory, 'pnpm-workspace.yaml'),
`packages:
- ${workspaces.join('\n - ')}
${workspaces.map((workspace) => `- "${workspace}"`).join('\n ')}
`
);
} else {
Expand Down

0 comments on commit 47956db

Please sign in to comment.