IanVS / prettier-plugin-sort-imports

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

Weird issue when formating Next Page components #132

Closed SalahAdDin closed 3 months ago

SalahAdDin commented 1 year ago

Your Environment

Describe the bug When trying to format the page.tsx files on my NextJS 13 project (with the app routing page), it fails terribly.

To Reproduce

const { NEXT_PUBLIC_DOMAIN } = process.env; const { date: dateUtils } = utils;

- Save it.
- Format it.
- Check the error. 

<!-- IMPORTANT:
 - How to reproduce the issue
 - Steps to reproduce the issue
-->

**Expected behavior**

As it happens when we formatted in other files, all import should be ordered without any fail.

<!-- A clear and concise description of what you expected to happen. -->

**Screenshots, code sample, etc**

<!-- If applicable, add screenshots to help explain your problem.  -->

**Configuration File (cat .prettierrc, prettier.config.js, .prettier.js)**
```json
{
  "parser": "typescript",
  "printWidth": 80,
  "arrowParens": "always",
  "semi": true,
  "tabWidth": 2,
  "endOfLine": "auto",
  "trailingComma": "es5",
  "useTabs": false,
  "quoteProps": "consistent",
  "bracketSameLine": true,
  "plugins": [
    "@ianvs/prettier-plugin-sort-imports",
    "prettier-plugin-tailwindcss"
  ],
  "importOrder": [
    "<BUILTIN_MODULES>",
    "",
    "^(^react$|@react|react)",
    "",
    "<THIRD_PARTY_MODULES>",
    "",
    "^@(.*)$",
    "",
    "^[./]"
  ],
  "importOrderParserPlugins": ["importAssertions", "typescript", "jsx"],
  "overrides": [
    {
      "files": ["*.js", "*.cjs", "*.mjs"],
      "options": {
        "parser": "meriyah"
      }
    },
    {
      "files": ["*.ts", "*.cts"],
      "options": {
        "parser": "typescript"
      }
    },
    {
      "files": ["*.json", "*.jsonc", ".*rc"],
      "options": {
        "parser": "json"
      }
    },
    {
      "files": "*.css",
      "options": {
        "parser": "css"
      }
    }
  ]
}

Error log

> prettier src  --check "--write"

Checking formatting...
src/app/news/[...path]/page.tsx
[error] src/app/news/[...path]/page.tsx: TypeError: Cannot read properties of undefined (reading 'buildError')
[error]     at Scope.checkBlockScopedCollisions (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:399:22)
[error]     at Scope.registerBinding (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:535:16)
[error]     at Scope.registerDeclaration (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:487:14)
[error]     at Object.BlockScoped (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:254:12)
[error]     at Object.newFn (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/visitors.js:192:17)
[error]     at NodePath._call (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/path/context.js:46:20)
[error]     at NodePath.call (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/path/context.js:32:14)
[error]     at NodePath.visit (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/path/context.js:82:31)
[error]     at TraversalContext.visitQueue (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/context.js:86:16)
[error]     at TraversalContext.visitMultiple (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/context.js:61:17)
[warn] src/app/news/components/NewsCard.test.tsx
[warn] src/app/news/components/NewsCard.tsx
[warn] src/app/news/components/NewsList.tsx
[warn] src/app/news/components/Pagination.tsx
src/app/news/page.tsx
[error] src/app/news/page.tsx: TypeError: Cannot read properties of undefined (reading 'buildError')
[error]     at Scope.checkBlockScopedCollisions (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:399:22)
[error]     at Scope.registerBinding (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:535:16)
[error]     at Scope.registerDeclaration (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:480:12)
[error]     at Object.BlockScoped (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/scope/index.js:254:12)
[error]     at Object.newFn (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/visitors.js:192:17)
[error]     at NodePath._call (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/path/context.js:46:20)
[error]     at NodePath.call (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/path/context.js:32:14)
[error]     at NodePath.visit (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/path/context.js:82:31)
[error]     at TraversalContext.visitQueue (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/context.js:86:16)
[error]     at TraversalContext.visitSingle (/home/luisalaguna/Projects/challenge-trt/node_modules/.pnpm/@babel+traverse@7.23.0/node_modules/@babel/traverse/lib/context.js:65:19)
[warn] Code style issues fixed in 4 files.
 ELIFECYCLE  Command failed with exit code 2.
 ELIFECYCLE  Command failed with exit code 1.

Contribute to @ianvs/prettier-plugin-sort-imports

IanVS commented 1 year ago

Thanks for the report, @SalahAdDin. Would you be willing to create a minimal reproduction repo that we can take a look at?

venerated commented 9 months ago

I had this same issue, not sure if the exact same error as I didn't print the error message, but I started creating a minimal reproduction repo and did not have the error there. Seemingly, closing VS Code and reopening it fixed the issue. 🙈

SalahAdDin commented 9 months ago

Thanks for the report, @SalahAdDin. Would you be willing to create a minimal reproduction repo that we can take a look at?

I will check it as soon as possible.

yuma-brendan commented 8 months ago

We were seeing the same issue, and (for us) this is caused by importing a typescript type with the same name as the default export

Minimal reproduction (the failures.ts file doesn't need to exist)

import { Failure } from './failures'; // <------ Causes erorr because of a name collision, even though this is valid TS 
const Failure = ({}) => {
  return (
    <>
    </>
  );
};

export default Failure;

pnpm exec prettier --write --ignore-unknown --no-error-on-unmatched-pattern "app/lib/Failure.tsx"

app/lib/Failure.tsx
[error] app/lib/Failure.tsx: TypeError: Cannot read properties of undefined (reading 'buildError')
[error]     at Scope.checkBlockScopedCollisions (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/scope/index.js:399:22)
[error]     at Scope.registerBinding (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/scope/index.js:535:16)
[error]     at Scope.registerDeclaration (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/scope/index.js:487:14)
[error]     at Object.BlockScoped (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/scope/index.js:254:1
[prettierrc.json](https://github.com/IanVS/prettier-plugin-sort-imports/files/14070107/prettierrc.json)
2)
[error]     at Object.newFn (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/visitors.js:195:17)
[error]     at NodePath._call (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/path/context.js:46:20)
[error]     at NodePath.call (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/path/context.js:32:14)
[error]     at NodePath.visit (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/path/context.js:82:31)
[error]     at TraversalContext.visitQueue (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/context.js:86:16)
[error]     at TraversalContext.visitMultiple (/home/xrendan/dev/yuma/nextjs-dashboard/node_modules/.pnpm/@babel+traverse@7.23.9/node_modules/@babel/traverse/lib/context.js:61:17)

package.json .prettierrc.json

IanVS commented 3 months ago

@yuma-brendan that is only valid typescript when isolatedModules is not enabled. The problem is that while tsc runs on your entire codebase and understands that the Failure being imported is a type, prettier (and many other tools) only run on a per-file basis. So, in your example they have no way of knowing whether Failure is a type or value.

I'd recommend enabling isolatedModules or even better verbatimModuleSyntax, and using https://typescript-eslint.io/rules/consistent-type-imports/ to make sure that all of your type-only imports use the type keyword.

Unfortunately, there's nothing we can do on our end to address this.

SalahAdDin commented 3 months ago

@yuma-brendan that is only valid typescript when isolatedModules is not enabled. The problem is that while tsc runs on your entire codebase and understands that the Failure being imported is a type, prettier (and many other tools) only run on a per-file basis. So, in your example they have no way of knowing whether Failure is a type or value.

I'd recommend enabling isolatedModules or even better verbatimModuleSyntax, and using https://typescript-eslint.io/rules/consistent-type-imports/ to make sure that all of your type-only imports use the type keyword.

Unfortunately, there's nothing we can do on our end to address this.

We have the default behaviour on the linter and the those options in tsconfig and yet we have the issue.

No way to fix it, right?

IanVS commented 3 months ago

If you have that option set in tsconfig then the code shared would not compile. Can you share a minimal reproduction that shows your uissue?