lydell / eslint-plugin-simple-import-sort Goto Github PK
View Code? Open in Web Editor NEWEasy autofixable import sorting.
License: MIT License
Easy autofixable import sorting.
License: MIT License
Duplicate imports are to be combined to the one import.
Discovered in release 2.0.0
Steps to reproduce:
Try to fix the following
import './styles.scss'
import './styles.scss'
Actual result:
import './styles.scss'
import './styles.scss'
Expected result:
import './styles.scss'
I'm not sure if I'm doing it wrong, but sorting happens even inside a eslint-disable / eslint-enable block.
e.g.
import React from 'react';
import { ToastContainer } from 'react-toastify';
import { useAccount, useUser } from 'src/state';
import mapboxgl from 'mapbox-gl';
/* eslint-disable */
import '@feathr/components/style/theme/index.css';
import '@feathr/components/style/global/index.css';
import './ReactApp.css';
// Load after theme/index.css.
import { ErrorBoundary } from '@feathr/components';
/* eslint-enable */
import Routes from './Routes';
I would expect anything outside the disable/enable block to get sorted, but inside to be left alone.
The readme says:
Since “.” sorts before “/”, relative imports of files higher up in the directory structure come before closer ones –
"../../utils"
comes before"../utils"
. Perhaps surprisingly though,".."
would come before"../../utils"
(since shorter substrings sort before longer strings). For that reason there’s one addition to the alphabetical rule:"."
and".."
are treated as"./"
and"../"
.
That is pretty broken, though:
import {} from "../";
import {} from "../../";
import {} from "../../a";
import {} from "../a";
import {} from "./";
import {} from "./a";
Expected:
import {} from "../../";
import {} from "../../a";
import {} from "../";
import {} from "../a";
import {} from "./";
import {} from "./a";
I have some ideas around this that I’d like to play with this fall.
I have to say, I love how this project works! It nails the developer experience, and just works without config, all the way down to the error messages.
Unfortunately I'm coming from a mixed project, https://github.com/badges/shields (the front end uses ESM and the back end uses require
) so I'm using import/order
.
It's really clear from the readme that require
isn't supported, though wanted to say I would definitely use it if it were added!
Thanks so much for a great project!
I'd like to be able to fix position of a side-effect import. Here's the use-case:
// main.ts, entrypoint of a Vue app
import Vue from 'vue'
import VueBlahBlah from 'vue-blah-blah'
import VueBootstrap from 'vue-bootstrap' // imaginary library with CSS
// Import local assets, including local CSS files.
// This should really go **after** global imports, because those
// may have imported some initial CSS, and local assets should
// follow to be able to override the rules.
import './assets'
import '@/store'
import '@/other/local/module'
What if eslint-plugin-simple-import-sort supported some kind of magic comment, similar to // eslint-disable-next-line
? Like: // simple-import-sort: keep-group
TLDR, order should be:
import './foo/bar/baz';
import './foo/bar';
import './foo';
import React from 'react';
import { App, QueryParams } from './App';
import { flushPromises } from './utils/flushPromises';
import { mockRouteComponentProps } from './utils/mockRouteComponentProps';
should be:
import React from 'react';
import { flushPromises } from './utils/flushPromises';
import { mockRouteComponentProps } from './utils/mockRouteComponentProps';
import { App, QueryParams } from './App';
import { config } from '../config';
import { UUID } from '../utils/UUID';
should be:
import { UUID } from '../utils/UUID';
import { config } from '../config';
import 'core-js';
import 'regenerator-runtime/runtime';
import 'whatwg-fetch';
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Router } from './Router';
import { Layout } from './layout/Layout';
import './index.scss';
becomes:
import 'core-js';
import 'regenerator-runtime/runtime';
import 'whatwg-fetch';
import './index.scss';
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Router } from './Router';
import { Layout } from './layout/Layout';
=> './index.scss'
should be last
Hi!
Prettier formats my code just fine when adding the plugin as-is, but it's ignoring the custom groups rule while formatting.
Simple Import Sort rules:
rules: {
"simple-import-sort/imports": [
"error",
{
groups: [
// Node.js builtins. You could also generate this regex if you use a `.js` config.
// For example: `^(${require("module").builtinModules.join("|")})(/|$)`
[
"^(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.
["^(@|@company|@ui|@src|components|utils|config|vendored-lib|src)(/.*|$)"],
// 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",
"sort-imports": "off",
"import/order": "off"
}
Outcome (after saving the file):
Formatting works just fine if I run eslint --fix
, but for some reason, Prettier is not taking this into account and formatting as if I had never written the groups option, even though ESLint clearly sees this as an error.
import { format, parseISO } from 'date-fns';
import React from 'react';
import { createFragmentContainer, graphql } from 'react-relay';
import { FaqAuthor_author } from '~/__generated__/FaqAuthor_author.graphql';
import { FaqAuthor_faq } from '~/__generated__/FaqAuthor_faq.graphql';
import { AuthorInfo } from '~/components/AuthorInfo/AuthorInfo';
Is our import block when running 'simple-import-sort/sort': 'off',
, and source code.
However, as soon as we go 'simple-import-sort/sort': 'error',
This produces:
import { format, parseISO } from 'date-fns';
import React from 'react';
import { createFragmentContainer, graphql } from 'react-relay';
import { FaqAuthor_author } from '~/__generated__/FaqAuthor_author.graph
q
l
'
;
import { FaqAuthor_faq } from '~/__generated__/FaqAuthor_faq.g
ra
ph
ql
';
import { AuthorInfo } from '~/components/AuthorInfo/AuthorInfo';
My eslintrc file:
module.exports = {
extends: ['plugin:@autoguru/react'],
env: {
'shared-node-browser': true,
browser: true,
},
parserOptions: {
tsconfigRootDir: __dirname,
},
settings: {
'import/resolver': {
typescript: {
directory: __dirname,
},
},
},
};
and rule config @ https://github.com/autoguru-au/octane/blob/master/packages/eslint-plugin/configs/base/import.js#L7
It'd be great if we could set up a flag to enable/disable adding a comment above each defined group (if a custom definition is provided):
// ...
'groups': [
{
match: '^\\u0000',
comment: 'side effects',
},
{
match: '^@?\\w',
comment: 'package imports,
},
// ...
],
// ...
I can take care of this feature if you see it fit for your package. Thoughts?
Nowadays, absolute imports is a very popular thing, as well as monorepos with different features "stored" as a separate packages. However they are not packages.
Webpack aliases and yarn workspaces are breaking original idea behind the "groups" feature.
import React from 'react'; // 1. "external" package
import Button from 'components/Button'; // 2. "internal" package (or just an absolute URL)
import style from './style'; // 3. "relative" module
import "./messages"; // 4. side effect
Technically these are:
node_modules
node_modules
2
could be distinguished from 1
by calling require.resolve
and checking path to include node_modules
(obvious)2
could be distinguished from 1
by having some configuration rules, but I reckon it's not feature proof and quite fragile.I could work on PR if you'll accept the idea
Hey 👋,
The new exports
sort does not handle sorting exports that use the as
keyword.
export { something, something as default } from './something'
will be sorted as:
export { something as, defaultsomething } from './something'
which obviously is incorrect.
Thanks for nice plugin!
I tried to use this and had one question.
How to remove newline between import groups?
(Or is there no option to remove line breaks?)
import fetch from 'cross-fetch'
import { NextPage } from 'next'
import Link from 'next/link'
import React from 'react'
// I want to delete ↑ line...
import { Head } from '~/components/abstracts/head'
The config file used is shown below.
{
"root": true,
"env": {
"es6": true,
"node": true,
"browser": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": { "jsx": true },
"sourceType": "module"
},
"plugins": [
"react",
"import",
"unicorn",
"security",
"prettier",
"react-hooks",
"simple-import-sort",
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"plugin:react/recommended",
"plugin:unicorn/recommended",
"plugin:security/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:prettier/recommended",
"prettier/@typescript-eslint",
"prettier/unicorn",
"prettier/react"
],
"rules": {
"prefer-const": "error",
"react/prop-types": "off",
"simple-import-sort/sort": "error",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"import/newline-after-import": "error",
"unicorn/prevent-abbreviations": "off",
"unicorn/consistent-function-scoping": "off",
"@typescript-eslint/ban-ts-ignore": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/consistent-type-definitions": ["error", "type"]
},
"settings": {
"react": {
"version": "detect"
},
"import/resolver": {
"babel-module": {}
},
"import/parsers": {
"@typescript-eslint/parser": [".ts", ".tsx"]
}
}
}
Hi I have these imports:
import moment, { Moment } from 'moment'
import React, { Component } from 'react'
import { Text, View } from 'react-native'
import * as GQL from '@gql-schema'
import { Texts } from '@styles/common/Texts'
import { ToggleItem } from '@ui/Section'
import { amountWithCurrency } from '@util/amountFormatter'
import { GraphColumns } from './GraphColumns'
import { styles } from './styles'
Sort plugin reports them as wrong and it will correct them to the:
import { Texts } from '@styles/common/Texts'
import moment, { Moment } from 'moment'
import React, { Component } from 'react'
import { Text, View } from 'react-native'
import * as GQL from '@gql-schema'
import { ToggleItem } from '@ui/Section'
import { amountWithCurrency } from '@util/amountFormatter'
import { GraphColumns } from './GraphColumns'
import { styles } from './styles'
i would expect all imports starting with @
to be in same group. Could you provide explanation how this was sorted?
Thank you
import { something } from '../otherModule/something'
import { somethingElse } from './somethingElse'
Becomes:
import { something } from '../otherModule/something'
import { somethingElse } from './somethingElse'
Since upgrading to v6.0.0, when linting, I get the following error:
error Definition for rule 'simple-import-sort/sort' was not found simple-import-sort/sort
I have noticed a strange behaviour that occurs with Angular testing library.
Before autofix:
import { TestBed, async } from '@angular/core/testing';
After autofix:
import { ,asyncTestBed } from '@angular/core/testing';
Package versions:
eslint-plugin-simple-import-sort
-> 4.0.0
@typescript-eslint/eslint-plugin
-> 1.10.2
@typescript-eslint/parser
-> 1.10.2
async
is not a reserved keyword - see https://www.ecma-international.org/ecma-262/10.0/index.html#sec-keywords
It’s possible to import types and values in a single file. If so, these can be safely merged.
Input:
import type { ReactNode } from 'react';
import React from 'react';
export default function Foo(): ReactNode {
return <div>Hello</div>
}
Expected output:
import React, { ReactNode } from 'react';
export default function Foo(): ReactNode {
return <div>Hello</div>
}
The only case where this is questionable, is if the type is re-exported.
import type { ReactNode } from 'react';
import React from 'react';
export { ReactNode };
When the imports are merged, this becomes the following, where some tools can’t determine if ReactNode
is a type or value.
import React, { ReactNode } from 'react';
export { ReactNode };
I think this is ok though. When properly written, a type export is used for this instead.
import React, { ReactNode } from 'react';
export type { ReactNode };
TypeScript doesn’t verify this (yet), but I think this makes it ok for this ESLint plugin to fully ignore that situation.
First of all -- great plugin. I'm a huge fan of sorting my imports and I've managed to convince my team to include this plugin in our application.
That being said, I'm running into a weird issue where the spacing isn't right after sorting.
Before fix:
After fix:
See how there is no space between alias
and oneWay
or between computed
and get
?
Is this an issue perhaps with another eslint rule?
Thanks!
When using @typescript-eslint/[email protected]
as a parser for eslint the side-effects imports are no longer recognized as such in all cases and thus the order is sometimes off:
E.g. this is how my file is now sorted
import http from 'http';
import '@datacamp/multiplexer-tracer';
import getConfig from 'src/getConfig';
import server from 'src/server';
in a group, I have:
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
all of those are in my custom "framework" group.
but, when apply the auto-fix, @glimmer/component
moves to the bottom, because g comes after e.
Is there a way to keep it at the top, because it's a default import?
For example, previously, I had:
'sort-imports-es6-autofix/sort-imports-es6': [2, {
'ignoreCase': false,
'ignoreMemberSort': false,
'memberSyntaxSortOrder': ['single', 'all', 'multiple', 'none'],
}],
which looks like:
import single from 'a';
import * from 'b';
import { foo, bar } from 'c';
import from 'd';
i'd like to maintain that to reduce impact to the (very large) codebase (and people's workflows)
For example I want to have those imports into a new separated group:
import crypto from 'crypto';
import fs from 'fs';
import path from 'path';
import util from 'util';
Those packages are node built-in.
In a sample app structure
node_modules
src
util
App.js
where App.js
is:
import React from "react";
import lib from "util/lib";
// code
Would it be possible to separate the two groups? Thanks!
/home/asday/code/src/app/containers/Navigation.js
1:1 error Run autofix to sort these imports! simple-import-sort/sort
Is this complaining about the gap between the parent imports and the sibling imports? The fact I have react-navigation
after react-navigation-redux-helpers
? Who knows!
It's lovely that you can autofix it, but I don't want you to. I want to be told what I wrote that was wrong, so I can learn to write the right thing, first time, in future. That way, when I come to other code on the project that's compliant, I already know what I'm expecting to see, because that's how I've taught myself to write.
Failed to load plugin 'simple-import-sor' declared in '.eslintrc.js': Cannot find module 'eslint-plugin-simple-import-sor'
"extends": [ "eslint:recommended", "plugin:react/recommended", "plugin:import/errors", "plugin:import/warnings", "plugin:simple-import-sort" ],
I set to only simple-import-sort but no works
Description
Consider following import declarations:
import { PROPERTY } from './config'; // later refered as "import A"
import './style'; // later refered as "import B"
According to AST, the the import A has specifier, the import B has none. I would like to sort imports without specifier last.
Digging into the code, following function was discovered (so it looks like, my case is considered side-effect):
eslint-plugin-simple-import-sort/src/sort.js
Line 841 in 7b29c07
The behaviour described is proven by this comment:
eslint-plugin-simple-import-sort/src/sort.js
Line 782 in 7b29c07
Verdict: the side-effect comes first. I would like it come last.
I am also suspecting the regex I pass is wrong, if that's the case, please let me know. The configs can be seen in examples bellow.
Motivation
The feature is specifically important for stylesheet imports, if imported as CSS - the order matters. So, I would like my imports in module to come last, this means if I extend a component which also imports style, mine module style will have a priority when resolving.
What I tried
Plugin options provided:
{
"groups": [
[
"^\\u0000"
], // side effect imports
[
"^@?[a-z]"
], // anything that starts with @ and lowercase
[
"^[^.]"
], // anything but a dot
[
"^\\."
] // starting with dot
]
}
Gives me following output:
import './UrlResolver.style';
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { CATEGORY, PRODUCT, UNKNOWN } from './UrlResolver.config';
The config as follows:
{
"groups": [
[
"^@?[a-z]"
], // anything that starts with @ and lowercase
[
"^[^.]"
], // anything but a dot
[
"^\\."
], // starting with dot
[
"^\\u0000"
], // side effect imports
]
}
Gives me:
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import './UrlResolver.style';
import { CATEGORY, PRODUCT, UNKNOWN } from './UrlResolver.config';
Expected result:
An option to configuration is added, which allows to sort side-effects / importds without specifier last.
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { CATEGORY, PRODUCT, UNKNOWN } from './UrlResolver.config';
import './UrlResolver.style';
We have a module alias called web
for our local code (like @
in #4) and I'd like it to be sorted into it's own group like this:
import React from "react"
import { Foo } from "web/components/foo"
import { Bar } from "./bar"
import/order
supports this by doing a bunch of magic with Webpack parsing, but just having a list of first party packages as a config variable would be a lot easier.
Thanks
In a project created with vue-cli
, local components are sorted above global packages:
import Error from "@/components/error.vue"
import { Component, Vue } from "vue-property-decorator"
which is counter-intuitive, and may possibly suffer from missing side-effects coming from global imports.
The @
alias comes from here:
https://github.com/vuejs/vue-cli/blob/486a921e9fc782fe4a9b9dd1bdf82066b1522782/packages/%40vue/cli-service/lib/config/base.js#L49
I understand that the sort plugin treats this as a normal package import, and character code of @
(64) is smaller than of any letter—I agree that the current behaviour is correct as per documentation.
However, using @
is a wide spread use case (at least in Vue world) for referring to local modules, so this problem might have a solution provided by simple-import-sort
without needing to update all imports.
I think the simplest solution would be to allow to customize prefixes for "absolute imports" group. As I understand, currently an import is considered absolute if and only if it starts with /
. What if user could add more prefixes? Something like { absolutePrefixes: ['/', '@/'] }
.
For now I've changed @/absolute/import
to ~/absolute/import
(~
sorts after all alphanumeric characters so these imports come directly after all package imports). Granted, it even makes more sense, as ~
means home in Unix (and also ~
is a suggested default in e.g. babel-plugin-root-import).
However, it's breaking wide spread Vue conventions, so a solution in the sorter allowing to use the default alias @/
would be appreciated.
Also, logically even ~/package
is an absolute import and belong to 'absolute imports' group, not a global package with weird name which just coincidentally happens to be sorted alphabetically after all other packages. This will also be useful for putting line breaks between groups.
Hi, first time trying to use your lib. Facing that error, look at my eslintrc.js
, what I does wrong?
eslintrc.js:
module.exports = {
root: true,
ignorePatterns: ["node_modules/**/*", "dist/**/*", "storybook-static/*"],
overrides: [
{
files: ["*.ts"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: [
"tsconfig.json"
],
createDefaultProgram: true
},
extends: [
'airbnb-typescript/base',
'prettier/@typescript-eslint',
'plugin:prettier/recommended'
],
plugins: [
"@typescript-eslint",
"@angular-eslint",
"simple-import-sort"
],
rules: {
"@angular-eslint/directive-selector": [
"error",
{ "type": "attribute", "prefix": "app", "style": "camelCase" }
],
"@angular-eslint/component-selector": [
"error",
{ "type": "element", "prefix": "app", "style": "kebab-case" }
],
"simple-import-sort/sort": [
'error',
{
groups: [
// Side effect imports.
['^\\u0000'],
// Packages.
['^@?(?!mediu@nrwl/eslint-plugin-nxm\-stories)\\w'],
['^@medium\-stories?\\w'],
['^[^.]'],
// Relative imports.
// Anything that starts with a dot.
['^\\.'],
],
},
],
"sort-imports": "off",
"import/first": "error",
"import/newline-after-import": "error",
"import/no-duplicates": "error"
}
},
{
files: ["*.html"],
parser: "@angular-eslint/template-parser",
extends: ["plugin:@angular-eslint/template/recommended"],
rules: {
"max-len": ["error", { "code": 140 }]
}
}
]
}
https://github.com/eslint/eslint-plugin-markdown
Parsed some markdown files and totally mangled them. Easy to turn off the rule for markdown but other rules (like import/order
) seemed to manage the individual code blocks well.
@lydell hi, this is a great plugin!
...but I missing an option to ignore some files.
I always put typings (TypeScript) in a separate block:
import React from 'react'
import { Button } from './Button'
// typings
import { MyType } from '../types'
But with this plugin (and others) there's no way to preserve the order. Even with /* eslint-disable-next-line */
in some cases.
Any plans for such option?
If you maintain a plugin and provide installation instructions, you should ensure that the installation instructions are up to date with the user-facing changes to how plugins are loaded. In particular, if your plugin was generated with the generator-eslint package, it likely contains outdated instructions for how to use the plugin with global ESLint installations.
Updating to 6.0 leads to errors:
Namely:
Definition for rule 'simple-import-sort/imports' was not found simple-import-sort/imports
Is there a way to do something like this :
// eslint-disable-next-line simple-import-sort/sort
process.env.NODE_ENV = 'development';
import './some-import';
import './another import';
where I can set some environment variables before the imports ?
But what happens is process.env.NODE_ENV
gets transferred to the bottom of the imports.
import './some-import';
import './another import';
process.env.NODE_ENV = 'development';
Hi, I have some problems sorting by groups.
{
...
rules: {
"simple-import-sort/sort": [
"error",
{
groups: [["^\\u0000"], ["^[^.]"], ["^@?\\w"], ["^\\."]],
},
],
},
...
}
import react from "react";
import test from "@/components/test";
import "./style.less";
import {sort} from "../src"
Expected behavior
import "./style.less";
import test from "@/components/test";
import react from "react";
import {sort} from "../src"
Actual behavior
import "./style.less";
import test from "@/components/test";
import react from "react";
import {sort} from "../src"
So I think the defaultGroups need to be changed, The user should be able to change the import order directly by changing the defaultGroups, but this is not possible now, as this will mislead the user。for example, change it like below:
const defaultGroups = [
// Side effect imports.
["^\\u0000"],
// Packages.
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
["^@?\\w"],
// Absolute imports and other imports such as Vue-style `@/foo`.
// Anything that does not start with a dot.
["(^@/[^.])|(^/[^.])"],
// Relative imports.
// Anything that starts with a dot.
["^\\."],
];
if ["^\u0000"] is at the end of the groups
Eslint Config
{
...
rules: {
"simple-import-sort/sort": [
"error",
{
groups: [ ["^@?\\w"], ["^\\."],["^[^.]"],["^\\u0000"]],
},
],
},
...
}
** import code **
import react from "react";
import test from "@/components/test";
import "./style.less";
import {sort} from "../src"
Expected behavior
import react from "react";
import {sort} from "../src";
import test from "@/components/test";
import "./style.less";
Actual behavior
import react from "react";
import {sort} from "../src";
import "./style.less";
import test from "@/components/test";
The reason for this problem is that the 【"^[^.]"】 rules and 【["^\u0000"]】 rules coincide
Solution One: change group
groups: [ ["^@?\\w"], ["^\\."],["^[^.]"],["^\\u0000"]] => groups: [ ["^@?\\w"], ["^\\."],["(^@/[^.])|(^/[^.])"],["^\\u0000"]]
Solution Two: change flatMap function; such as:
flatMap(itemGroups, (groups) =>
groups.map((group) => [group, group.regex.exec(source)])
)
----------------------------------------------------------------------------------
flatMap(itemGroups, (groups) =>
groups.map((group) => group.regex.source.includes("^\\u0000")
? [group, group.regex.exec(source)]
: RegExp("^\\u0000", "u").exec(source)
? [group, null]
: [group, group.regex.exec(source)];)
)
I think it should be possible to change the import position by changing the parameter position in the default groups, but this is not possible now 🤡
Should change the default groups, and Readme documents 🤠🤠🤠
Some modules re-export members directly. This is also sort of an import.
I.e.
export { default as Foo, Fooz, Foob } from './Foo';
export { default, NonDefault } from './qwe';
export * from './asd';
export * as bar from './bar';
It would be nice if this would be sorted automatically as well following the same rules as imports.
I think this is mostly not combined with regular imports, but it could be. This means there should be rules for this.
Candidate rules I could come up with:
Personally I’d go with 2.
TypeScript 3.8 adds type-only imports:
https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#type-only-imports-exports
It should be easy to support this given that import type
in Flow is already supported.
Blocked by typescript-eslint/typescript-eslint#1465
👋 @lydell!
After switching from TSLint to ESLint and your plugin, I've noticed that named imports are sorted differently. Your approach is case-sensitive, while TSLint's ordered-imports
is not by default.
// tslint
import { a, B, c } from "somethiing";
// eslint-plugin-simple-import-sort
import { B, a, c } from "somethiing";
The former notation feels more natural to me. WDYT?
The plugin insists on removing the delimiting empty line between the imports and a semicolon. This affects, for example, inline function calls (which are prepended with a semicolon by prettier).
Example:
import { foo } from "bar"
;(async function() {
await foo()
})()
See screenshots:
The "fixed" version:
Allow empty line between imports and a block starting with a semicolon (as on screenshot 1).
If you need a reproduction repo I can create one. But I think the problem will repeat if you just copy/paste my example to any environment.
It would be nice to have an option to add comments above custom groups.
// node modules
import React, { useCallback, useState } from 'react';
import { View } from 'react-native';
// components
import { CustomButton } from 'src/components';
// screens
import CurrentTimezoneClock from 'src/screens/Clock/CurrentTimezoneClock';
// store
import { StoreState } from 'src/store/rootReducer';
// services
import { NavigationService } from 'src/services';
// utils
import { DateUtils, HooksUtils } from 'src/utils';
import { clockFormat, dateFormat } from 'src/utils/DateUtils';
// types
import { eIcons } from 'src/types/enums';
import { iSavedTimezoneEntry } from 'src/types/interfaces';
// styles
import styles from 'src/screens/Clock/styles';
import { appStyles, dimensions } from 'src/styles';
{
...
rules: {
"simple-import-sort/sort": [
"error",
{
groups: [
{ comment:"node modules", ['^react', '^@?\\w'] },
{ comment:"components", ['^src/components'] },
{ comment:"screens", ['^src/screens'] },
{ comment:"strore", ['^src/store'] },
{ comment:"services", ['^src/services'] },
{ comment:"utils", ['^src/utils'] },
{ comment:"types", ['^src/types'] },
],
},
],
},
...
}
I have <script> block in my vue component. For example:
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';
import { Location } from 'vue-router';
...
</script>
Indent is set to 4 spaces inside script block.
But when I run linter, I got this error:
As you can see, imports are sorted. And if I remove indentation, the error is gone.
Not sure how yours it supposed to work exactly. I saw a bunch of regex...
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md#groups-array
Currently the plugin crashes with typescript-eslint-parser
:
TypeError: Expected `index` to be a number.
at SourceCode.getLocFromIndex (/Users/semenov/tmp/ts-rule/node_modules/eslint/lib/util/source-code.js:436:19)
at maybeReportSorting (/Users/semenov/tmp/ts-rule/node_modules/eslint-plugin-simple-import-sort/src/sort.js:62:27)
at Program (/Users/semenov/tmp/ts-rule/node_modules/eslint-plugin-simple-import-sort/src/sort.js:20:11)
at listeners.(anonymous function).forEach.listener (/Users/semenov/tmp/ts-rule/node_modules/eslint/lib/util/safe-emitter.js:45:58)
at Array.forEach (<anonymous>)
at Object.emit (/Users/semenov/tmp/ts-rule/node_modules/eslint/lib/util/safe-emitter.js:45:38)
at NodeEventGenerator.applySelector (/Users/semenov/tmp/ts-rule/node_modules/eslint/lib/util/node-event-generator.js:251:26)
at NodeEventGenerator.applySelectors (/Users/semenov/tmp/ts-rule/node_modules/eslint/lib/util/node-event-generator.js:280:22)
at NodeEventGenerator.enterNode (/Users/semenov/tmp/ts-rule/node_modules/eslint/lib/util/node-event-generator.js:294:14)
at CodePathAnalyzer.enterNode (/Users/semenov/tmp/ts-rule/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:632:23)
I created the reproduction repo: https://github.com/IlyaSemenov/eslint-plugin-simple-import-sort-typescript-repro
Thanks for this awesome plugin.
Ran into this bug...
Using version 5.0.0
Input:
import { Subject, of } from 'rxjs';
Output:
import { ,ofSubject } from 'rxjs';
It would be cool if the plugin could automatically detect tsconfig.json to see which first party imports you have, such as web/components/foo
. Then those could be moved into the “absolute imports” group, instead of ending up in the (third party) “packages” group.
One idea is to use https://github.com/dividab/tsconfig-paths. Need to check that it actually supports baseUrl, though.
Another idea is to try to require("typescript")
. If it’s there, use it to resolve the config.
The initial idea comes from: #18 (comment)
Edit: This is a light-weight package that can do the hard work for us: https://github.com/privatenumber/get-tsconfig
Imports of the same package are to be combined to the one import.
Steps to reproduce:
Try to fix the following
import React from 'react'
import { Component } from 'react'
Actual result:
import React from 'react'
import { Component } from 'react'
Expected result:
import React, { Component } from 'react'
Steps to reproduce:
Try to fix the following
import './styles.scss'
import './styles.scss'
Actual result:
import './styles.scss'
import './styles.scss'
Expected result:
import './styles.scss'
I would love to have an option to disable alphabetical sorting. I just want import grouping.
Is that possible any way? Can't seem to find a solution.
Hi there - first off, thank you for creating this project!
We are having autofix issues when running eslint --fix
on this particular set of side-effect imports:
import "codemirror/addon/fold/brace-fold"
import "codemirror/addon/edit/closebrackets"
import "codemirror/addon/fold/foldgutter"
import "codemirror/addon/fold/foldgutter.css"
import "codemirror/addon/lint/json-lint"
import "codemirror/addon/lint/lint"
import "codemirror/addon/lint/lint.css"
import "codemirror/addon/scroll/simplescrollbars"
import "codemirror/addon/scroll/simplescrollbars.css"
import "codemirror/lib/codemirror.css"
import "codemirror/mode/javascript/javascript"
Expected behavior:
Actual behavior:
import "codemirror/addon/lint/lint"
import "codemirror/addon/fold/brace-fold"
import "codemirror/addon/fold/foldgutter"
import "codemirror/addon/fold/foldgutter.css"
import "codemirror/addon/lint/json-lint"
import "codemirror/addon/edit/closebrackets"
import "codemirror/addon/lint/lint.css"
import "codemirror/addon/scroll/simplescrollbars"
import "codemirror/addon/scroll/simplescrollbars.css"
import "codemirror/lib/codemirror.css"
import "codemirror/mode/javascript/javascript"
If I find an easier repro, I'll include it. Happy to also help dig into this further when I have a chance. Cheers.
I have this code:
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
with this config:
// conflicts with the below
'sort-imports-es6-autofix/sort-imports-es6': 'off',
// combine imports
'import/no-duplicates': 'error',
// does not support sorting "require"
'simple-import-sort/sort': ['error', {
groups: [
// Framework Packages
// ['^@ember', '^@glimmer', 'ember-qunit', 'qunit'],
// Side effect imports.
['^\\u0000'],
// Parent imports. Put `..` last.
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
// Other relative imports. Put same-folder imports and `.` last.
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
// Style imports.
['^.+\\.s?css$'],
],
}],
and the imports keep flip flopping and the broken state never settles.
import { setupTest } from 'ember-qunit';
import { module, test } from 'qunit';
only the bottom import errors, but autfixing goes to
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
but then both lines error, and autofix to the first
Now imports of this kind
import { b, a } from 'some-package';
Are treated as OK and there is no option to highlight and fix them so they will look like
import { a, b } from 'some-package';
This is with "eslint-plugin-simple-import-sort": "5.0.1"
.
Before (i.e. 2.22.0):
import "hard-rejection/register";
import chalk from "chalk";
import dotenv from "dotenv";
import ora from "ora";
import pluralize from "pluralize";
After:
import chalk from "chalk";
import dotenv from "dotenv";
import "hard-rejection/register";
import ora from "ora";
import pluralize from "pluralize";
Here's the changelog. Seems most likely to be caused by (completely uneducated guess) typescript-eslint/typescript-eslint#1697?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.