From 0515d7edb1f4413f387c25c68f84bbdaa0ed1a3c Mon Sep 17 00:00:00 2001 From: SimeonC <1085899+SimeonC@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:20:40 +0900 Subject: [PATCH] feat: add and replace stylistic rules around imports See https://github.com/tablecheck/settings-frontend/pull/967#discussion_r1678656187 --- package-lock.json | 10 +++++++ packages/audit/src/index.ts | 4 +-- packages/eslint-config/package.json | 1 + packages/eslint-config/src/index.ts | 1 + .../src/overrides/buildBaseTypescript.ts | 7 +++++ .../eslint-config/src/overrides/cypress.ts | 2 +- packages/eslint-config/src/presets/basic.ts | 9 ++++++- packages/eslint-config/src/rules/general.ts | 27 ++++++++++++++++--- .../__tests__/forbiddenImports.test.ts | 7 +++-- .../__tests__/shortestImport.test.ts | 2 +- .../src/consistentReactImport.ts | 2 +- .../eslint-plugin/src/forbiddenImports.ts | 4 +-- packages/eslint-plugin/src/shortestImport.ts | 4 +-- packages/nx/src/executors/publint/executor.ts | 2 +- packages/nx/src/executors/quality/executor.ts | 2 +- .../nx/src/generators/quality/eslintConfig.ts | 2 +- .../nx/src/generators/quality/generator.ts | 8 +++--- .../src/generators/quality/projectConfig.ts | 2 +- .../generators/ts-carbon-icons/generator.ts | 2 +- .../src/generators/ts-file-types/generator.ts | 4 +-- .../generators/ts-node-config/generator.ts | 2 +- .../nx/src/generators/vite-lib/generator.ts | 2 +- packages/nx/src/utils/nx.ts | 2 +- packages/nx/src/utils/packageJson.ts | 2 +- packages/nx/src/utils/tempFiles.ts | 2 +- 25 files changed, 80 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index b9368fb4..1390ed4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2484,6 +2484,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -18126,6 +18127,14 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-simple-import-sort": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", + "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, "node_modules/eslint-rule-docs": { "version": "1.1.235", "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", @@ -38609,6 +38618,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", + "eslint-plugin-simple-import-sort": "^12.1.1", "fs-extra": "^11.1.1", "queue-microtask": "^1.2.3" }, diff --git a/packages/audit/src/index.ts b/packages/audit/src/index.ts index 884b87cf..3ab70522 100644 --- a/packages/audit/src/index.ts +++ b/packages/audit/src/index.ts @@ -2,8 +2,8 @@ import * as path from 'path'; import * as prompts from '@clack/prompts'; import CVSS, { - DetailedVectorObject, - VectorMetric, + type DetailedVectorObject, + type VectorMetric, } from '@turingpointde/cvss.js'; import definitions from '@turingpointde/cvss.js/lib/cvss_3_0.json' assert { type: 'json' }; import chalk from 'chalk'; diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 6307d7c3..fbf92ea2 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -74,6 +74,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", + "eslint-plugin-simple-import-sort": "^12.1.1", "fs-extra": "^11.1.1", "queue-microtask": "^1.2.3" }, diff --git a/packages/eslint-config/src/index.ts b/packages/eslint-config/src/index.ts index 446787c4..1c34f83b 100644 --- a/packages/eslint-config/src/index.ts +++ b/packages/eslint-config/src/index.ts @@ -55,6 +55,7 @@ module.exports = { '@tablecheck', '@nx', 'react-refresh', + 'simple-import-sort', ], globals: { diff --git a/packages/eslint-config/src/overrides/buildBaseTypescript.ts b/packages/eslint-config/src/overrides/buildBaseTypescript.ts index 28182d87..dd280e3c 100644 --- a/packages/eslint-config/src/overrides/buildBaseTypescript.ts +++ b/packages/eslint-config/src/overrides/buildBaseTypescript.ts @@ -40,6 +40,13 @@ export const baseTypescriptRules: Linter.RulesRecord = { }, }, ], + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + disallowTypeAnnotations: false, + fixStyle: 'inline-type-imports', + }, + ], '@tablecheck/prefer-shortest-import': 'error', }; diff --git a/packages/eslint-config/src/overrides/cypress.ts b/packages/eslint-config/src/overrides/cypress.ts index 1e674a30..51ade730 100644 --- a/packages/eslint-config/src/overrides/cypress.ts +++ b/packages/eslint-config/src/overrides/cypress.ts @@ -1,4 +1,4 @@ -import { Linter } from 'eslint'; +import { type Linter } from 'eslint'; import { namingRules } from '../rules/namingConvention'; import { mergeDeep as merge } from '../utils/merge'; diff --git a/packages/eslint-config/src/presets/basic.ts b/packages/eslint-config/src/presets/basic.ts index 785948d6..19e08d4a 100644 --- a/packages/eslint-config/src/presets/basic.ts +++ b/packages/eslint-config/src/presets/basic.ts @@ -15,7 +15,14 @@ if (!process.env.NODE_ENV) { module.exports = { extends: ['airbnb', 'plugin:eslint-comments/recommended', 'prettier'], - plugins: ['eslint-comments', 'promise', '@tablecheck', '@nx', '@emotion'], + plugins: [ + 'eslint-comments', + 'promise', + '@tablecheck', + '@nx', + '@emotion', + 'simple-import-sort', + ], parserOptions: { ecmaVersion: 'latest', diff --git a/packages/eslint-config/src/rules/general.ts b/packages/eslint-config/src/rules/general.ts index ebf47eb0..7905aa66 100644 --- a/packages/eslint-config/src/rules/general.ts +++ b/packages/eslint-config/src/rules/general.ts @@ -21,14 +21,33 @@ export const generalRules: Linter.RulesRecord = { }, ], 'import/newline-after-import': 'error', - 'import/order': [ + 'import/order': 'off', + 'simple-import-sort/imports': [ 'error', { - groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], - 'newlines-between': 'always', - alphabetize: { order: 'asc', caseInsensitive: false }, + groups: [ + // Node.js builtins. + [ + '^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)', + ], + // Packages. `react` related packages come first. + ['^react', '^@?\\w'], + // Internal packages. + ['^(@|@local|~)(/.*|$)'], + // Side effect imports. + ['^\\u0000'], + // Parent imports. Put `..` last. + ['^\\.\\.(?!/?$)', '^\\.\\./?$'], + // Other relative imports. Put same-folder imports and `.` last. + ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], + // Style imports. + ['^.+\\.s?css$'], + ], }, ], + 'simple-import-sort/exports': 'error', + 'import/first': 'error', + 'import/no-duplicates': 'error', // https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html 'import/prefer-default-export': 'off', 'import/no-default-export': 'error', diff --git a/packages/eslint-plugin/__tests__/forbiddenImports.test.ts b/packages/eslint-plugin/__tests__/forbiddenImports.test.ts index 49a7a6e9..d834b8c4 100644 --- a/packages/eslint-plugin/__tests__/forbiddenImports.test.ts +++ b/packages/eslint-plugin/__tests__/forbiddenImports.test.ts @@ -1,7 +1,10 @@ import { RuleTester } from '@typescript-eslint/rule-tester'; -import { TSESLint } from '@typescript-eslint/utils'; +import { type TSESLint } from '@typescript-eslint/utils'; -import { forbiddenImports as rule, messageId } from '../src/forbiddenImports'; +import { + forbiddenImports as rule, + type messageId, +} from '../src/forbiddenImports'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/__tests__/shortestImport.test.ts b/packages/eslint-plugin/__tests__/shortestImport.test.ts index 562f2420..6d3a11a9 100644 --- a/packages/eslint-plugin/__tests__/shortestImport.test.ts +++ b/packages/eslint-plugin/__tests__/shortestImport.test.ts @@ -2,7 +2,7 @@ import { join as pathJoin } from 'path'; import { RuleTester } from '@typescript-eslint/rule-tester'; -import { shortestImport as rule, messageId } from '../src/shortestImport'; +import { messageId, shortestImport as rule } from '../src/shortestImport'; const typescriptSetups = [ { diff --git a/packages/eslint-plugin/src/consistentReactImport.ts b/packages/eslint-plugin/src/consistentReactImport.ts index 452a5065..bf8fa35a 100644 --- a/packages/eslint-plugin/src/consistentReactImport.ts +++ b/packages/eslint-plugin/src/consistentReactImport.ts @@ -1,6 +1,6 @@ import type { ImportSpecifier } from '@typescript-eslint/types/dist/generated/ast-spec'; import { TSESLint, TSESTree } from '@typescript-eslint/utils'; -import { RuleFix } from '@typescript-eslint/utils/dist/ts-eslint'; +import { type RuleFix } from '@typescript-eslint/utils/dist/ts-eslint'; export const messageId = 'consistentReactImport'; diff --git a/packages/eslint-plugin/src/forbiddenImports.ts b/packages/eslint-plugin/src/forbiddenImports.ts index ef7d8bcf..af07273b 100644 --- a/packages/eslint-plugin/src/forbiddenImports.ts +++ b/packages/eslint-plugin/src/forbiddenImports.ts @@ -1,6 +1,6 @@ import { TSESTree } from '@typescript-eslint/types'; -import { TSESLint } from '@typescript-eslint/utils'; -import { RuleFix } from '@typescript-eslint/utils/ts-eslint'; +import { type TSESLint } from '@typescript-eslint/utils'; +import { type RuleFix } from '@typescript-eslint/utils/ts-eslint'; type ImportDeclaration = TSESTree.ImportDeclaration; type ImportSpecifier = TSESTree.ImportSpecifier; diff --git a/packages/eslint-plugin/src/shortestImport.ts b/packages/eslint-plugin/src/shortestImport.ts index c0acfb1f..1342e05d 100644 --- a/packages/eslint-plugin/src/shortestImport.ts +++ b/packages/eslint-plugin/src/shortestImport.ts @@ -1,9 +1,9 @@ import * as path from 'path'; import type { TSESTree } from '@typescript-eslint/types'; -import { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES, type TSESLint } from '@typescript-eslint/utils'; import fs from 'fs-extra'; -import { CompilerOptions } from 'typescript'; +import { type CompilerOptions } from 'typescript'; type ImportExpression = TSESTree.ImportDeclaration; type ImportDeclaration = TSESTree.ImportExpression; diff --git a/packages/nx/src/executors/publint/executor.ts b/packages/nx/src/executors/publint/executor.ts index b87ccc9d..aca07c7e 100644 --- a/packages/nx/src/executors/publint/executor.ts +++ b/packages/nx/src/executors/publint/executor.ts @@ -1,4 +1,4 @@ -import { ExecutorContext } from '@nx/devkit'; +import { type ExecutorContext } from '@nx/devkit'; import { dynamicImport } from 'tsimportlib'; export default async function runExecutor( diff --git a/packages/nx/src/executors/quality/executor.ts b/packages/nx/src/executors/quality/executor.ts index be5db259..648dacfd 100644 --- a/packages/nx/src/executors/quality/executor.ts +++ b/packages/nx/src/executors/quality/executor.ts @@ -1,6 +1,6 @@ import { execSync } from 'child_process'; -import { ExecutorContext } from '@nx/devkit'; +import { type ExecutorContext } from '@nx/devkit'; import lintRun from '@nx/eslint/src/executors/lint/lint.impl.js'; import { configCheck } from './configs.js'; diff --git a/packages/nx/src/generators/quality/eslintConfig.ts b/packages/nx/src/generators/quality/eslintConfig.ts index b8f97afc..88fe4f76 100644 --- a/packages/nx/src/generators/quality/eslintConfig.ts +++ b/packages/nx/src/generators/quality/eslintConfig.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import { Tree } from '@nx/devkit'; +import { type Tree } from '@nx/devkit'; import { getNxProjectRoot } from '../../utils/nx'; import { outputPrettyFile } from '../../utils/prettier'; diff --git a/packages/nx/src/generators/quality/generator.ts b/packages/nx/src/generators/quality/generator.ts index 65251bb2..e4a6feb7 100644 --- a/packages/nx/src/generators/quality/generator.ts +++ b/packages/nx/src/generators/quality/generator.ts @@ -1,18 +1,18 @@ import * as path from 'path'; import { + addDependenciesToPackageJson, formatFiles, generateFiles, - addDependenciesToPackageJson, - Tree, + type Tree, updateJson, } from '@nx/devkit'; -import { PackageJson } from 'type-fest'; +import { type PackageJson } from 'type-fest'; import { getLatestVersions } from '../../utils/dependencies'; import generateIcons from '../ts-carbon-icons/generator'; import generateFileTypes from '../ts-file-types/generator'; -import { FileTypesGeneratorSchema } from '../ts-file-types/schema'; +import { type FileTypesGeneratorSchema } from '../ts-file-types/schema'; import generateConfig from '../ts-node-config/generator'; import { generateEslintConfig } from './eslintConfig'; diff --git a/packages/nx/src/generators/quality/projectConfig.ts b/packages/nx/src/generators/quality/projectConfig.ts index 897c04d7..809a3a5b 100644 --- a/packages/nx/src/generators/quality/projectConfig.ts +++ b/packages/nx/src/generators/quality/projectConfig.ts @@ -1,9 +1,9 @@ import * as path from 'path'; import { - Tree, addProjectConfiguration, readProjectConfiguration, + type Tree, updateProjectConfiguration, } from '@nx/devkit'; import merge from 'lodash/merge'; diff --git a/packages/nx/src/generators/ts-carbon-icons/generator.ts b/packages/nx/src/generators/ts-carbon-icons/generator.ts index 70d3481a..ed566a00 100644 --- a/packages/nx/src/generators/ts-carbon-icons/generator.ts +++ b/packages/nx/src/generators/ts-carbon-icons/generator.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import { Tree } from '@nx/devkit'; +import { type Tree } from '@nx/devkit'; import { getNxProjectRoot } from '../../utils/nx'; import { detectInstalledVersion } from '../../utils/packageJson'; diff --git a/packages/nx/src/generators/ts-file-types/generator.ts b/packages/nx/src/generators/ts-file-types/generator.ts index 5b829782..9e174138 100644 --- a/packages/nx/src/generators/ts-file-types/generator.ts +++ b/packages/nx/src/generators/ts-file-types/generator.ts @@ -1,10 +1,10 @@ import * as path from 'path'; -import { formatFiles, generateFiles, Tree } from '@nx/devkit'; +import { formatFiles, generateFiles, type Tree } from '@nx/devkit'; import { getNxProjectRoot } from '../../utils/nx'; -import { FileTypesGeneratorSchema } from './schema'; +import { type FileTypesGeneratorSchema } from './schema'; export async function tsFileTypesGenerator( tree: Tree, diff --git a/packages/nx/src/generators/ts-node-config/generator.ts b/packages/nx/src/generators/ts-node-config/generator.ts index cb054f2d..3edfbb97 100644 --- a/packages/nx/src/generators/ts-node-config/generator.ts +++ b/packages/nx/src/generators/ts-node-config/generator.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import { Tree } from '@nx/devkit'; +import { type Tree } from '@nx/devkit'; import * as fs from 'fs-extra'; import uniq from 'lodash/uniq'; diff --git a/packages/nx/src/generators/vite-lib/generator.ts b/packages/nx/src/generators/vite-lib/generator.ts index 89ad690e..9cabda28 100644 --- a/packages/nx/src/generators/vite-lib/generator.ts +++ b/packages/nx/src/generators/vite-lib/generator.ts @@ -1,4 +1,4 @@ -import { Tree } from '@nx/devkit'; +import { type Tree } from '@nx/devkit'; import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils'; import { libraryGeneratorInternal } from '@nx/js/src/generators/library/library'; diff --git a/packages/nx/src/utils/nx.ts b/packages/nx/src/utils/nx.ts index c34747ac..e1fa31d5 100644 --- a/packages/nx/src/utils/nx.ts +++ b/packages/nx/src/utils/nx.ts @@ -1,6 +1,6 @@ import path from 'path'; -import { Tree, getProjects } from '@nx/devkit'; +import { getProjects, type Tree } from '@nx/devkit'; export function getNxProjectRoot(tree: Tree, projectName: string) { const project = getProjects(tree).get(projectName); diff --git a/packages/nx/src/utils/packageJson.ts b/packages/nx/src/utils/packageJson.ts index 6f631816..736408a6 100644 --- a/packages/nx/src/utils/packageJson.ts +++ b/packages/nx/src/utils/packageJson.ts @@ -2,8 +2,8 @@ import * as path from 'path'; import fs from 'fs-extra'; import { - format as prettyFormatPackage, check as checkPackageFormat, + format as prettyFormatPackage, } from 'prettier-package-json'; import * as semver from 'semver'; import type { PackageJson } from 'type-fest'; diff --git a/packages/nx/src/utils/tempFiles.ts b/packages/nx/src/utils/tempFiles.ts index fd8c4b82..0da7ba17 100644 --- a/packages/nx/src/utils/tempFiles.ts +++ b/packages/nx/src/utils/tempFiles.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import { Tree, generateFiles } from '@nx/devkit'; +import { generateFiles, type Tree } from '@nx/devkit'; import fs from 'fs-extra'; type GenerateFilesFunction = (