- 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 #
90 lines
3.1 KiB
TypeScript
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;
|
|
}
|