diff --git a/packages/workspace/src/generators/new/generate-preset.ts b/packages/workspace/src/generators/new/generate-preset.ts index 6824da637cc09..1b4ff94db1fcc 100644 --- a/packages/workspace/src/generators/new/generate-preset.ts +++ b/packages/workspace/src/generators/new/generate-preset.ts @@ -13,7 +13,8 @@ import { getNpmPackageVersion } from '../utils/get-npm-package-version'; import { NormalizedSchema } from './new'; import { join } from 'path'; import * as yargsParser from 'yargs-parser'; -import { spawn, SpawnOptions } from 'child_process'; +import { fork, ForkOptions } from 'child_process'; +import { getNxRequirePaths } from 'nx/src/utils/installation-directory'; export function addPresetDependencies(host: Tree, options: NormalizedSchema) { const { dependencies, dev } = getPresetDependencies(options); @@ -32,25 +33,34 @@ export function generatePreset(host: Tree, opts: NormalizedSchema) { interactive: true, }, }); - const spawnOptions: SpawnOptions = { + + const newWorkspaceRoot = join(host.root, opts.directory); + const forkOptions: ForkOptions = { stdio: 'inherit', - shell: true, - cwd: join(host.root, opts.directory), - windowsHide: false, + cwd: newWorkspaceRoot, }; const pmc = getPackageManagerCommand(); - const executable = `${pmc.exec} nx`; + const nxInstallationPaths = getNxRequirePaths(newWorkspaceRoot); + const nxBinForNewWorkspaceRoot = require.resolve('nx/bin/nx', { + paths: nxInstallationPaths, + }); const args = getPresetArgs(opts); return new Promise((resolve, reject) => { - spawn(executable, args, spawnOptions).on('close', (code: number) => { - if (code === 0) { - resolve(); - } else { - const message = 'Workspace creation failed, see above.'; - reject(new Error(message)); + // This needs to be `fork` instead of `spawn` because `spawn` is failing on Windows with pnpm + yarn + // The root cause is unclear. Spawn causes the `@nx/workspace:preset` generator to be called twice + // and the second time it fails with `Project {projectName} already exists.` + fork(nxBinForNewWorkspaceRoot, args, forkOptions).on( + 'close', + (code: number) => { + if (code === 0) { + resolve(); + } else { + const message = 'Workspace creation failed, see above.'; + reject(new Error(message)); + } } - }); + ); }); function getPresetArgs(options: NormalizedSchema) {