Skip to content

Commit

Permalink
feat(devkit): prefer strings over Linter enum (#27209)
Browse files Browse the repository at this point in the history
We should be consistent about how options are defined in our plugins.
Currently, there are some options that use `enum`s and some that use
typed strings. I think typed strings are preferable because someone
extending a generator only needs to import the main generator that
they're extending, not all the transitive dependencies of that
generator.

Current extending code:
```
// ...
import { applicationGenerator as reactApplicationGenerator } from '@nx/react';
import { Linter } from '@nx/eslint';

export async function applicationGenerator(
  tree: Tree,
  options: ApplicationGeneratorSchema
) {
  reactApplicationGenerator(tree, {
    ...options,
    linter: Linter.EsLint,
  });
}
```

Desired extending code:
```
// ...
import { applicationGenerator as reactApplicationGenerator } from '@nx/react';

export async function applicationGenerator(
  tree: Tree,
  options: ApplicationGeneratorSchema
) {
  reactApplicationGenerator(tree, {
    ...options,
    linter: 'eslint',
  });
}
```

The problem is not just an extra line of code, the person extending the
`reactApplicationGenerator` has to dig into the implementation details
of the generator itself in order to know where to find the `Linter`
enum. The `e2eTestRunner` is already a typed string and is easily
extended.

The solution I'm proposing in this PR would define a typed string in the
same file as the existing enum. None of the implementations need to
change. No community plugin code will be broken.
  • Loading branch information
isaacplmann authored Aug 19, 2024
1 parent 14be63b commit 839dc15
Show file tree
Hide file tree
Showing 55 changed files with 117 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { NxCloudOnBoardingStatus } from 'nx/src/nx-cloud/models/onboarding-status';
import { E2eTestRunner, UnitTestRunner } from '../../../utils/test-runners';
import type { Schema } from '../schema';
import { Linter } from '@nx/eslint';
import { Linter, LinterType } from '@nx/eslint';

export interface NormalizedSchema extends Schema {
linter: Linter;
linter: Linter | LinterType;
unitTestRunner: UnitTestRunner;
e2eTestRunner: E2eTestRunner;
prefix: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import type { Styles } from '../utils/types';

Expand All @@ -17,7 +17,7 @@ export interface Schema {
directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
tags?: string;
linter?: Linter;
linter?: Linter | LinterType;
unitTestRunner?: UnitTestRunner;
e2eTestRunner?: E2eTestRunner;
backendProject?: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/generators/host/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import type { Styles } from '../utils/types';

Expand All @@ -17,7 +17,7 @@ export interface Schema {
directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
tags?: string;
linter?: Linter;
linter?: Linter | LinterType;
unitTestRunner?: UnitTestRunner;
e2eTestRunner?: E2eTestRunner;
backendProject?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UnitTestRunner } from '../../../utils/test-runners';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface NormalizedSchema {
libraryOptions: {
Expand Down Expand Up @@ -27,7 +27,7 @@ export interface NormalizedSchema {
skipPackageJson?: boolean;
skipPostInstall?: boolean;
standalone?: boolean;
linter: Linter;
linter: Linter | LinterType;
unitTestRunner: UnitTestRunner;
prefix: string;
fileName: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/generators/library/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { UnitTestRunner } from '../../utils/test-runners';

export interface Schema {
Expand All @@ -24,7 +24,7 @@ export interface Schema {
parent?: string;
tags?: string;
strict?: boolean;
linter?: Linter;
linter?: Linter | LinterType;
unitTestRunner?: UnitTestRunner;
compilationMode?: 'full' | 'partial';
setParserOptionsProject?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/generators/ng-add/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Linter } from '@nx/eslint';
import { Linter, LinterType } from '@nx/eslint';
import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import type { Styles } from '../utils/types';

Expand All @@ -11,6 +11,6 @@ export interface GeneratorOptions {
skipInstall?: boolean;
skipPostInstall?: boolean;
style?: Styles;
linter?: Linter;
linter?: Linter | LinterType;
skipPackageJson?: boolean;
}
4 changes: 2 additions & 2 deletions packages/angular/src/generators/remote/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import type { Styles } from '../utils/types';

Expand All @@ -16,7 +16,7 @@ export interface Schema {
directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
tags?: string;
linter?: Linter;
linter?: Linter | LinterType;
unitTestRunner?: UnitTestRunner;
e2eTestRunner?: E2eTestRunner;
backendProject?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface StorybookConfigurationOptions {
configureStaticServe?: boolean;
generateStories: boolean;
linter: Linter;
linter: Linter | LinterType;
project: string;
tsConfiguration?: boolean;
skipFormat?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
getRelativePathToRootTsConfig,
initGenerator as jsInitGenerator,
} from '@nx/js';
import { Linter } from '@nx/eslint';
import { Linter, LinterType } from '@nx/eslint';
import { join } from 'path';
import { addLinterToCyProject } from '../../utils/add-linter';
import { addDefaultE2EConfig } from '../../utils/config';
Expand All @@ -40,7 +40,7 @@ export interface CypressE2EConfigSchema {
skipPackageJson?: boolean;
bundler?: 'webpack' | 'vite' | 'none';
devServerTarget?: string;
linter?: Linter;
linter?: Linter | LinterType;
port?: number | 'cypress-auto';
jsx?: boolean;
rootProject?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/cypress/src/utils/add-linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
runTasksInSerial,
Tree,
} from '@nx/devkit';
import { Linter, lintProjectGenerator } from '@nx/eslint';
import { Linter, LinterType, lintProjectGenerator } from '@nx/eslint';
import { installedCypressVersion } from './cypress-version';
import { eslintPluginCypressVersion } from './versions';
import {
Expand All @@ -24,7 +24,7 @@ import {

export interface CyLinterOptions {
project: string;
linter: Linter;
linter: Linter | LinterType;
setParserOptionsProject?: boolean;
skipPackageJson?: boolean;
rootProject?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/detox/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface Schema {
appProject: string; // name of the project app to be tested (directory + app name in kebab class)
Expand All @@ -8,7 +8,7 @@ export interface Schema {
e2eDirectory?: string; // the directory where e2e app going to be located
projectNameAndRootFormat?: ProjectNameAndRootFormat;
e2eName: string; // name of the e2e app
linter?: Linter;
linter?: Linter | LinterType;
js?: boolean;
skipFormat?: boolean;
setParserOptionsProject?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { lintProjectGenerator } from './src/generators/lint-project/lint-project';
export { lintInitGenerator } from './src/generators/init/init';
export { Linter } from './src/generators/utils/linter';
export { Linter, LinterType } from './src/generators/utils/linter';

// @nx/angular needs it for the Angular CLI workspace migration to Nx to
// infer whether a config is using type aware rules and set the
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint/src/generators/lint-project/lint-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
writeJson,
} from '@nx/devkit';

import { Linter as LinterEnum } from '../utils/linter';
import { Linter as LinterEnum, LinterType } from '../utils/linter';
import { findEslintFile } from '../utils/eslint-file';
import { join } from 'path';
import { lintInitGenerator } from '../init/init';
Expand All @@ -39,7 +39,7 @@ import { setupRootEsLint } from './setup-root-eslint';

interface LintProjectOptions {
project: string;
linter?: LinterEnum;
linter?: LinterEnum | LinterType;
eslintFilePatterns?: string[];
tsConfigPaths?: string[];
skipFormat: boolean;
Expand Down
5 changes: 5 additions & 0 deletions packages/eslint/src/generators/utils/linter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
/*
* @deprecated Use LinterType instead
*/
export enum Linter {
EsLint = 'eslint',
None = 'none',
}

export type LinterType = 'eslint' | 'none';
4 changes: 2 additions & 2 deletions packages/expo/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface Schema {
name: string;
Expand All @@ -13,7 +13,7 @@ export interface Schema {
pascalCaseFiles?: boolean;
classComponent?: boolean;
js: boolean; // default is false
linter: Linter; // default is eslint
linter: Linter | LinterType; // default is eslint
setParserOptionsProject?: boolean; // default is false
e2eTestRunner: 'cypress' | 'playwright' | 'detox' | 'none'; // default is playwright
standaloneConfig?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/expo/src/generators/library/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

/**
* Same as the @nx/react library schema, except it removes keys: style, component, routing, appProject
Expand All @@ -13,7 +13,7 @@ export interface Schema {
tags?: string;
pascalCaseFiles?: boolean;
unitTestRunner: 'jest' | 'none';
linter: Linter; // default is eslint
linter: Linter | LinterType; // default is eslint
publishable?: boolean;
buildable?: boolean;
importPath?: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/expo/src/utils/add-linting.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Linter, lintProjectGenerator } from '@nx/eslint';
import { Linter, LinterType, lintProjectGenerator } from '@nx/eslint';
import {
addDependenciesToPackageJson,
GeneratorCallback,
Expand All @@ -13,7 +13,7 @@ import {
} from '@nx/eslint/src/generators/utils/eslint-file';

interface NormalizedSchema {
linter?: Linter;
linter?: Linter | LinterType;
projectName: string;
projectRoot: string;
setParserOptionsProject?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/express/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { UnitTestRunner } from '../../utils/test-runners';

export interface Schema {
Expand All @@ -10,7 +10,7 @@ export interface Schema {
projectNameAndRootFormat?: ProjectNameAndRootFormat;
unitTestRunner: UnitTestRunner;
tags?: string;
linter: Linter;
linter: Linter | LinterType;
frontendProject?: string;
swcJest?: boolean;
/** @deprecated use `swcJest` instead */
Expand Down
4 changes: 2 additions & 2 deletions packages/js/src/utils/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project
import type { AssetGlob, FileInputOutput } from './assets/assets';
import { TransformerEntry } from './typescript/types';
// nx-ignore-next-line
const { Linter } = require('@nx/eslint'); // use require to import to avoid circular dependency
const { Linter, LinterType } = require('@nx/eslint'); // use require to import to avoid circular dependency

export type Compiler = 'tsc' | 'swc';
export type Bundler = 'swc' | 'tsc' | 'rollup' | 'vite' | 'esbuild' | 'none';
Expand All @@ -17,7 +17,7 @@ export interface LibraryGeneratorSchema {
skipPackageJson?: boolean;
includeBabelRc?: boolean;
unitTestRunner?: 'jest' | 'vitest' | 'none';
linter?: Linter;
linter?: Linter | LinterType;
testEnvironment?: 'jsdom' | 'node';
importPath?: string;
js?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/nest/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface ApplicationGeneratorOptions {
name: string;
directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
frontendProject?: string;
linter?: Linter;
linter?: Linter | LinterType;
skipFormat?: boolean;
skipPackageJson?: boolean;
standaloneConfig?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/nest/src/generators/library/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { UnitTestRunner } from '../utils';

export interface LibraryGeneratorOptions {
Expand All @@ -10,7 +10,7 @@ export interface LibraryGeneratorOptions {
projectNameAndRootFormat?: ProjectNameAndRootFormat;
global?: boolean;
importPath?: string;
linter?: Linter;
linter?: Linter | LinterType;
publishable?: boolean;
service?: boolean;
skipFormat?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { SupportedStyles } from '@nx/react';

export interface Schema {
Expand All @@ -11,7 +11,7 @@ export interface Schema {
tags?: string;
unitTestRunner?: 'jest' | 'none';
e2eTestRunner?: 'cypress' | 'playwright' | 'none';
linter?: Linter;
linter?: Linter | LinterType;
js?: boolean;
setParserOptionsProject?: boolean;
swc?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/generators/library/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';
import type { SupportedStyles } from '@nx/react';

export interface Schema {
Expand All @@ -14,7 +14,7 @@ export interface Schema {
routing?: boolean;
appProject?: string;
unitTestRunner: 'jest' | 'none';
linter: Linter;
linter: Linter | LinterType;
component?: boolean;
publishable?: boolean;
buildable?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/node/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface Schema {
name: string;
Expand All @@ -9,7 +9,7 @@ export interface Schema {
projectNameAndRootFormat?: ProjectNameAndRootFormat;
unitTestRunner?: 'jest' | 'none';
e2eTestRunner?: 'jest' | 'none';
linter?: Linter;
linter?: Linter | LinterType;
tags?: string;
frontendProject?: string;
swcJest?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/node/src/generators/library/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface Schema {
name: string;
Expand All @@ -10,7 +10,7 @@ export interface Schema {
skipFormat?: boolean;
tags?: string;
unitTestRunner?: 'jest' | 'none';
linter?: Linter;
linter?: Linter | LinterType;
buildable?: boolean;
publishable?: boolean;
importPath?: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/nuxt/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/eslint';
import type { Linter, LinterType } from '@nx/eslint';

export interface Schema {
name: string;
directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
linter?: Linter;
linter?: Linter | LinterType;
skipFormat?: boolean;
unitTestRunner?: 'vitest' | 'none';
e2eTestRunner?: 'cypress' | 'playwright' | 'none';
Expand Down
Loading

0 comments on commit 839dc15

Please sign in to comment.