Giter Club home page Giter Club logo

eslint-plugin-import-helpers's Introduction

eslint-plugin-import-helpers

Originally forked/inspired by eslint-plugin-import and this fork

npm version

This package was created to supplement the rules provided by eslint-plugin-import. There are a lot of great rules in there, but we found it missing a few key use cases.

Rules

Enforce a configurable convention in module import order. See the order-imports page for configuration details.

// Given ESLint Config
rules: {
  'import-helpers/order-imports': [
      'warn',
      {
          newlinesBetween: 'always', // new line between groups
          groups: [
              'module',
              '/^@shared/',
              ['parent', 'sibling', 'index'],
          ],
          alphabetize: { order: 'asc', ignoreCase: true },
      },
  ],
}

// will fix
import SiblingComponent from './SiblingComponent';
import lodash from 'lodash';
import SharedComponent from '@shared/components/SharedComponent';
import React from 'react';

// into
import lodash from 'lodash';
import React from 'react';

import SharedComponent from '@shared/components/SharedComponent';

import SiblingComponent from './SiblingComponent';

Installation

npm install eslint-plugin-import-helpers -g

or if you manage ESLint as a dev dependency:

# inside your project's working tree
npm install eslint-plugin-import-helpers --save-dev

To add a rule, update your .eslintrc.(yml|json|js):

{
    // .eslintrc.js
    plugins: ['eslint-plugin-import-helpers'],
    rules: {
        'import-helpers/order-imports': [
            'warn',
            { // example configuration
                newlinesBetween: 'always',
                groups: [
                    'module',
                    '/^@shared/',
                    ['parent', 'sibling', 'index'],
                ],
                alphabetize: { order: 'asc', ignoreCase: true },
            },
        ],
    }
}

TypeScript

To use this plugin with TypeScript, you must use the TypeScript parser for ESLint. See @typescript-eslint/parser for more details.

Working with This Repo

Dependencies

Name Version
node.js 16.x

Running Tests

First, npm install Then, npm test

eslint-plugin-import-helpers's People

Contributors

ai avatar bmish avatar dantman avatar doochik avatar willhoney7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

eslint-plugin-import-helpers's Issues

Question: Why remove `builtin` in v1?

Hi,

First of all, thanks for this awesome ESLint plugin. It is really helpful to organize my project imports! :)


My question is in about the new v1 version: why did you remove the builtin? I personally consider that option quite useful.

In regard the internal and external options, I maybe understand the reason that made you remove them. For me it seems quite tricky to differentiate an internal module that uses absolute importing and a normal external module. Was that the reason?

It doesn't respect the order under group

Lets say I have this configuration

'rules': {
      'import-helpers/order-imports': ['error',
        {
          newlinesBetween: 'always',
          groups: ['module', ['/aaa/', '/bbb/', '/ccc/']],
        },
      ],
    },
import {...} from '@external-module';

import {...} from '../ccc/';  // <= It doesn't complain about this line. It suppose to be placed after '/bbb/'.
import {...} from '../aaa/';
import {...} from '../bbb/';

import {...} from '../../somewhere/local';

Different groups for node_modules and internal modules

I wondered if there was a way to separate imports from node_modules from other internal imports
Is common (and useful) for devs map internal src files in jsconfig.json or tsconfig.json, like baseUrl and paths

.
+-- node_modules
|   +-- express
+-- src
|   +-- controllers
|   |   +-- MainController.js
|   +-- app.js
|   +-- index.js
+-- .eslintrc.json
+-- jsconfig.json
// jsconfig.json

{
	"compilerOptions": {
		"baseUrl": "./src",
		"paths": { "*": ["*"] }
	}
}
// .eslintrc.json

{
	"plugins": ["eslint-plugin-import-helpers"],
	"rules": {
		"import-helpers/order-imports": [
			"error",
			{
				"newlinesBetween": "always",
				"groups": [
					"node-module", // old "module", but dedicated for project dependencies (package.json)
					"module", // new using for "module", dedicated for nom-project dependencies
					["parent", "sibling", "index"]
				],
				"alphabetize": { "order": "asc", "ignoreCase": true }
			}
		]
	}
}
// index.js

import express from 'express';

import MainController from 'controllers/MainController'

import app from './app'

This a simple example... but please consider a deep folder structure that benefit a relative import method

[QUESTION] - Why make this order 👇 ?

Sorry for the new issue. When have a "^react" import a want that stays in the top but when have styled-components default import I want that stays on the top because In my style files I want the styled-components default import stays before of react-icons. But when I import the theme provider from styled-components ( named export ) I want him to stay after react
I try this:

{
 rules: {
    "import-helpers/order-imports": [
      "error",
      {
        "newlinesBetween": "always",
        "groups": [
          [
            "/^react(?!-icons\/*)/", // also I tried"/^react(?!-icons)"
            "/styled-components/",
            "/react-icons/"
          ],
          "module",
          [
            "parent",
            "sibling",
            "index"
          ]
        ],
        "alphabetize": {
          "order": "asc",
          "ignoreCase": true
        }
      }
    ],
 }
}

but not work

Different newline behaviour in 1.0

ESLint config:

    'import-helpers/order-imports': ['error', {
      groups: [
        ['absolute', 'module'],
        ['parent', 'sibling', 'index']
      ],
      newlinesBetween: 'always'
    }],

Expected code after --fix

let { addPrometheus, addScaling } = require('@evilmartians/logux-server-pro')
let { Server } = require('@logux/server')
let path = require('path')
let fs = require('fs')

Actual code after --fix (also ESLint show error on previous code)

let { addPrometheus, addScaling } = require('@evilmartians/logux-server-pro')

let { Server } = require('@logux/server')

let path = require('path')
let fs = require('fs')

How I can ask the plugin to not force me to insert a newline in this example?

Relative import mistaken as modules

If you use relative modules with baseUrl config in tsconfig.json, they're now treated as modules, just like import React from 'react'. (It's either that or import asd from ../../../../components) Don't know if there's a way to fix that but I'll just add '/^components/'

does it support "^7.12.1" ?

Hello guys, i followed the documentation but it did work on my react native project, is this lib supported on "^7.12.1"?

How does this compare to eslint-plugin-import-order-alphabetical?

Thanks for creating this plugin! This addresses one of my most-wanted enhancements to eslint-plugin-import.

Recently, I started using eslint-plugin-import-order-alphabetical to address the issue.

I see that you provide a couple of options for what the sorting order should be within the groups, but other than those enhancements, I'm wondering how similar these two plugins are.

If they're close, is there a way to perhaps combine efforts to make one really great plugin (or perhaps have something awesome to push back upstream to eslint-plugin-import)?

It's doens't works with Prettier

When we have prettier on the project, import helpers doens't works, i tried many times to make this work but have no success.

Anyone could help?

{
	"env": {
		"browser": true,
		"es6": true
	},
	"parser": "@typescript-eslint/parser",
	"plugins": [
		"eslint-plugin-import-helpers",
		"react-hooks",
		"react/recommended",
		"@typescript-eslint/recommended",
		"jsx-a11y/recommended",
		"prettier/recommended"
	],
	"extends": ["prettier/@typescript-eslint"],
	"parserOptions": {
		"ecmaVersion": 2018,
		"sourceType": "module",
		"ecmaFeatures": {
			"jsx": true
		}
	},
	"settings": {
		"react": {
			"version": "detect"
		}
	},
	"rules": {
		"import-helpers/order-imports": [
			"error",
			{
				"newlinesBetween": "always", // new line between groups
				"groups": ["/ˆreact/", "module", ["parent", "sibling", "index"]],
				"alphabetize": { "order": "asc", "ignoreCase": true }
			}
		],
		"@typescript-eslint/explicit-function-return-type": 0,
		"react/display-name": 0,
		"jsx-a11y/anchor-is-valid": 0,
		"react-hooks/rules-of-hooks": "error",
		"react-hooks/exhaustive-deps": "warn"
	}
}

Sort import with styles does not work

I trying to sort imports with '.css' extension and add write rule in config like this:

    "import-helpers/order-imports": [
      "warn",
      {
        "newlinesBetween": "always",
        "groups": [
          "module",
          "/^@shared/",
          "/^@server/",
          "/^@client/",
          "/^@/",
          ["parent", "sibling", "index"],
          "/\\.css$/"
        ],
        "alphabetize": {
          "order": "asc",
          "ignoreCase": true
        }
      }
    ],

but it does not work

How to separate modules that are only `import`

How the imports look like:

import Client from '~/structures/Client';
import 'dotenv/config';

How I would like it to be:

import Client from '~/structures/Client';

import 'dotenv/config';

How could I do this?

Support for 'type' imports

now that both flow and typescript support them

import lodash from 'lodash';
import React from 'react';

import SharedComponent from '@shared/components/SharedComponent';

import SiblingComponent from './SiblingComponent';

import type { SiblingComponentType } from './SiblingComponent';
{
    // .eslintrc.js
    plugins: ['eslint-plugin-import-helpers'],
    rules: {
        'import-helpers/order-imports': [
            'warn',
            { // example configuration
                newlinesBetween: 'always',
                groups: [
                    'module',
                    '/^@shared/',
                    ['parent', 'sibling', 'index'],
                    'types', // <-------------------------------
                ],
                alphabetize: { order: 'asc', ignoreCase: true },
            },
        ],
    }
}

Type sorting does not work correctly

The section with type imports looks wrong
My config is:

'import-helpers/order-imports': [
  'error',
  {
    newlinesBetween: 'always', // new line between groups
    groups: [
      ['/^react$/', '/^next/', 'module'],
      ['/^@framework/', '/^@lib/'],
      '/^@contexts/',
      '/^@components/',
      ['parent', 'sibling', 'index'],
      'type',
    ],
    alphabetize: { order: 'asc', ignoreCase: true },
  },
],

The sorting result looks like this:

import { AnimatePresence, motion } from 'framer-motion'
import { useTranslation } from 'next-i18next'
import Link from 'next/link'
import { useToggle } from 'react-use'

import {
  useTrackIdentifyCustomer,
  useTrackLogin,
  useTrackRegistration,
} from '@lib/tracking/helper'

import { useAuthContext } from '@contexts/AuthContext/AuthContext'

import { Button, Logo } from '@components/ui'

import { AuthFormInput } from './AuthFormInput'
import { getFormData } from './get-form-data'
import { hasErrors } from './has-errors'

import type { AuthFormData, AuthFormErrors } from './useFormValidation'
import { useFormValidation } from './useFormValidation'
import { useCallback, useEffect, useState } from 'react'
import type { FC, FormEvent, HTMLAttributes } from 'react'

Path to v1

Todo

  • Rename newlines-between to newLinesBetween #1

  • Remove concept of builtin, external, and internal modules. Just call them modules. Anything that isn't imported relatively. Because of the regular expression groups, you can still implement the same functionality (builtins could be /fs|path/ and so on). This makes it so this plugin doesn't have to do any resolving... It will only sort the imports text. This should improve performance. (open for discussion/comments)

  • Remove import/core-modules and import/external-module-folders as eslint settings. They are artifacts from the eslint-plugin-import fork and unnecessary if we do the previous todo.

  • Remove dependence on lodash.cond. Again, an artifact from the fork I'd like to remove. It makes the code harder to understand.

  • Fix tests to follow new API

  • Convert to TypeScript (in-progress and improving type definitions). As ESLint gets better documentation and typings for developing rules with TypeScript, I'll improve the types we have.

  • Add documentation on migrating to v1

Progress is being made in: branch/v1-dev

Control order within groups

I'm wondering if it would be possible to control the order within the defined groups, or in other words, to create subgroups.

a very simplified example:

groups: [
  [['a'], ['b', 'c']],
  'd',
]

The goal in this example would be to have the a imports first, then imports from b and c, then a newline and finally imports from d.

The other idea I had to accomplish this was to make the newlines an explicit part of the groups array:

groups: [
  'a', 
  ['b', 'c']
  '\n',
  'd',
]

How can I set order for import './index.styl'

I know that the documentation has a clause about such imports, but can there still be some way?
I just want the style imports to always be at the bottom of everyone else

ex. imports:

import React, { useState } from 'react'
import { Image } from 'react-native'
import { observer, useDidUpdate } from 'startupjs'
import PropTypes from 'prop-types'
import randomcolor from 'randomcolor'
import Div from './../Div'
import Span from '../typography/Span'
import './index.styl'

my config:

    "import-helpers/order-imports": [
            "warn",
              { 
                "newlinesBetween": "ignore",
                "groups": [
                    "/^react$/",
                    "/react-native/",
                    "/^react.*/",
                    "/^startupjs/", 
                    "/^@?startupjs.*/",
                    "/^@?dmapper.*/",
                    "module",
                    "/components/",
                    ["/helpers/", "/hooks/"],
                    ["sibling", "parent"],
                    "/.\/index.styl/"
                ]
              }
        ]

It doesnt work with (import '../styles/mystyle.scss');

Hello,
I'm trying to order my styles imports like:

import '../styles/components/CreditCard.scss';
import 'react-credit-cards/es/styles-compiled.css';

I tried to use this group:
"/\bstyles\b/", and "/css$/"
but its not working.

I think that the imports must have the "from", i'm correct?
There is a plan to add support to css / scss?

Allow Functions Before Imports

Problem:
When it is necessary to use a function before imports, such as jest, having a way to allow it to be at the top of the file without disabling the eslint function.

Eslint Error without bypass
image

image

Does not work with typescript

Thanks for this plugin! I have been waiting it for several years. wemake-services/wemake-vue-template#495

Unfortunately, it does not work with eslint and typescript.
I am using this setup: https://github.com/wemake-services/wemake-vue-template/blob/feature-typescript/template/.eslintrc.js

Whenever I shuffle imports in any file (including .ts and .vue) - nothin happens.
It just passes.

» npm run lint:js

> [email protected] lint:js /Users/sobolev/Documents/github/wemake-vue-template/template
> eslint --ext .js,.jsx,.ts,.tsx,.vue,.json --ignore-path .gitignore .

Things that I have done (that are not included into the template):

  1. `npm i -D eslint-plugin-import-helpers
+ [email protected]
added 3 packages from 5 contributors, removed 180 packages and audited 1503420 packages in 44.013s
found 0 vulnerabilities
  1. .eslintrc.js modifications:
  'plugins': [
    ...
    'import-helpers',
  ],
  'rules': {
    // import order
    'import-helpers/order-imports': 2,
    ...
  1. Modify any of these files: https://github.com/wemake-services/wemake-vue-template/blob/feature-typescript/template/client/logics/api/comments.ts#L1-L2 or https://github.com/wemake-services/wemake-vue-template/blob/feature-typescript/template/client/components/Comment.vue#L32-L38

Am I doing something wrong?

Line count dependent `newlinesBetween`

Thanks for this great plugin! 🍻

I am using newlinesBetween: "always" in these two configurations:

This type of grouping, looks like this:

import { join, dirname } from 'path';

import BroccoliDebug from 'broccoli-debug';
import BroccoliMergeTrees from 'broccoli-merge-trees';
import BroccoliPlugin, { BroccoliNode } from 'broccoli-plugin';
import { WatchedDir } from 'broccoli-source';
import EmberApp from 'ember-cli/lib/broccoli/ember-app';
import Addon from 'ember-cli/lib/models/addon';
import Project from 'ember-cli/lib/models/project';
import fromPairs from 'lodash.frompairs';

import commands from './commands';
import {
  computeOptions,
  MakeupOptions,
  FinalMakeupOptions
} from './lib/options';
import { addon } from './lib/utils/ember-cli-entities';
import { CSSConfigCreator } from './plugins/broccoli/config-creator';
import EmberCSSModulesPlugin from './plugins/ember-css-modules';
import { Usage } from './plugins/postcss';
import { register } from './plugins/preprocessor-registry';
import { ThemeProviderRegistry, ThemeProvider } from './themes';

It works great for files, that have a lot of imports, like above, but it's total overkill for files with only a few imports of different groups, e.g.:

import Application from '@ember/application';

import loadInitializers from 'ember-load-initializers';

import config from './config/environment';

This would look cleaner IMO:

import Application from '@ember/application';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';

What do you think about an additional config that allows to specify the minimum number of imports per group for newlines to be inserted.

Cannot get alphabetize to work

Configuration for rule "import/order" is invalid:
Value {"groups":[["builtin"],["parent","sibling","index"]],"newlines-between":"always","alphabetize":{"order":"asc","ignoreCase":true}} should NOT have additional properties.

I'm using the latest version and the plugin code seems to be ok:

	meta: {
		type: 'suggestion',
		docs: {
			url: '' // docsUrl('order'), TODO
		},

		fixable: 'code',
		schema: [{
			type: 'object',
			properties: {
				groups: {
					type: 'array'
				},
				'newlines-between': {
					enum: ['ignore', 'always', 'always-and-inside-groups', 'never']
				},
				alphabetize: {
					type: 'object',
					properties: {
						order: {
							enum: ['ignore', 'asc', 'desc'],
							default: 'ignore'
						},
						ignoreCase: {
							type: 'boolean',
							default: false
						}
					}
				}
			},
			additionalProperties: false
		}]
	},

But when I include alphabetize in my config I always get that error.

Importing from parent behaving unexpectedly

I have import-helpers/sort-order configured like so:

    {
        groups: [
          'absolute',
          'module',
          '/^\\$src/',
          'parent',
          'sibling',
          'index'
        ],
        newlinesBetween: 'always',
        alphabetize: { order: 'asc' }
      }

I am seeing that either of these are considered "allowable" by the plugin

import { useCapabilities } from '..';

import { Capabilities, PREFIX } from '../useCapabilities';
import { Capabilities, PREFIX } from '../useCapabilities';

import { useCapabilities } from '..';

But this is not, because there must be a newline between groups

import { Capabilities, PREFIX } from '../useCapabilities';
import { useCapabilities } from '..';

This doesn't seem right to me, since it seems like they are in separate groups, but the groups can be ordered either way. Any idea what might be going on?

Thank you!

I just wanted to thank you, I'm in the process of finally setting-up ESLint properly and your plugin is exactly what I wanted, I can't believe I have been managing the order of my imports manually so far!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.