nx/packages/react/src/generators/application/lib/normalize-options.ts
Colum Ferry 320d9f223f
fix(testing): application generators should accurately configure e2e projects (#27453)
- feat(devkit): add util for determining the e2e web server info
- feat(vite): add util for determining the e2e web server info
- feat(webpack): add util for determining the e2e web server info
- fix(webpack): allow port override
- fix(devkit): e2e web server info util should handle target defaults
- feat(webpack): export the e2e web server info utils
- fix(vite): rename util
- fix(devkit): util should determine the devTarget for cypress
- fix(react): improve accuracy of e2e project generation

<!-- 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 -->
The logic for finding the correct targets and web addresses to use when
setting up e2e projects is flawed and missing some key considerations.


## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The logic is accurate and usage is simplified across plugins 

Projects:
- [x] Angular
- [x] Expo
- [x] Next
- [x] Nuxt
- [x] Vue
- [x] Web
- [x] Remix
- [x] React
- [x] React Native


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

Fixes #
2024-08-27 10:00:43 -04:00

90 lines
3.1 KiB
TypeScript

import { Tree, extractLayoutDirectory, names, readNxJson } from '@nx/devkit';
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
import { assertValidStyle } from '../../../utils/assertion';
import { NormalizedSchema, Schema } from '../schema';
import { findFreePort } from './find-free-port';
import { VitePluginOptions } from '@nx/vite/src/plugins/plugin';
import { WebpackPluginOptions } from '@nx/webpack/src/plugins/plugin';
export function normalizeDirectory(options: Schema) {
options.directory = options.directory?.replace(/\\{1,2}/g, '/');
const { projectDirectory } = extractLayoutDirectory(options.directory);
return projectDirectory
? `${names(projectDirectory).fileName}/${names(options.name).fileName}`
: names(options.name).fileName;
}
export function normalizeProjectName(options: Schema) {
return normalizeDirectory(options).replace(new RegExp('/', 'g'), '-');
}
export async function normalizeOptions<T extends Schema = Schema>(
host: Tree,
options: Schema,
callingGenerator = '@nx/react:application'
): Promise<NormalizedSchema<T>> {
const {
projectName: appProjectName,
projectRoot: appProjectRoot,
projectNameAndRootFormat,
} = await determineProjectNameAndRootOptions(host, {
name: options.name,
projectType: 'application',
directory: options.directory,
projectNameAndRootFormat: options.projectNameAndRootFormat,
rootProject: options.rootProject,
callingGenerator,
});
const nxJson = readNxJson(host);
const addPlugin =
process.env.NX_ADD_PLUGINS !== 'false' &&
nxJson.useInferencePlugins !== false;
options.addPlugin ??= addPlugin;
options.rootProject = appProjectRoot === '.';
options.projectNameAndRootFormat = projectNameAndRootFormat;
const e2eProjectName = options.rootProject ? 'e2e' : `${appProjectName}-e2e`;
const e2eProjectRoot = options.rootProject ? 'e2e' : `${appProjectRoot}-e2e`;
const parsedTags = options.tags
? options.tags.split(',').map((s) => s.trim())
: [];
const fileName = options.pascalCaseFiles ? 'App' : 'app';
const styledModule = /^(css|scss|less|tailwind|none)$/.test(options.style)
? null
: options.style;
assertValidStyle(options.style);
const normalized = {
...options,
name: names(options.name).fileName,
projectName: appProjectName,
appProjectRoot,
e2eProjectName,
e2eProjectRoot,
parsedTags,
fileName,
styledModule,
hasStyles: options.style !== 'none',
} as NormalizedSchema;
normalized.routing = normalized.routing ?? false;
normalized.strict = normalized.strict ?? true;
normalized.classComponent = normalized.classComponent ?? false;
normalized.compiler = normalized.compiler ?? 'babel';
normalized.bundler = normalized.bundler ?? 'webpack';
normalized.unitTestRunner = normalized.unitTestRunner ?? 'jest';
normalized.e2eTestRunner = normalized.e2eTestRunner ?? 'playwright';
normalized.inSourceTests = normalized.minimal || normalized.inSourceTests;
normalized.devServerPort ??= findFreePort(host);
normalized.minimal = normalized.minimal ?? false;
return normalized;
}