eslint-plugin-import icon indicating copy to clipboard operation
eslint-plugin-import copied to clipboard

Newlines between custom path groups

Open iamsharzil opened this issue 2 years ago • 2 comments

I want to define custom path groups such that there should be a new line between them.

eg. I've React, NextJs, MUI, and local folders (components, features, etc). I want to specify the rules such that React package will be on top, and NextJs and its related packages will be grouped into one, similarly, MUI and emotion packages, Redux, Redux persist, and Redux-toolkit.

What I want:

import React from "react";

import { NextPage } from "next";
import { AppProps } from "next/app";
import Head from "next/head";

import CssBaseline from "@mui/material/CssBaseline";
import { ThemeProvider } from "@mui/material/styles";
import { CacheProvider, EmotionCache } from "@emotion/react";

import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";

import { store, persistor } from "@store/index";

import createEmotionCache from "@shared/create-emotion-cache";
import { globalStyles } from "@shared/styles";
import theme from "@shared/theme";

Current behavior with the below rules:

import React from "react";

import { NextPage } from "next";

import { AppProps } from "next/app";
import Head from "next/head";

import CssBaseline from "@mui/material/CssBaseline";
import { ThemeProvider } from "@mui/material/styles";

import { CacheProvider, EmotionCache } from "@emotion/react";

import { Provider } from "react-redux";

import { PersistGate } from "redux-persist/integration/react";

import { store, persistor } from "@store/index";

import createEmotionCache from "@shared/create-emotion-cache";
import { globalStyles } from "@shared/styles";
import theme from "@shared/theme";

Eslintrc.json

"import/order": [
      "error",
      {
        "pathGroupsExcludedImportTypes": ["react"],
        "newlines-between": "always",
        "alphabetize": {
          "order": "asc",
          "caseInsensitive": true
        },
        "groups": ["builtin", "external", "internal", "parent", "sibling", "index", "object"],
        "pathGroups": [
          {
            "pattern": "react",
            "group": "external",
            "position": "before"
          },

          {
            "pattern": "next",
            "group": "external",
            "position": "before"
          },

          {
            "pattern": "**/next/**",
            "group": "external",
            "position": "before"
          },

          {
            "pattern": "**/@mui/**",
            "group": "external",
            "position": "before"
          },

          {
            "pattern": "**/@emotion/**",
            "group": "external",
            "position": "before"
          },

          {
            "pattern": "react-redux",
            "group": "external",
            "position": "before"
          },

          {
            "pattern": "redux-persist/**",
            "group": "external",
            "position": "before"
          },

          {
            "pattern": "**/@store/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@layout/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@screens/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@features/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@components/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@services/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@hooks/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@shared/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@interfaces/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@utils/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@config/**",
            "group": "internal",
            "position": "before"
          },

          {
            "pattern": "**/@events/**",
            "group": "internal",
            "position": "before"
          }
        ]
      }
    ],

iamsharzil avatar Jun 05 '22 06:06 iamsharzil

Seconding this. Saying it a different way, assuming that "newlines-between" = "always", we need to be able to specify whether a custom pattern creates a newline or not. We may want it for some patterns but not all!

ThomasAitken avatar Jul 06 '22 01:07 ThomasAitken

So pattern uses the minimatch format, if we can match everything we want in a group with one pattern, there won't be any newlines.

foo|bar or (foo|bar) don't match foo and bar, but *(foo|bar) does. Is that something you could use?

I solved this issue by using { pattern: "*(foo|bar|baz**|qux)/**", patternOptions: { partial: true } }. Note the combination of the trailing /** and partial: true for allowing matches both with and without slashes.

toerndev avatar Jul 11 '22 15:07 toerndev