Code Monkey home page Code Monkey logo

prettier-plugin-sort-imports's Introduction

Prettier plugin sort imports

A prettier plugin to sort import declarations by provided Regular Expression order.

Note: If you are migrating from v2.x.x to v3.x.x, Please Read Migration Guidelines

Input

import React, {
    FC,
    useEffect,
    useRef,
    ChangeEvent,
    KeyboardEvent,
} from 'react';
import { logger } from '@core/logger';
import { reduce, debounce } from 'lodash';
import { Message } from '../Message';
import { createServer } from '@server/node';
import { Alert } from '@ui/Alert';
import { repeat, filter, add } from '../utils';
import { initializeApp } from '@core/app';
import { Popup } from '@ui/Popup';
import { createConnection } from '@server/database';

Output

import { debounce, reduce } from 'lodash';
import React, {
    ChangeEvent,
    FC,
    KeyboardEvent,
    useEffect,
    useRef,
} from 'react';

import { createConnection } from '@server/database';
import { createServer } from '@server/node';

import { initializeApp } from '@core/app';
import { logger } from '@core/logger';

import { Alert } from '@ui/Alert';
import { Popup } from '@ui/Popup';

import { Message } from '../Message';
import { add, filter, repeat } from '../utils';

Install

npm

npm install --save-dev @trivago/prettier-plugin-sort-imports

or, using yarn

yarn add --dev @trivago/prettier-plugin-sort-imports

Note: If you are migrating from v2.x.x to v3.x.x, Please Read Migration Guidelines

Note: If formatting .vue sfc files please install @vue/compiler-sfc if not in your dependency tree - this normally is within Vue projects.

Usage

Add an order in prettier config file.

module.exports = {
  "printWidth": 80,
  "tabWidth": 4,
  "trailingComma": "all",
  "singleQuote": true,
  "semi": true,
  "importOrder": ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
  "importOrderSeparation": true,
  "importOrderSortSpecifiers": true
}

**Note: There may be an issue with some package managers, such as pnpm. You can solve it by providing additional configuration option in prettier config file.

module.exports = {
    ...
    "plugins": ["@trivago/prettier-plugin-sort-imports"]
}

APIs

importOrder

type: Array<string>

A collection of Regular expressions in string format.

"importOrder": ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],

Default behavior: The plugin moves the third party imports to the top which are not part of the importOrder list. To move the third party imports at desired place, you can use <THIRD_PARTY_MODULES> to assign third party imports to the appropriate position:

"importOrder": ["^@core/(.*)$", "<THIRD_PARTY_MODULES>", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],

importOrderSeparation

type: boolean

default value: false

A boolean value to enable or disable the new line separation between sorted import declarations group. The separation takes place according to the importOrder.

"importOrderSeparation": true,

importOrderSortSpecifiers

type: boolean

default value: false

A boolean value to enable or disable sorting of the specifiers in an import declarations.

importOrderGroupNamespaceSpecifiers

type: boolean

default value: false

A boolean value to enable or disable sorting the namespace specifiers to the top of the import group.

importOrderCaseInsensitive

type: boolean

default value: false

A boolean value to enable case-insensitivity in the sorting algorithm used to order imports within each match group.

For example, when false (or not specified):

import ExampleView from './ExampleView';
import ExamplesList from './ExamplesList';

compared with "importOrderCaseInsensitive": true:

import ExamplesList from './ExamplesList';
import ExampleView from './ExampleView';

importOrderParserPlugins

type: Array<string>

default value: ["typescript", "jsx"]

Previously known as experimentalBabelParserPluginsList.

A collection of plugins for babel parser. The plugin passes this list to babel parser, so it can understand the syntaxes used in the file being formatted. The plugin uses prettier itself to figure out the parser it needs to use but if that fails, you can use this field to enforce the usage of the plugins' babel parser needs.

To pass the plugins to babel parser:

  "importOrderParserPlugins" : ["classProperties", "decorators-legacy"]

To pass the options to the babel parser plugins: Since prettier options are limited to string, you can pass plugins with options as a JSON string of the plugin array: "[\"plugin-name\", { \"pluginOption\": true }]".

  "importOrderParserPlugins" : ["classProperties", "[\"decorators\", { \"decoratorsBeforeExport\": true }]"]

To disable default plugins for babel parser, pass an empty array:

importOrderParserPlugins: []

How does import sort work ?

The plugin extracts the imports which are defined in importOrder. These imports are considered as local imports. The imports which are not part of the importOrder is considered as third party imports.

After, the plugin sorts the local imports and third party imports using natural sort algorithm.

In the end, the plugin returns final imports with third party imports on top and local imports at the end.

The third party imports position (it's top by default) can be overridden using the <THIRD_PARTY_MODULES> special word in the importOrder.

FAQ / Troubleshooting

Having some trouble or an issue ? You can check FAQ / Troubleshooting section.

Compatibility

Framework Supported Note
JS with ES Modules ✅ Everything -
NodeJS with ES Modules ✅ Everything -
React ✅ Everything -
Angular ✅ Everything Supported through importOrderParserPlugins API
Vue ✅ Everything @vue/compiler-sfc is required
Svelte ⚠️ Soon to be supported. Any contribution is welcome.

Used by

Want to highlight your project or company ? Adding your project / company name will help plugin to gain attraction and contribution. Feel free to make a Pull Request to add your project / company name.

Contribution

For more information regarding contribution, please check the Contributing Guidelines. If you are trying to debug some code in the plugin, check Debugging Guidelines

Maintainers

Ayush Sharma Behrang Yarahmadi
ayusharma @byara
@ayusharma_ @behrang_y

Disclaimer

This plugin modifies the AST which is against the rules of prettier.

prettier-plugin-sort-imports's People

Contributors

adamdilgergeo avatar ayusharma avatar basselworkforce avatar blake-newman avatar blutorange avatar broofa avatar byara avatar c-dante avatar esjs avatar friederbluemle avatar gavinhenderson avatar harryzcy avatar jamesgelok avatar juanrgm avatar leomotors avatar marvinroger avatar mathieu-bour avatar matt-kinton avatar miles-au avatar odiak avatar omarsotillo avatar raineorshine avatar ratierd avatar saaryab avatar stephdotnet avatar taiwabisabi avatar timiles avatar transitive-bullshit avatar xenfo avatar yykamei 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  avatar  avatar  avatar  avatar  avatar

prettier-plugin-sort-imports's Issues

Separate and prioritize built-in Node modules over 3rd party modules

Is it possible prioritize Node's built-in modules over 3rd party modules?

Given the following imports:

import path from 'path'
import cookieSession from 'cookie-session'
import cors from 'cors'
import favicon from 'serve-favicon'
import 'express-async-errors'
import { createProxyMiddleware } from 'http-proxy-middleware'
import express from 'express'

The plugin will output the following after formatting

import cookieSession from 'cookie-session'
import cors from 'cors'
import express from 'express'
import 'express-async-errors'
import { createProxyMiddleware } from 'http-proxy-middleware'
import path from 'path'
import favicon from 'serve-favicon'

But would be nice if built-in modules like path, fs, util, etc are prioritized

import path from 'path'

import cookieSession from 'cookie-session'
import cors from 'cors'
import express from 'express'
import 'express-async-errors'
import { createProxyMiddleware } from 'http-proxy-middleware'
import favicon from 'serve-favicon'

Even the following config would not solve this because these built-in modules would appear after and not before.

"importOrder": [
  "^(assert|buffer|child_process|cluster|crypto|dgram|dns|domain|events|fs|http|https|net|os|path|punycode|querystring|readline|stream|string_decoder|timers|tls|tty|url|util|v8|vm|zlib)$",
  "^[./]"
],

Undesired result (path is not prioritized):

import cookieSession from 'cookie-session'
import cors from 'cors'
import express from 'express'
import 'express-async-errors'
import { createProxyMiddleware } from 'http-proxy-middleware'
import favicon from 'serve-favicon'

import path from 'path'

Comments have trailing new lines removed

Input:

/*
 * Licence Header
*/

import { foo } from "foo"

console.log(foo.bar())

Expected Output

Unchanged from input

/*
 * Licence Header
*/

import { foo } from "foo"

console.log(foo.bar())

Actual Output:

/*
 * Licence Header
*/
import { foo } from "foo"

console.log(foo.bar())

Plugin eats all newlines in svelte modules

To reproduce:

package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "prettier": "^2.2.1",
    "prettier-plugin-svelte": "^2.2.0",
    "svelte": "^3.38.2"
  },
  "devDependencies": {
    "@trivago/prettier-plugin-sort-imports": "^2.0.2"
  }
}

test.svelte

$ cat test.svelte
<script lang="ts">
  import { getContext } from "svelte";
  import { calculateCartContents } from "$lib/utils";
  import type { CartContents, Item } from "$lib/utils";

  const cartStore: Readable<CartContents> = getContext("cart-store");
  const shopItems: Record<string, Item> = getContext("shop-items");

  let cartItemsCount: number;
  let cartTotal: number;

  cartStore.subscribe((cart) => {
    ({ count: cartItemsCount, sum: cartTotal } = calculateCartContents(cart, shopItems));
  });
</script>

<div>
<p>Hello world</p>
</div>

Output from npm exec prettier test.svelte after env NODE_ENV=production npm i (doesn't install this plugin)

<script>
  import { getContext } from "svelte";
  import { calculateCartContents } from "$lib/utils";
  import type { CartContents, Item } from "$lib/utils";

  const cartStore: Readable<CartContents> = getContext("cart-store");
  const shopItems: Record<string, Item> = getContext("shop-items");

  let cartItemsCount: number;
  let cartTotal: number;

  cartStore.subscribe((cart) => {
    ({ count: cartItemsCount, sum: cartTotal } = calculateCartContents(
      cart,
      shopItems
    ));
  });
</script>

<div>
  <p>Hello world</p>
</div>

Output from npm exec prettier test.svelte after env NODE_ENV=development npm i (installs also this plugin)

<script>
  import { calculateCartContents } from "$lib/utils";
  import type { CartContents, Item } from "$lib/utils";
  import { getContext } from "svelte";
  const cartStore: Readable<CartContents> = getContext("cart-store");
  const shopItems: Record<string, Item> = getContext("shop-items");
  let cartItemsCount: number;
  let cartTotal: number;
  cartStore.subscribe((cart) => {
    ({ count: cartItemsCount, sum: cartTotal } = calculateCartContents(
      cart,
      shopItems
    ));
  });
</script>

<div>
  <p>Hello world</p>
</div>

Nothing changes when I add .prettierrc with importOrderSeparation: true

Feature request: Preserve comments

It would be lovely if it comments inside the imports could be preseved. This becomes a problem with long imports when only a single item is imported (and there is an eslint rule about max-line-length in place).

For example:

// eslint-disable-next-line max-len
import { UpdateCheckoutShippingAddress_checkoutEmailUpdate_checkoutErrors as CheckoutError } from '@api-sdk/mutations/types/UpdateCheckoutShippingAddress';

import BusinessForm, { BusinessFormValues } from './Forms/BusinessForm';
import ProfileForm, { ProfileFormValues } from './Forms/ProfileForm';

currently always becomes this:

import { UpdateCheckoutShippingAddress_checkoutEmailUpdate_checkoutErrors as CheckoutError } from '@saleor-sdk/mutations/types/UpdateCheckoutShippingAddress';

import BusinessForm, { BusinessFormValues } from './Forms/BusinessForm';
import ProfileForm, { ProfileFormValues } from './Forms/ProfileForm';

// eslint-disable-next-line max-len

Case-insensitive ordering

Hi, is it possible to have imports ordered with case-insensitivity? If not, can I please request this as a feature?

An example: no import order specified, importing siblings "ThingsList" and "ThingView". I would like for them to listed in that order, as s comes before V. But due to case sensitivity, upper case V actually comes before lower case s, so we get:

import ThingView from './ThingView';
import ThingsList from './ThingsList';

I could try to help write this feature if it is desirable.

Feature: Sort imports by line length

Hello,

Add an option to sort imports by line length. For example:

Sort by line length in ascending order:

import { LocationProvider } from "@services/location/location.context";
import { FavouritesProvider } from "@services/favourites/favourites.context";
import { RestaurantsProvider } from "@services/restaurants/restaurants.context";
import { AuthenticationProvider } from "@services/authentication/authentication.context";

Sort by line length in descending order:

import { AuthenticationProvider } from "@services/authentication/authentication.context";
import { RestaurantsProvider } from "@services/restaurants/restaurants.context";
import { FavouritesProvider } from "@services/favourites/favourites.context";
import { LocationProvider } from "@services/location/location.context";

How to use babelRC to pass the Parser option?

Your source code is follows

 var defaultConfig = {
        sourceType: 'module',
        plugins: ['typescript', 'jsx'],
    };
    var babelConfig = core_1.loadOptions();
    var mergedOptions = lodash_1.merge(defaultConfig, babelConfig);
    var ast = parser_1.parse(code, mergedOptions);

.babelrc is example

{
  "parserOpts": {
    "plugins": ["classProperties"]
  }
}

merge value is

 {
    sourceType: 'module',
    plugins: ['typescript', 'jsx'],
    parserOpts: {
        plugins: ['classProperties']
    }
};

The expected value should be follows

 {
    sourceType: 'module',
    plugins: ['typescript', 'jsx', 'classProperties'],
};

How do I set .babelrc to pass the Parser option correctly, or is there a problem with your source code?

Thank you very much

Breaks with shebang

Prettier v2.2.1
@trivago/prettier-plugin-sort-imports v1.4.4
macOS 11.2.1

Screenshot 2021-03-07 at 4 12 34 PM

Move React on top

Thanks for the plugin. The default order works for me, except one thing: Is there a way to move React on top, and keep it as a first-line?

Typescript error in first argument of `getParserPlugins` function

Problem

line 18 of src/preprocessor.ts stating:

Argument of type 'LiteralUnion<BuiltInParserName, string> | CustomParser' is not assignable to parameter of type 'BuiltInParserName | CustomParser'.
  Type 'Pick<string, never> & { _?: undefined; }' is not assignable to type 'BuiltInParserName | CustomParser'.
    Type 'Pick<string, never> & { _?: undefined; }' is not assignable to type 'CustomParser'.
      Type 'Pick<string, never> & { _?: undefined; }' provides no match for the signature '(text: string, parsers: BuiltInParsers, options: Options): any'.ts(2345)

Steps to recreate

  1. Fork repo
  2. Clone repo
  3. Open in an ide that supports typescript (ex: VSCode), with typescript installed.
  4. Open src/preprocessor.ts with typescript highlighting enabled
  5. Notice the error under getParserPlugins

OR

Try to compile

Additional Notes

This ts error seems straightforward to correct.

It may be good to use GitHub actions/other tests to prevent this from happening in the future.

SyntaxError: Unexpected token, expected "}"

[error] apps/api/src/app/modules/design/template/template.controller.ts: SyntaxError: Unexpected token, expected "}" (60:68)
[error]    1 | import { Body, Controller, HttpService, Post } from "@nestjs/common";
[error]    2 | import { retry } from "rxjs/operators";
[error]    3 |
[error]    4 | import { DesignTemplate, DesignTextElement } from "@diandiantu/design/interfaces";
[error]    5 |
[error]    6 | import { TemplateService } from "../service/template.service";
[error]    7 | import { UpdateTextDao } from "./update-text.dao";
[error]    8 | import { TextRender } from "@diandiantu/design/render";
[error]    9 | import { CanvasKitService } from "../../../thrid-party/canvas-kit/canvas-kit.service";
[error]   10 | import { CanvasKit } from "@design/canvaskit-wasm";
[error]   11 |
[error]   12 | @Controller("/design/template")
[error]   13 | export class TemplateController {
[error]   14 |   requestFile: (url) => Promise<ArrayBuffer>;
[error]   15 |   CanvasKit: CanvasKit;
[error]   16 |
[error]   17 |   constructor(private templateService: TemplateService, private _httpService: HttpService,
[error]   18 |               private _canvaskitService: CanvasKitService) {
[error]   19 |     this.CanvasKit = this._canvaskitService.canvasKit;
[error]   20 |     this.requestFile = (url) => {
[error]   21 |       const req = this._httpService
[error]   22 |         .get<ArrayBuffer>(`http:${url}`, { responseType: "arraybuffer" })
[error]   23 |         .pipe(retry(3))
[error]   24 |         .toPromise();
[error]   25 |       return new Promise<ArrayBuffer>((resolve, reject) => {
[error]   26 |         req
[error]   27 |           .then((resp) => {
[error]   28 |             resolve(resp.data);
[error]   29 |           })
[error]   30 |           .catch(reject);
[error]   31 |       });
[error]   32 |     };
[error]   33 |   }
[error]   34 |
[error]   35 |   @Post("/update_text_height")
[error]   36 |   async update_text_height(@Body() body: UpdateTextDao) {
[error]   37 |     const { template_id, system } = body;
[error]   38 |     let templateData: DesignTemplate;
[error]   39 |     if (system) {
[error]   40 |       templateData = await this.templateService.getSystemTemplateData(template_id);
[error]   41 |     } else {
[error]   42 |       templateData = await this.templateService.getUserTemplateData(template_id);
[error]   43 |     }
[error]   44 |
[error]   45 |     for (const page of templateData) {
[error]   46 |       const pIndex = templateData.indexOf(page);
[error]   47 |       for (const ele of page.elements) {
[error]   48 |         const eIndex = page.elements.indexOf(ele);
[error]   49 |         if (ele.type === "text") {
[error]   50 |           const oldHeight = ele.base.h;
[error]   51 |
[error]   52 |           const provider = await this._canvaskitService.loadProvider();
[error]   53 |           const defaultName = this._canvaskitService.defaultFonts;
[error]   54 |
[error]   55 |           const textProcess = new TextRender(<DesignTextElement>ele, this.CanvasKit, provider, defaultName);
[error]   56 |           await textProcess.render();
[error]   57 |           const newHeight = textProcess.paragraph.getHeight();
[error]   58 |
[error]   59 |           if (newHeight > oldHeight) {
[error]   60 |             templateData[pIndex].elements[eIndex].base.h = newHeight;
[error]   61 |           }
[error]   62 |         }
[error]   63 |       }
[error]   64 |     }
[error]   65 |
[error]   66 |     if (system) {
[error]   67 |       return this.templateService.saveSystemTemplateData(template_id, templateData);
[error]   68 |     } else {
[error]   69 |       return this.templateService.saveUserTemplateData(template_id, templateData);
[error]   70 |     }
[error]   71 |   }
[error]   72 | }
[error]   73 |
[error] libs/design/render/src/page-render.ts: SyntaxError: Unexpected token (169:8)
.
.
.
[error]   161 |   async render() {
[error]   162 |     const bgNode = await this.renderBackground();
[error]   163 |     this.svgTree.children.push(bgNode);
[error]   164 |     const { elements } = this.data;
[error]   165 |     const elePromises = elements.map((element) => {
[error]   166 |       if (element.type === 'svg') {
[error]   167 |         return this.renderSVG(<DesignSVGElement>element);
[error]   168 |       } else if (element.type === 'text') {
[error]   169 |         return this.renderText(<DesignTextElement>element);
[error]   170 |       }
[error]   171 |     });
[error]   172 |     const eleNodes = (await Promise.all(elePromises)).reduce<INode[]>((result, curr) => {
[error]   173 |       if (curr) {
[error]   174 |         result.push(curr);
[error]   175 |       }
[error]   176 |       return result;
[error]   177 |     }, []);
[error]   178 |     this.svgTree.children.push(...eleNodes);
[error]   179 |     return stringify(this.svgTree);
[error]   180 |   }

There are two errors during formatting, and I don't know why there is an error here. If I remove prettier-plugin-sort-imports without any errors

Not sorting imports in .vue files

Hi, I have a following config:

{
  "importOrder": [
    "^vue/(.*)$",
    "^[^@v](.*)$",
    "^@(.*)$",
    "^[./]"
  ],
  "importOrderSeparation": true,
}

And an App.vue file (already formatted with prettier):

<script>
import Vue from 'vue'
import TheNavBar from '@/components/TheNavBar'
import dayjs from 'dayjs'
</script>

When I copy its content to .ts file, it gets formatted as expected:

import Vue from 'vue'

import dayjs from 'dayjs'

import TheNavBar from '@/components/TheNavBar'

Is it possible to somehow enable .vue files support?

decorators an class properties errors on a react project

when trying to run on a project with modern/ experimental js features it throws errors

packages/react-common/stores/UsersRepoStore.ts: SyntaxError: This experimental syntax requires enabling the parser plugin: 'classProperties' (10:22)

or

s[error] packages/react-common/stores/RecipesRepoStore.ts: SyntaxError: This experimental syntax requires enabling one of the following parser plugin(s): 'decorators-legacy, decorators' (9:1)

here is my setup:

module.exports = {
	singleQuote: true,
	printWidth: 120,
	useTabs: true,
	tabWidth: 2,
	semi: true,
	arrowParens: 'always',
	bracketSpacing: true,
	trailingComma: 'es5',
	importOrder: ['^\@co\-cooking', '^\.\.\/', '^\.\/(?!style)', '^\.\/style'],
	importOrderSeparation: true
};

tried using the typescript & babel parsers but it didn't work

line between import and comment

Hello, how can i disable line between imports and first comment after imports
I'm using hygen and i don't need line after imports, but formatting file paste this line

Match Last Regex

Hello!
I was wondering if it's possible to make the sorter use the last regex matched.

The way I assume it works right now is it goes through the list of regexes in order and stops when it finds a match.
Maybe it could first reverse the list and then find the first match? (which would be the last match)
This would make it easier to setup a sorting order where a regex can match multiple statements!

If there's already a way to do this that I'm not aware of please let me know!

Throws when babel config has override section

The problem occurs when using the plugin with more complex babel configuration. Example:

{
     overrides: [{
         test: /\.jsx$/,
         presets: ['@babel/preset-react']
     }]
}

This is not specified anywhere in Babel documentation, but Babel expects that the filename option should be provided, when calling loadPartialConfig() or loadOptions().

Otherwise this line causes the exception:
Error: Configuration contains string/RegExp pattern, but no filename was passed to Babel

I suggest at least to wrap it with try-catch block and use base config as a fallback.

Plugin not running

Prettier config:

module.exports = {
  semi: true,
  singleQuote: true,
  bracketSpacing: true,
  trailingComma: 'none',
  importOrder: ['^[./]'],
  importOrderSeparation: true,
  experimentalBabelParserPluginsList: ['typescript'],
  plugins: [require.resolve('@trivago/prettier-plugin-sort-imports')],
  overrides: [
    {
      files: ['*.ts'],
      options: {
        parser: 'babel-ts',
      },
    }
  ]
};

Example Repo:
https://github.com/Xenfo/snow.js

When I format my document imports do no get sorted.

Join similar import source

Hi, it would be nice to join the similar import source. E.g. this:

Input

import one, { two } from './source'
import { three } from './source'

Output

import one, { two, three } from './source'

Thanks!

Sort not work with parser: "babel-flow"

Here is my .prettierrc.json
{ "singleQuote": true, "importOrder": ["^src/(.*)$", "^[./]"], "importOrderSeparation": true, "printWidth": 120, "parser": "babel-flow" }

I try removing parser line then it works normally, but it won't sort with the parser: "babel-flow. Is this a bug or I was wrong somewhere?

Commented imports dupe

File Imports or destructured imports get duped after formatting if they're commented at the beginning of the file.

I have the following config:

{
  "importOrder": [
    "^@k9/(.*)$",
    "^@(.*)$",
    "^[./]"
  ],
  "importOrderSeparation": true,
  "semi": false,
  "singleQuote": true,
  "printWidth": 80
}

gif

Monorepo config

The plugin is showing me these warnings:

[warn] Ignored unknown option { importOrder: ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"] }.
[warn] Ignored unknown option { importOrderSeparation: true }.

I have this folder structure

|
|-- packages/
|        |-- utils/
|        `-- ui/
`-- package.json

And my .prettierrc is inside the ui folder.

Note:

  • This error doesn't happen when running prettier from the root.

Thanks a lot!

Extra empty lines with ESLint comment on top of the file

Hello.
While I'm using ESLint comment to disable some rules in the file, the plugin adds some extra lines between imports and the code.
Formatted file looks like this:

/* eslint-disable no-console */
import { ApplicationState } from '../types';





function test(value: string): ApplicationState {
    console.log('TEST');
    return {};
}

export default test;

I'm using these versions of packages:
package.json

    ...
    "devDependencies": {
        ...
        "@trivago/prettier-plugin-sort-imports": "^1.3.0",
        "@typescript-eslint/eslint-plugin": "^4.9.1",
        "@typescript-eslint/parser": "^4.9.1",
        "eslint": "7.15.0",
        "eslint-config-airbnb": "18.2.1",
        "eslint-config-airbnb-typescript": "^12.0.0",
        "eslint-config-prettier": "^7.0.0",
        "eslint-plugin-import": "^2.22.1",
        "eslint-plugin-jest": "^24.1.3",
        "eslint-plugin-jsx-a11y": "^6.4.1",
        "eslint-plugin-prettier": "^3.3.0",
        "eslint-plugin-react": "^7.21.5",
        "eslint-plugin-react-hooks": "4.2.0",
        "prettier": "2.1.2",
        "typescript": "^4.1.3"
    }
}

Decorators problem for Angular project.

Hello,

I tried to use the plugin in the Angular project and got this error:

> prettier --write src/app/app.component.ts --config ./.prettierrc
src\app\app.component.ts
[error] src\app\app.component.ts: SyntaxError: This experimental syntax requires enabling one of the following parser plugin(s): 'decorators-legacy, decorators' (5:0)
[error]    1 | import { isEmpty } from "lodash-es";
[error]    2 | 
[error]    3 | import { Component } from "@angular/core";
[error]    4 | 
[error]    5 | @Component({
[error]    6 |   selector: "app-root",
[error]    7 |   templateUrl: "./app.component.html",
[error]    8 |   styleUrls: ["./app.component.css"]
[error]    9 | })
[error]   10 | export class AppComponent {
[error]   11 |   title = "ng-prettier";
[error]   12 | 
[error]   13 |   get text(): string {
[error]   14 |     return isEmpty(this.title) ? "" : this.title;
[error]   15 |   }
[error]   16 | }
[error]   17 | 
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] format: `prettier --write src/app/app.component.ts --config ./.prettierrc`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] format script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

I use:

  • Prettier: 2.2.0
  • Angular: 11.0.2
  • Typescript: 4.0.5
  • Plugin version: 1.3.0

What am I doing wrong?
Is there any workaround?

Thanks a lot.

NOTE: No problem with React.

SyntaxError: Unexpected token throws when using with flow

I tried to add on react project which uses flow but it shows several errors on nullable types such as

handleChange = (value: ?string) => {}

or when have such code during import

import { type Something } from './__generated__/;

Support option on Prettier CLI

To be able to run the script prettier --write . and apply the changes in the codebase to fix the import sorting. Not sure if this is the right medium to ask for this.

image

TypeScript - import from declare module is moved to top

I have global.d.ts with contents:

declare module "*.scss" {
  const content: { [className: string]: string };
  export = content;
}

declare const env: {
  [key: string]: string;
};


declare module "path-browserify" {
  import * as path from "path";
  export = path;
}

and after running prettier on this file this happens:

+  import * as path from "path";
+
declare module "*.scss" {
  const content: { [className: string]: string };
  export = content;
}

declare const env: {
  [key: string]: string;
};


declare module "path-browserify" {
-  import * as path from "path";
  export = path;
}

Experimental syntax error not going away with flag on true

hi there, im trying out this plugin.
It works great with VScode and running eslint or prettier but when i try to start the app i get the error:

Syntax error: This experimental syntax requires enabling one of the following parser plugin(s): 'jsx, flow, typescript' prettier/prettier (10:14)

In many files, i tried setting what you suggest in the FAQ but nothing changes.

I have these options in my prettierrc.toml file

importOrder = [ "^__(.*)$", "^[./]" ]
importOrderSeparation = true
experimentalBabelParserPluginsList = ["jsx"]

I'm using CRACO with very basic config options, nothing weird.

Any ideas what i could add/remove to help with this?

Thanks and kind regards

sort imported items, too

Hi,

it would be nice to sort the imported items from a file, too. E.g. this:

import {
  dayCalendarPath,
  weekCalendarPath,
  monthCalendarPath,
  agendaCalendarPath,
} from "../path_helpers/calendar_paths";

will get sorted to

import {
  agendaCalendarPath,
  dayCalendarPath,
  monthCalendarPath,
  weekCalendarPath
} from "../path_helpers/calendar_paths";

Best regards,
CK

Remove unused imports

Love this plugin! Saves so much time.

One thing I'd love it to do is remove imports that aren't used. VS Code does this already with alt+shift+O but the ability for this plugin to do it alongside the sorting would be great.

Ignore blocks for Angular Universal

Hi there, first of all, many thanks for the plugin! And especially recent the fix that allows us to run in TS/Angular.

We have an instance that runs pre-rendering with Angular Universal, and in our server.ts file, we need to instantiate a browser emulator, before import { AppServerModule } (see code below). Running your plugin however puts all of the imports at the top, which breaks our pre-rendering of our app.

I have looked at the standard Prettier ignore, which doesn't seem to allow ignoring blocks (range ignore) in JavaScript code.

Is there a smart way to ignore a file/block from import sorting that works with your plugin?

Thanks!

...

// Emulate browser APIs
const domino = require('domino');
const templateA = readFileSync(join(distFolder, indexHtml)).toString();

const win = domino.createWindow(templateA);
win.Object = Object;
win.Math = Math;
// NOTE: This must happen before importing `AppServerModule`
global['window'] = win;
global['document'] = win.document;

import { AppServerModule } from './src/projects/website';

...

Error: Cannot find module 'prettier/parser-babel'

After adding @trivago/prettier-plugin-sort-imports to the project, I'm receiving an error when formatting:

Command:

/project_path/node_modules/.bin/prettier --write js/components/MyComponent.tsx

Error message:

Error: Cannot find module 'prettier/parser-babel'
Require stack:
- /project_path/node_modules/@trivago/prettier-plugin-sort-imports/lib/src/index.js
- /project_path/node_modules/prettier/bin-prettier.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:793:17)
    at Function.Module._load (internal/modules/cjs/loader.js:686:27)
    at Module.require (internal/modules/cjs/loader.js:848:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/project_path/node_modules/@trivago/prettier-plugin-sort-imports/lib/src/index.js:14:22)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Module.require (internal/modules/cjs/loader.js:848:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/project_path/node_modules/@trivago/prettier-plugin-sort-imports/lib/src/index.js',
    '/project_path/node_modules/prettier/bin-prettier.js'
  ]

Here's my .prettierrc:

{
  "trailingComma": "all",
  "singleQuote": true,
  "printWidth": 100,
  "importOrder": [
    "(.*).scss$",
    "(^react$)|(^react-(.*)$)",
    "(^[a-z_-]+$)|(^@(.*)/(.*)$)",
    "^components/(.*)$",
    "^[./]"
  ],
  "importOrderSeparation": true
}

Any ideas what could be wrong 🙁?

Fails to install with Prettier 2.3.0

Hi there,

Now Prettier 2.3.0 is out, there's an issue installing this. In https://github.com/trivago/prettier-plugin-sort-imports/blob/master/package.json Prettier is listed both as a peerDependency with a version specifier of ^2.2.1 which permits Prettier 2.3.0, but it's also listed as a dependency with an exact version of 2.2.1. I suspect this is a mistake, and it should only be listed as a peerDependency, but right now this causes Yarn to fail to install this as it can't find a version of Prettier to link. Fixing Prettier to 2.2.1 in our package.json when importing this fixes it, but I think the duplication needs to be resolved here too.

Thanks in advance for the help :)

feature: optionally insert new lines between import blocks

This project is amazing! I am forever fixing imports to be in an order like this.

The only thing that's stopping me using it is that I like to have a new line between the import blocks. So something like:

import react from 'react';

import util from '@app/util';

import relativeImport from '../../thing';

I'm sure lots of people don't want this so maybe it makes sense to have it be an optional flag?

Removes all line breaks in Svelte

Summary

The problem is as stated in the title: when formatting with this plugin, all line breaks disappear.

Actual behavior

<script>
  import Component from './Component.js'
  import { onMount } from 'svelte'
  onMount(() => {
    // --snip--
  })
</script>

Expected behavior

<script>
  import Component from './Component.js'
  import { onMount } from 'svelte'

  onMount(() => {
    // --snip--
  })
</script>

If there are more line breaks, either between imports or normal lines of code, they are all deleted.

Allow to not sort local imports

Usually the order of 3rd parties doesn't matter but locally might be (when a module initiate something and return the initiated instance).

It could be nice to have a flag to prevent the local imports sorting.

Functionality to move NodeJS builtin modules to the top

Hi there, thanks for this package, really cool! Will consider recommending it to our bootcamp students at @upleveled.

One suggestion that came to mind would be to make it the default sort order to sort imports using the new node: scheme / prefix to the top. What do you think?

SyntaxError: This experimental syntax requires enabling the parser plugin: 'classProperties' (118:33)

when I install this plugin, vscode and prettier stop formatting with the above error

I'm using vscode 1.52.1, with typescript 4.1.2

the stack trace is this

at Object._raise (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:748:17)
	at Object.raiseWithData (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:741:17)
	at Object.expectPlugin (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:9106:18)
	at Object.parseClassProperty (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12722:12)
	at Object.parseClassProperty (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6968:18)
	at Object.pushClassProperty (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12690:30)
	at Object.parseClassMemberWithIsStatic (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12595:14)
	at Object.parseClassMemberWithIsStatic (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6856:11)
	at Object.parseClassMember (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12532:10)
	at callParseClassMember (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6820:13)
	at Object.parseClassMember (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6826:7)
	at /workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12477:14
	at Object.withTopicForbiddingContext (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:11516:14)
	at Object.parseClassBody (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12454:10)
	at Object.parseClass (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12427:22)
	at Object.parseStatementContent (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:11718:21)
	at Object.parseStatementContent (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6806:18)
	at Object.parseStatement (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:11676:17)
	at Object.parseExportDeclaration (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12892:17)
	at Object.parseExportDeclaration (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6927:27)
	at Object.maybeParseExportDeclaration (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12848:31)
	at Object.parseExport (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12786:29)
	at Object.parseExport (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6769:20)
	at Object.parseStatementContent (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:11782:27)
	at Object.parseStatementContent (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:6806:18)
	at Object.parseStatement (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:11676:17)
	at Object.parseBlockOrModuleBlockBody (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12258:25)
	at Object.parseBlockBody (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:12249:10)
	at Object.parseTopLevel (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:11607:10)
	at Object.parse (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:13415:10)
	at Object.parse (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/parser/lib/index.js:13468:38)
	at Object.preprocessor [as preprocess] (/workspace/node_modules/@trivago/prettier-plugin-sort-imports/lib/src/preprocessor.js:21:24)```

Add import groups configuration

Summary

My actual use-case is that I want React to be imported as first but I also want line breaking between my imports. If in the importOrder configuration I setup the following : "importOrder": ["^react", "^(?!react)\\w+$"] (from #7 (comment)) with importOrderSeparation: true, it will add a line break between my imports from node_modules.

Actual behavior

import React from 'react'

import classnames from 'classnames'

Expected behavior

import React from 'react'
import classnames from 'classnames'

For the moment, if you want to importOrderSeparation, there is no way of configuring import groups. I think it could be awesome if we could specify in the configuration where is the line breaking.

Possible solution

Create a configuration like:

{
  "importOrder": [
    // no line breaking if specified in a sub-array
    ["^react", "^(?!react)\\w+$"],
    "^[./]"
  ]
}

We could event remove the importOrderSeparation option because this way will allow you to put everything in the same block:

{
  "importOrder": [
    // no line breaking if specified in a sub-array
     [
       "^react", 
       "^(?!react)\\w+$", 
       "^[./]"
     ]
  ]
}

I'll be glad to PR this ;)

Related to #1 & #7

Duplicate imports when regexes collide.

Hello!

For given config:

{
  "importOrder": ["^(.*)$", "^[./]"],
  "importOrderSeparation": true
}

prettier-plugin-sort-imports produces the same line multiple times. Not just that but for every other clashing regex it writes the matching lines again.

Not sure what the expected behavior would be, but it definitely is not creating multiple imports.

One way to deal with this would be to start from the end and remove anything that has already been marked as used, so that for the above case, relative imports ./ would be at the end, end after that they wouldn't be re-inserted to the start of the list to be written. That way the import order would be decided.

Given my above idea, it might also be better to allow the end user -in the config file with something like importIgnoreClashingRegexOrder: "normal"|"reverse"- to decide which way to start parsing from, shouldn't be hassle to change since all the library would do in that case would be to reverse the list.

`importOrder` seems to ignore `$`

Hi,

with a sort order like this:

    "importOrder": [
      "^react$",
      "^[./@]",
      "^@"
    ]

I get the following result:

import { useDispatch, useSelector } from "react-redux";

import React from "react";

I would expect to get it sorted like this:

import React from "react";

import { useDispatch, useSelector } from "react-redux";

Material UI Theme Object raising unsolvable error

When using MaterialUI in a react application, we can set custom theme object in this way:

import { Theme } from '@material-ui/core';
const commonMUITheme = <Theme>{
    typography: {
        fontFamily: 'Inter',
    },
};

However, on adding @trivago/prettier-plugin-sort-import to the project, the following error occurs:

image

We have tried searching for a similar error in the issues or tweaking the experimentalBabelParserPluginsList configuration to no avail.

Other than this one specific problem with the Theme object from MaterialUI, there are no issues with explicit typecasting.

Is this a problem with the MaterialUI Theme type, because no error is being thrown without this plugin activated.

Fails to format when await used in try block

prettier 2.2.1
sort-imports 1.4.1
node 14.15.4
Archlinux

Input:

try {
    result = await test();
} catch (e) {
  result = false;
}

Without this plugin, the above example formats correctly. With this plugin, we get the following error:

[error] prettiertest.js: SyntaxError: Unexpected token, expected ";" (3:19)
[error]   1 | const result;
[error]   2 | try {
[error]   3 |     result = await test();
[error]   4 | } catch (e) {
[error]   5 |   result = false;
[error]   6 | }
[error]   7 | 

Plugin is not loaded when using pnpm

First, thanks for your hard work on this plugin!

When installing dependencies using pnpm and then running prettier I get the warning: Ignored unknown option { importOrder: [...] }.

If I remove node_modules, install dependencies with npm, and then run prettier, the files are formatted as expected.

Use project babel config when available

In our project we have a pretty complex babel setup. It would be nice if this plugin parsed our code with our babel setup rather than a pre determined setup.

Some files in our project cannot be parsed by the config that is hard coded as:

 const ast = parser(code, {
        sourceType: 'module',
        plugins: ['typescript', 'jsx'],
});

This causes prettier to throw an error, which blocks our CI pipe, so for the time being we have had to remove this plugin

Support // prettier-ignore

Is it possible to support // prettier-ignore comment? So marked import won't be reordered, e.g.

// prettier-ignore
import './polyfills';

import foo from 'foo'

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.