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)
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:
prettier-plugin-tailwindcss
v0.5 with Prettier v2eslint-plugin-prettier
, or other tools.Second,
prettier-plugin-tailwindcss
is now ESM-only.This means that:
'prettier-plugin-tailwindcss'
require()
— doing so will result in errors about being unable torequire()
an ES Module.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 aprettier.config.js
file containing the following: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:I am not using
import
orrequire()
in my prettier config fileIf you’re using the string
prettier-plugin-tailwindcss
directly as a plugin name you do not need to change anythingBefore and after:
I am using
require()
in my prettier config fileYou will need to replace
require('prettier-plugin-tailwindcss')
with'prettier-plugin-tailwindcss'
:Before:
After:
I am calling
import
in my prettier config fileThis 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:
After:
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 usingimport 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()
orimport
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")
orimport plugin from "prettier-plugin-tailwindcss"
orimport "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
orprettier-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 dynamicimport()
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()
:This plugin now requires Prettier v3+
i had 2.8.8, so updating to v3 fixed the issue
Same, cannot run from VSCode.
Having a similar issue, here’s my
prettier.config.js
:I’m using the prettier plugin from VSCode, here’s the error:
@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:
Here’s the
prettier.config.cjs
file:I’d expect
require
to work since it’s a.cjs
file, unlessprettier-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.
cool worked for me
It does, and it doesn’t.
SemVer clearly says:
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
notv1
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:
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:weird
Using a .prettierrc configuration file was the issue for me, once I converted the config to prettier.config.js it worked properly
This works for me
My
prettier.config.js
:plugins: ["prettier-plugin-tailwindcss"],
don’t require neither in tailwind.config.js