nx/packages/workspace/src/generators/new/generate-preset.ts
Leosvel Pérez Espinosa 1ae3c2d8f9
fix(angular): generate @nx/angular in devDependencies and move to dependencies when using runtime helpers (#27405)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

New workspaces are generated with `@nx/angular` as a production
dependency even though the generated code does not use any runtime
helper from it.

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

New workspaces should be generated with `@nx/angular` as a development
dependency. When generating a new MF host or dynamic MF application
(host or remote), the `@nx/angular` package should be moved to the
production dependencies because the generated code uses some runtime
helpers from it.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #27333
2024-08-16 09:23:19 -04:00

203 lines
5.8 KiB
TypeScript

import {
addDependenciesToPackageJson,
getPackageManagerCommand,
Tree,
} from '@nx/devkit';
import { Preset } from '../utils/presets';
import {
angularCliVersion,
nxVersion,
typescriptVersion,
} from '../../utils/versions';
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';
export function addPresetDependencies(host: Tree, options: NormalizedSchema) {
const { dependencies, dev } = getPresetDependencies(options);
return addDependenciesToPackageJson(
host,
dependencies,
dev,
join(options.directory, 'package.json')
);
}
export function generatePreset(host: Tree, opts: NormalizedSchema) {
const parsedArgs = yargsParser(process.argv, {
boolean: ['interactive'],
default: {
interactive: true,
},
});
const spawnOptions: SpawnOptions = {
stdio: 'inherit',
shell: true,
cwd: join(host.root, opts.directory),
};
const pmc = getPackageManagerCommand();
const executable = `${pmc.exec} nx`;
const args = getPresetArgs(opts);
return new Promise<void>((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));
}
});
});
function getPresetArgs(options: NormalizedSchema) {
// supported presets
return getDefaultArgs(options);
}
function getDefaultArgs(opts: NormalizedSchema) {
return [
`g`,
`@nx/workspace:preset`,
`--name=${opts.appName}`,
opts.style ? `--style=${opts.style}` : null,
opts.linter ? `--linter=${opts.linter}` : null,
opts.preset ? `--preset=${opts.preset}` : null,
opts.bundler ? `--bundler=${opts.bundler}` : null,
opts.framework ? `--framework=${opts.framework}` : null,
opts.docker ? `--docker=${opts.docker}` : null,
opts.js ? `--js` : null,
opts.nextAppDir ? '--nextAppDir=true' : '--nextAppDir=false',
opts.nextSrcDir ? '--nextSrcDir=true' : '--nextSrcDir=false',
opts.packageManager ? `--packageManager=${opts.packageManager}` : null,
opts.standaloneApi !== undefined
? `--standaloneApi=${opts.standaloneApi}`
: null,
parsedArgs.interactive ? '--interactive=true' : '--interactive=false',
opts.routing !== undefined ? `--routing=${opts.routing}` : null,
opts.e2eTestRunner !== undefined
? `--e2eTestRunner=${opts.e2eTestRunner}`
: null,
opts.ssr ? `--ssr` : null,
opts.prefix !== undefined ? `--prefix=${opts.prefix}` : null,
opts.nxCloudToken ? `--nxCloudToken=${opts.nxCloudToken}` : null,
].filter((e) => !!e);
}
}
function getPresetDependencies({
preset,
presetVersion,
bundler,
e2eTestRunner,
}: NormalizedSchema) {
switch (preset) {
case Preset.Apps:
case Preset.NPM:
case Preset.TS:
case Preset.TsStandalone:
return { dependencies: {}, dev: { '@nx/js': nxVersion } };
case Preset.AngularMonorepo:
case Preset.AngularStandalone:
return {
dependencies: {},
dev: {
'@angular-devkit/core': angularCliVersion,
'@nx/angular': nxVersion,
typescript: typescriptVersion,
},
};
case Preset.Express:
return { dependencies: {}, dev: { '@nx/express': nxVersion } };
case Preset.Nest:
return {
dependencies: {},
dev: { '@nx/nest': nxVersion, typescript: typescriptVersion },
};
case Preset.NextJs:
case Preset.NextJsStandalone:
return { dependencies: { '@nx/next': nxVersion }, dev: {} };
case Preset.RemixStandalone:
case Preset.RemixMonorepo:
return { dependencies: { '@nx/remix': nxVersion }, dev: {} };
case Preset.VueMonorepo:
case Preset.VueStandalone:
return {
dependencies: {},
dev: {
'@nx/vue': nxVersion,
'@nx/cypress': e2eTestRunner === 'cypress' ? nxVersion : undefined,
'@nx/playwright':
e2eTestRunner === 'playwright' ? nxVersion : undefined,
'@nx/vite': nxVersion,
},
};
case Preset.Nuxt:
case Preset.NuxtStandalone:
return {
dependencies: {},
dev: {
'@nx/nuxt': nxVersion,
'@nx/cypress': e2eTestRunner === 'cypress' ? nxVersion : undefined,
'@nx/playwright':
e2eTestRunner === 'playwright' ? nxVersion : undefined,
},
};
case Preset.ReactMonorepo:
case Preset.ReactStandalone:
return {
dependencies: {},
dev: {
'@nx/react': nxVersion,
'@nx/cypress': e2eTestRunner !== 'none' ? nxVersion : undefined,
'@nx/jest': bundler !== 'vite' ? nxVersion : undefined,
'@nx/vite': bundler === 'vite' ? nxVersion : undefined,
'@nx/webpack': bundler === 'webpack' ? nxVersion : undefined,
},
};
case Preset.ReactNative:
return { dependencies: {}, dev: { '@nx/react-native': nxVersion } };
case Preset.Expo:
return { dependencies: {}, dev: { '@nx/expo': nxVersion } };
case Preset.WebComponents:
return {
dependencies: {},
dev: { '@nx/web': nxVersion, typescript: typescriptVersion },
};
case Preset.NodeStandalone:
case Preset.NodeMonorepo:
return {
dependencies: {},
dev: {
'@nx/node': nxVersion,
'@nx/webpack': bundler === 'webpack' ? nxVersion : undefined,
},
};
default: {
return {
dev: {},
dependencies: {
[preset]:
process.env['NX_E2E_PRESET_VERSION'] ??
getNpmPackageVersion(preset, presetVersion),
},
};
}
}
}