From 02f51fb38cc3c3140b2d6f6e957191966db41fd4 Mon Sep 17 00:00:00 2001 From: Azat S Date: Fri, 9 Jun 2023 20:40:58 +0300 Subject: [PATCH] feat: add side-effect group to sort the imports --- docs/rules/sort-imports.md | 5 ++ rules/sort-imports.ts | 4 ++ test/sort-imports.test.ts | 108 +++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/docs/rules/sort-imports.md b/docs/rules/sort-imports.md index c219ae8d6..ab9ba7036 100644 --- a/docs/rules/sort-imports.md +++ b/docs/rules/sort-imports.md @@ -97,6 +97,7 @@ type Group = | 'internal' | 'parent' | 'sibling' + | 'side-effect' | 'index' | 'object' | 'style' @@ -155,6 +156,8 @@ import Button from '~/components/Button' import formatNumber from '../utils/format-number' // siblings - Modules from the same directory import config from './config' +// side-effect - Side effect imports +import './set-production-env.js' // index - Main file from the current directory import main from '.' // object - TypeScript object-imports @@ -233,6 +236,7 @@ If your project is written in TypeScript, you can read `tsconfig.json` and use ` "internal", ["parent-type", "sibling-type", "index-type"], ["parent", "sibling", "index"], + "side-effect", "style", "object", "unknown" @@ -273,6 +277,7 @@ export default [ 'internal', ['parent-type', 'sibling-type', 'index-type'], ['parent', 'sibling', 'index'], + 'side-effect' 'style', 'object', 'unknown', diff --git a/rules/sort-imports.ts b/rules/sort-imports.ts index 2fdb3376a..be1e30d63 100644 --- a/rules/sort-imports.ts +++ b/rules/sort-imports.ts @@ -231,6 +231,10 @@ export default createEslintRule({ defineGroup('style') } + if (node.specifiers.length === 0) { + defineGroup('side-effect') + } + if (isIndex(node.source.value)) { defineGroup('index') } diff --git a/test/sort-imports.test.ts b/test/sort-imports.test.ts index c0d96886c..61b1fc6e4 100644 --- a/test/sort-imports.test.ts +++ b/test/sort-imports.test.ts @@ -769,6 +769,42 @@ describe(RULE_NAME, () => { invalid: [], }) }) + + it(`${RULE_NAME}(${type}): separates side effect imports from the rest`, () => { + ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: dedent` + import { ShōyaIshida } from '../edu/kuise-hairdressing-school' + import { ShoukoNishimiya } from './salon-stray-cat' + + import '../edu/prepare-students.js' + import './load-memories' + `, + options: [ + { + type: SortType.alphabetical, + order: SortOrder.asc, + 'newlines-between': NewlinesBetweenValue.always, + 'internal-pattern': ['~/**'], + groups: [ + 'type', + ['builtin', 'external'], + 'internal-type', + 'internal', + ['parent-type', 'sibling-type', 'index-type'], + ['parent', 'sibling', 'index'], + 'side-effect', + 'object', + 'unknown', + ], + }, + ], + }, + ], + invalid: [], + }) + }) }) describe(`${RULE_NAME}: sorting by natural order`, () => { @@ -1530,6 +1566,42 @@ describe(RULE_NAME, () => { invalid: [], }) }) + + it(`${RULE_NAME}(${type}): separates side effect imports from the rest`, () => { + ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: dedent` + import { ShōyaIshida } from '../edu/kuise-hairdressing-school' + import { ShoukoNishimiya } from './salon-stray-cat' + + import '../edu/prepare-students.js' + import './load-memories' + `, + options: [ + { + type: SortType.natural, + order: SortOrder.asc, + 'newlines-between': NewlinesBetweenValue.always, + 'internal-pattern': ['~/**'], + groups: [ + 'type', + ['builtin', 'external'], + 'internal-type', + 'internal', + ['parent-type', 'sibling-type', 'index-type'], + ['parent', 'sibling', 'index'], + 'side-effect', + 'object', + 'unknown', + ], + }, + ], + }, + ], + invalid: [], + }) + }) }) describe(`${RULE_NAME}: sorting by line length`, () => { @@ -2333,6 +2405,42 @@ describe(RULE_NAME, () => { invalid: [], }) }) + + it(`${RULE_NAME}(${type}): separates side effect imports from the rest`, () => { + ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: dedent` + import { ShōyaIshida } from '../edu/kuise-hairdressing-school' + import { ShoukoNishimiya } from './salon-stray-cat' + + import '../edu/prepare-students.js' + import './load-memories' + `, + options: [ + { + type: SortType['line-length'], + order: SortOrder.desc, + 'newlines-between': NewlinesBetweenValue.always, + 'internal-pattern': ['~/**'], + groups: [ + 'type', + ['builtin', 'external'], + 'internal-type', + 'internal', + ['parent-type', 'sibling-type', 'index-type'], + ['parent', 'sibling', 'index'], + 'side-effect', + 'object', + 'unknown', + ], + }, + ], + }, + ], + invalid: [], + }) + }) }) describe(`${RULE_NAME}: misc`, () => {