IanVS / prettier-plugin-sort-imports

An opinionated but flexible prettier plugin to sort import statements
Apache License 2.0
951 stars 21 forks source link

Sorting not working with nameless imports #110

Closed 413n closed 1 year ago

413n commented 1 year ago

Your Environment

Describe the bug

I'm working with NextJS in the new App Router and I really like the package "server-only" that assures some files are ran only on server side. The problem I'm encountering is that adding "server-only" in the importOrders array is not working. I think the problem is about how the package is imported: import "server-only"; Without a "name" of the import, it's not sorted. In fact, if I try to import it like: import serverOnly from "server-only";, it works correctly.

To Reproduce

Import a package that does not require the name and add that name to the importOrder.

Expected behavior

The import should be sorted since the importOrder relies on the path or package name

Configuration File (cat .prettierrc, prettier.config.js, .prettier.js)

prettier.config.cjs

{
  importOrder: [
    "^(server-only$)",
    "^(react/(.*)$)|^(react$)|^(react-native(.*)$)",
    "^(next/(.*)$)|^(next$)",
    "<THIRD_PARTY_MODULES>",
    "^@/lib/(.*)$",
    "^@/components/(.*)$",
    "^@/(.*)$",
    "^[./]",
  ],
  importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"],
  importOrderTypeScriptVersion: "5.1.6",
}
fbartho commented 1 year ago

This is working as expected because that import exists to cause side-effects.

Side effects cannot safely be reordered without potentially causing crashes. Technically, any import could cause a side-effect, but a common heuristic is to assume that side-effects are rare, so we only apply that rule when no “names” are imported from an import declaration.

Note: it would be helpful if you provided an example of the imports you’re trying to sort, but I’m pretty sure I interpreted what you said correctly.

413n commented 1 year ago

Okay that make sense.

My use case is pretty simple. These are sorted imports:

import "server-only";
import { type ReactNode } from "react";
import { FullPage } from "@/components/layout/Page";
import { Container } from "./Container";

but if I move the "server-only" import as last, it stays there even when reformatting:

import { type ReactNode } from "react";
import { FullPage } from "@/components/layout/Page";
import { Container } from "./Container";
import "server-only";

Is another way to achieve the sorting of imports even when nameless? or I have put it manually where I want it to be?

IanVS commented 1 year ago

You'll need to manually put side-effect-only (nameless) imports where you want them manually. Or, there are other prettier plugins which do sort these kinds of imports, despite the dangers of doing so.