prettier-plugin-sort-imports icon indicating copy to clipboard operation
prettier-plugin-sort-imports copied to clipboard

Cannot resolve @ianvs/prettier-plugin-sort-imports (noop.js error) after cleaning node_modules

Open craftzcode opened this issue 10 months ago • 1 comments

Your Environment

  • Prettier version: ^3.5.2
  • node version: 23.7.0
  • package manager: [email protected]
  • IDE: Windsurf

Describe the bug

When using a shared Prettier configuration (in my case within a Turborepo setup) that includes @ianvs/prettier-plugin-sort-imports, everything works fine until I run cleaning scripts that remove all node_modules. After cleaning, even though I reinstall dependencies, running Prettier (via pnpm run format) results in an error that mentions a noop.js file. It appears that Prettier cannot locate the plugin module, even though it is listed as a dependency in my shared config.

To Reproduce

  1. Set up a Turborepo with a shared Prettier config package (e.g. @craftzcode/prettier-config) that includes:

    • @ianvs/prettier-plugin-sort-imports and prettier-plugin-tailwindcss in its dependencies.
    • A config file (index.js) exporting the Prettier configuration with a plugins array including the sort imports plugin.
  2. In one of the consuming packages (e.g. @craftzcode/ui), reference the shared config using the "prettier": "@craftzcode/prettier-config" field in package.json.

  3. Run the cleaning scripts:

pnpm run clean
pnpm run clean:workspaces

(These scripts run git clean -xdf .cache .turbo node_modules.)

  1. Reinstall dependencies using:
pnpm install
  1. Run the formatting command:
pnpm run format
  1. Observe the error referencing noop.js from @ianvs/prettier-plugin-sort-imports.

Expected behavior

Prettier should correctly resolve and load the @ianvs/prettier-plugin-sort-imports plugin even after cleaning and reinstalling dependencies, without error.

Screenshots, code sample, etc

Shared Prettier Config (@craftzcode/prettier-config/index.js):

/** @typedef {import("prettier").Config} PrettierConfig */
/** @typedef {import("@ianvs/prettier-plugin-sort-imports").PluginConfig} SortImportsConfig */
/** @typedef {import("prettier-plugin-tailwindcss").PluginOptions} TailwindConfig */

/** @type {PrettierConfig | SortImportsConfig | TailwindConfig} */
const config = {
  arrowParens: 'avoid',
  bracketSpacing: true,
  endOfLine: 'lf',
  jsxSingleQuote: true,
  singleQuote: true,
  semi: false,
  tabWidth: 2,
  trailingComma: 'none',
  plugins: [
    '@ianvs/prettier-plugin-sort-imports',
    'prettier-plugin-tailwindcss'
  ],
  importOrder: [
    '^(react/(.*)$)|^(react$)',
    '',
    '^(next/(.*)$)|^(next$)',
    '',
    '^(react-native(.*)$)',
    '^(expo(.*)$)|^(expo$)',
    '',
    '<THIRD_PARTY_MODULES>',
    '',
    '^(@trpc/(.*)$)|^(@trpc$)|^(@tanstack/(.*)$)|^(@tanstack$)',
    '',
    '^(drizzle-orm/(.*)$)|^(drizzle-orm$)|^(@/db/(.*)$)|^(@/db$)',
    '',
    '^@craftzcode/api/(.*)$',
    '',
    '^@craftzcode/db/(.*)$',
    '',
    '^@craftzcode/auth/(.*)$',
    '',
    '@/modules(.*)$',
    '',
    '^@/features/(.*)$',
    '',
    '^@/lib/(.*)$',
    '',
    '^@/hooks/(.*)$',
    '',
    'react-hook-form$',
    'zod$',
    '@hookform$',
    '',
    '^@craftzcode/ui/(.*)$',
    '^@/components/(.*)$',
    '',
    '^@/public/(.*)$',
    '',
    '^[./]'
  ],
  importOrderSeparation: false,
  importOrderSortSpecifiers: true,
  importOrderBuiltinModulesToTop: true,
  importOrderParserPlugins: ['typescript', 'jsx', 'decorators-legacy'],
  importOrderMergeDuplicateImports: true,
  importOrderCombineTypeAndValueImports: true
}

export default config

Consuming Package (@craftzcode/ui/package.json excerpt):

{
  "prettier": "@craftzcode/prettier-config",
  "devDependencies": {
    "@craftzcode/prettier-config": "workspace:*",
    ...
  }
}

Error log Image

Additional Debugging Notes - The issue only appears after running cleaning scripts (git clean -xdf .cache .turbo node_modules), which removes all installed packages. - Reinstalling dependencies with pnpm install is required after cleaning; however, even after reinstallation, Prettier fails to load the plugin. - Using Prettier version ^3.5.2 with Node 23.7.0 and [email protected]. - The shared config is using ESM ("type": "module" with export default config), and the plugin is correctly listed as a dependency.

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

  • [x] I'm willing to fix this bug 🥇

craftzcode avatar Feb 24 '25 03:02 craftzcode

Does this still happen with only prettier-plugin-tailwindcss? This sounds to me like a compatibility issue between pnpm and prettier, or a bug in pnpm!

It sounds like when you do something, it successfully works, but only after you hard-reset and pnpm install does something go weird?

fbartho avatar Feb 24 '25 07:02 fbartho

It is an issue with pnpm, I also faced this issue when I tried upgrading pnpm to 10

https://github.com/pnpm/pnpm/issues/5716

For some reason, it refused to install sub deps(I've this package listed as my company shared config package deps)

marklai1998 avatar Mar 16 '25 04:03 marklai1998

I don't know if you guys are still having this problem, but adding this configuration to .npmrc seems to fix it:

node-linker=hoisted
link-workspace-packages=true

As per pnpm documentation you use the pnpm-workspace.yaml set the same configuration too: https://pnpm.io/settings

bruwyvn avatar Apr 17 '25 14:04 bruwyvn

I've spent a full day around this sh*tty problem and resources where sparse and not coherent.

The reason that things completely breaks in v10, is that the default for public-hoist-pattern was ['*eslint*', '*prettier*'], enabling prettier to load all the plugins correctly. Credits to this hero.

I don't know why they removed the default (https://github.com/pnpm/pnpm/issues/8378) if prettier is not able to function properly, but setting it again for prettier resolved my problem:

public-hoist-pattern[]=*prettier*

I prefer this approach to the node-linker=hoisted used above because it doesn't mess with the structure of other dependencies.

loky-lp avatar Jun 16 '25 15:06 loky-lp

THANKS @loky-lp !! This fixed the problem for me as well :) I don't want global hoisting either, so this worked for me. For reference, here is the configuration key that I used in pnpm-workspace.yaml:

publicHoistPattern:
  - "*prettier*"

djbalin avatar Jul 31 '25 09:07 djbalin