prettier-plugin-tailwindcss: Can't `require()` plugin after upgrading to v0.5.x

What version of prettier-plugin-tailwindcss are you using? v0.5.3

What version of Tailwind CSS are you using? v3.3.3

What version of Node.js are you using? 19.5.0

What package manager are you using? npm

What operating system are you using? Windows 11

Describe your issue I have just updated from v0.4.0 to 0.5.3 and this issue came when we do try to run the site

` ./app/global.css.webpack[javascript/auto]!=!../…/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[2].oneOf[13].use[2]!../…/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[2].oneOf[13].use[3]!./app/global.css D:\Development\EmploHub\Emplohub\node_modules\prettier-plugin-tailwindcss\dist\index.mjs:4 const require=_module2.createRequire.call(void 0, import.meta.url) ^

SyntaxError: Identifier ‘require’ has already been declared `

We are using NextJs 13.4.19

About this issue

  • Original URL
  • State: closed
  • Created 10 months ago
  • Reactions: 9
  • Comments: 33 (9 by maintainers)

Most upvoted comments

Hey everyone! In general what I’m seeing here can be explained by users either calling require("prettier-plugin-tailwindcss") or importing the plugin in the wrong place.

This plugin, as of v0.5, requires Prettier v3+ and is now ESM-only. Let’s discuss the upgrade path from v0.4 to v0.5+, some scenarios that you might’ve run into, and the reasons behind the change:

Upgarding to v0.5+

Overview

First, prettier-plugin-tailwindcss v0.5 requires a minimum of Prettier v3. Supporting both versions of Prettier is, unfortunately, not possible in a single version of our plugin.

This means that:

  • All plugins you are using MUST be listed in your prettier config
  • You will get an error when trying to use prettier-plugin-tailwindcss v0.5 with Prettier v2
  • Any tooling you use MUST also be upgraded to support Prettier v3 they have not done so already — whether it be the Prettier VS Code extension, eslint-plugin-prettier, or other tools.

Second, prettier-plugin-tailwindcss is now ESM-only.

This means that:

  • You MUST specify it in your Prettier Config as a string 'prettier-plugin-tailwindcss'
  • You CANNOT require() — doing so will result in errors about being unable to require() an ES Module.
  • You CANNOT import it in a file that is compiled to Common JS.

How to upgrade

If you have not done so — first upgrade to Prettier v3. Then proceed with the rest of this guide.

I do not have a prettier config

In Prettier v2 plugins could be autoloaded. This worked by following a naming convention for a package — any package name starting with prettier-plugin- was automatically lodaded by Prettier unless autoloading was disabled. This did not work well with certain package managers and the feature was removed in Prettier v3. Now you MUST create a prettier config listing all plugins you want to use. To migrate you will need to create a prettier.config.js file containing the following:

// prettier.config.js

module.exports = {
  plugins: ['prettier-plugin-tailwindcss'],
}

My prettier config is in package.json

It’s likely you won’t need to change anything but you’ll want to make sure that prettier-plugin-tailwindcss is present in your plugins list — and be sure it is listed last if you are using multiple plugins:

// package.json

{
  // …
  "prettier": {
    "plugins": [
      "prettier-plugin-tailwindcss"
    ]
  }
}

I am not using import or require() in my prettier config file

If you’re using the string prettier-plugin-tailwindcss directly as a plugin name you do not need to change anything

Before and after:

// prettier.config.js

module.exports = {
  plugins: ['prettier-plugin-tailwindcss'],
}

I am using require() in my prettier config file

You will need to replace require('prettier-plugin-tailwindcss') with 'prettier-plugin-tailwindcss':

Before:

// prettier.config.js

module.exports = {
  plugins: [require('prettier-plugin-tailwindcss')],
}

After:

// prettier.config.js

module.exports = {
  plugins: ['prettier-plugin-tailwindcss'],
}

I am calling import in my prettier config file

This is not a typical situation that is/was supported by Prettier. But, on the chance that you do have a setup that looks like this you will need to remove the import for the package and put 'prettier-plugin-tailwindcss' directly in your plugin list:

Before:

// prettier.config.js

import tailwindcssPlugin from 'prettier-plugin-tailwindcss'

export default {
  plugins: [tailwindcssPlugin],
}

After:

// prettier.config.js

export default {
  plugins: ['prettier-plugin-tailwindcss'],
}

I’m still seeing errors

If you’ve gone through the above list and are still seeing errors:

Error [ERR_REQUIRE_ESM]: require() of ES Module …

This means that you still have a call to require("prettier-plugin-tailwindcss") somewhere in your code. Probably in a config file. In this situation you’ll want to track down the file with the require and remove it. Additionally, if it was in a prettier config — add 'prettier-plugin-tailwindcss' to the end of the plugin list.

SyntaxError: Identifier 'require' has already been declared

This is probably happening because you’re calling require("prettier-plugin-tailwindcss") in your Tailwind config file (tailwind.config.js, tailwind.config.cjs, tailwind.config.mjs, tailwind.config.ts).

This package is NOT a Tailwind CSS plugin. It is a Prettier plugin for Tailwind CSS. As such you should remove require("prettier-plugin-tailwindcss") from your Tailwind config, and remove any reference to the prettier plugin from your Tailwind plugins list. Additionally, if you’re using import plugin from "prettier-plugin-tailwindcss" in your Tailwind CSS file you should also remove that.

No references to this plugin need to exist in your Tailwind CSS config file.

I’m still seeing the above but it’s not in my Tailwind CSS config file

This likely means that the above is true but for your application code. You do NOT need to require() or import this plugin in your application code. This plugin is a development-time or build-time tool.

In this situation, the result is the same: You should remove any references to require("prettier-plugin-tailwindcss") or import plugin from "prettier-plugin-tailwindcss" or import "prettier-plugin-tailwindcss" from your application code.

My project requires Prettier v2

If your project’s dependencies or situation preclude you from upgrading Prettier itself then you may continue to use Prettier v2 alongside version v0.4.x of our plugin. This may be the case especially if you require the use of prettier-plugin-marko or prettier-plugin-twig-melody as, at the time of this writing, neither plugin has been updated for Prettier v3.

Why things changed

So, prettier-plugin-tailwindcss is ESM-only now. Why?

Prettier v3 moved to using dynamic imports to load plugins. This means that other plugins may be written and published as ESM-only. Unfortunately, this means that we ALSO must use dynamic imports to load third-party plugins that we support.

Our plugin works by loading built-in and third-party plugins, re-defining their parsers, and defering back to the original parser before sorting classes. In CJS environments this was fairly simple as a require() call is synchronous and can be dynamic. The problem is that these calls don’t support loading ESM plugins. So, in ESM environments the only way to achieve this is to use a dynamic import() which returns a promise. However, Prettier itself loads plugins asynchronously but expects parsers, printers, etc… to be defined synchronously by the time the plugin has been imported.

To work around this we figure out what plugins you have installed in your node_modules and load them using a dynamic import. When then use a ESM-only feature called Top-Level Await. This feature allows us to delay initialization of the entire module until all supported third-party plugins have been checked for and loaded when available. After loading these plugins we keep a reference around such that, at the appropriate time, we can load the plugin’s original parser to call into it before sorting classes.

Couldn’t you provide a dual CJS/ESM build?

Sadly, no. While we could support built-in plugins in a CJS bundle, third-party plugin support wouldn’t be possible in a CJS build for some plugins. This is entirely based on whether or not the third-party plugin was CJS or ESM itself. Additionally, some tools like the Prettier VS Code extension do not load the ESM version of a package unless it’s ESM-only because it uses require.resolve internally which will always pick the CJS build if one is available. This means that third-party support would be completely broken in VS Code but not the CLI. Given that it’s such a popular editor we consider this a non-starter.

The side-effect of these last two points is that a CJS build of this plugin is no longer possible.

@buhlerfanny You should use just the plugin name without require():

// prettier.config.js
module.exports = {
  plugins: ["prettier-plugin-tailwindcss"],
};

This plugin now requires Prettier v3+

i had 2.8.8, so updating to v3 fixed the issue

plugins: [“prettier-plugin-tailwindcss”],

Same, cannot run from VSCode.

Doesn’t work for me. If I rename my file to .prettierrc then I can npm run lint but the prettier-plugin-tailwindcss just doesn’t work. And If I rename it to .prettier.config.js it’s the opposite: I can’t run npm run lint but the plugin work.

Note: When I run npm run lint I get this error:

Oops! Something went wrong! :(

ESLint: 8.54.0

Error [ERR_REQUIRE_ESM]: require() of ES Module /home/project/node_modules/prettier-plugin-tailwindcss/dist/index.mjs not supported.
Instead change the require of /home/project/node_modules/prettier-plugin-tailwindcss/dist/index.mjs to a dynamic import() which is available in all CommonJS modules.
Occurred while linting /home/project/.eslintrc.js:4
Rule: "prettier/prettier"

weird

Having a similar issue, here’s my prettier.config.js:

/** @type {import("prettier").Config} */
module.exports = {
  "plugins": ["prettier-plugin-svelte", 'prettier-plugin-tailwindcss',  "@trivago/prettier-plugin-sort-imports"],
  "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }],
  "printWidth": 160,
  "useTabs": true,
  "trailingComma": "all",
  "singleQuote": true,
  "semi": true,
  "importOrder": ["<THIRD_PARTY_MODULES>", "^@/(.*)$", "^$env/(.*)$", "^[./]"],
  "importOrderSeparation": true,
  "importOrderSortSpecifiers": true
};

I’m using the prettier plugin from VSCode, here’s the error:

["ERROR" - 14:34:15] Error handling text editor change
["ERROR" - 14:34:15] require() of ES Module /Users/chiru/.../node_modules/prettier-plugin-tailwindcss/dist/index.mjs not supported.
Instead change the require of /Users/chiru/.../node_modules/prettier-plugin-tailwindcss/dist/index.mjs to a dynamic import() which is available in all CommonJS modules.
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/chiru/.../node_modules/prettier-plugin-tailwindcss/dist/index.mjs not supported.
Instead change the require of /Users/chiru/.../node_modules/prettier-plugin-tailwindcss/dist/index.mjs to a dynamic import() which is available in all CommonJS modules.
    at Function.<anonymous> (node:electron/js2c/asar_bundle:2:13327)
    at l._load (/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:173:5635)
    at r._load (/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:170:29791)
    at t._load (/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:135:35292)

@thecrypticace I don’t believe the issue is resolved. I’m also running Prettier v3.2.4

Not sure if it’s related, but I see the following error:

Error [ERR_REQUIRE_ESM]: require() of ES Module /node_modules/prettier-plugin-tailwindcss/dist/index.mjs not supported.
Instead change the require of /node_modules/prettier-plugin-tailwindcss/dist/index.mjs to a dynamic import() which is available in all CommonJS modules.

Here’s the prettier.config.cjs file:

/** @type {import("prettier").Config} */
module.exports = {
  plugins: [require("prettier-plugin-tailwindcss")],
  tailwindConfig: "./tailwind.config.cjs",
};

I’d expect require to work since it’s a .cjs file, unless prettier-plugin-tailwindcss is now ESM-only?

Please check that you’re actually using version >3.0 with prettier --version

You may be running an old Prettier version, even though you locally installed the correct version.

@buhlerfanny You should use just the plugin name without require():

// prettier.config.js
module.exports = {
  plugins: ["prettier-plugin-tailwindcss"],
};

cool worked for me

@designorant The version bump from 0.4.x to 0.5.x does satisfy Semantic Versioning requirements. If we were already at 1.y.z then we would’ve needed to bump to v2.0 but we were not.

It does, and it doesn’t.

SemVer clearly says:

MINOR version when you add functionality in a backward compatible manner

Bump to v0.5.x wasn’t backward compatible as it requires Prettier v3 which comes with major changes.

I appreciate you may consider prettier-plugin-tailwindcss not v1 worthy (something SemVer calls “initial development phase”) and that “anything may change at any time”, but as per my reasoning, the major number is just a number, just like the minor and patch numbers.

There seems to be an industry convention is to keep the major versions low for some reason but major version zero is all about rapid development.

Given this package has 1m+ downloads every week and 200+ dependents bumping it to 1.0.0 would certainly help, especially given the recent changes.

After all:

If your software is being used in production, it should probably already be 1.0.0.

Doesn’t work for me. If I rename my file to .prettierrc then I can npm run lint but the prettier-plugin-tailwindcss just doesn’t work. And If I rename it to .prettier.config.js it’s the opposite: I can’t run npm run lint but the plugin work.

Note: When I run npm run lint I get this error:

Oops! Something went wrong! :(

ESLint: 8.54.0

Error [ERR_REQUIRE_ESM]: require() of ES Module /home/project/node_modules/prettier-plugin-tailwindcss/dist/index.mjs not supported.
Instead change the require of /home/project/node_modules/prettier-plugin-tailwindcss/dist/index.mjs to a dynamic import() which is available in all CommonJS modules.
Occurred while linting /home/project/.eslintrc.js:4
Rule: "prettier/prettier"

weird

Using a .prettierrc configuration file was the issue for me, once I converted the config to prettier.config.js it worked properly

This plugin now requires Prettier v3+

i had 2.8.8, so updating to v3 fixed the issue

This works for me

My prettier.config.js:

// prettier.config.js

plugins: ["prettier-plugin-tailwindcss"],

plugins: ["prettier-plugin-tailwindcss"],

don’t require neither in tailwind.config.js