Repository navigation
Incompatibility with Node.js v22.12.0: ReferenceError: require is not defined (But Works with v22.11.0) #56155
Description
Activity
- changed the title
[-]Incompatibility with Node.js v22.12.0: ReferenceError: require is not defined[/-][+]Incompatibility with Node.js v22.12.0: ReferenceError: require is not defined (But Works with v22.11.0)[/+]on Dec 6, 2024 Clone the repository.
There doesn't seem to be a repository link in the OP?
This seems similar to #56140 - you may have
"type": "module"in your package.json while having a.jsfile usingrequire, which is technically a bug by the interpretation of Node.js's builtin module loaders, but was probably masked by some toolchain that incorrectly monkey patches Node.js's internals (e.g. missing the third argument of the internal they patched). If you do, solution would be similar to what's mentioned in #56140 (comment) (either rename your config file to usetailwind.config.cjs, or use ESM syntax in your.jsfile)Hey @joyeecheung I am having a similar issue. My code works with v22.11.0, but not with v22.12.0 or v23.3.0.
Here is a minimal reproducible repo:
https://github.com/virtuallyunknown/node-error
# ✅ works nvm use 22.11.0 node build.js # ❌ fails nvm use 22.12.0 node build.js # ❌ fails nvm use 23.3.0 node build.js
Renaming to
.cjsallowsbuild.jsto pass with the following warnings:(node:5485) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. (Use `node --trace-warnings ...` to show where the warning was created) (node:5485) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.But is renaming to
.cjsthe only solution here? I have dozens of projects using build scripts like these, so it's going to be an absolute nightmare renaming each one of them.#56140 explains that you can use ESM syntax in your
tailwind.config.jsfile, but my file is already using ESM syntax:import { fontFamily } from 'tailwindcss/defaultTheme.js'; /** @type {import('tailwindcss').Config} */ export default { content: ['./src/**/*.tsx'], theme: { extend: { fontFamily: { 'inter': ['Inter', ...fontFamily.sans], 'source-code-pro': ['"Source Code Pro"', ...fontFamily.mono], } }, }, }
I am not sure what tailwind does but judging from
but my file is already using ESM syntax
it seems to be monkey patching Node.js CJS loader internals to magically transpile ESM to CJS and maybe writing them to .js files with
"type": "module"in the package.json and introduce glitches. It may be something that can be fixed on tailwind's side, if they are already monkey patching the CJS loader, they could probably be updated to patch the newer CJS loaders internals, er, less incorrectly.Reacted by virtuallyunknownI am not sure what tailwind does but judging from
but my file is already using ESM syntax
it seems to be monkey patching Node.js CJS loader internals to magically transpile ESM to CJS and maybe writing them to .js files with
"type": "module"in the package.json and introduce glitches. It may be something that can be fixed on tailwind's side, if they are already monkey patching the CJS loader, they could probably be updated to patch the newer CJS loaders internals, er, less incorrectly.I think the issue was that I was not using extensionless import. I apologize if my terminology is incorrect.
import { fontFamily } from 'tailwindcss/defaultTheme.js'; // vs import { fontFamily } from 'tailwindcss/defaultTheme';
When I use extensionless import, I only get a warning, but the
build.jsscript works.(node:40614) ExperimentalWarning: CommonJS module /path/to/node-error/node_modules/tailwindcss/lib/lib/load-config.js is loading ES Module /path/to/node-error/tailwind.config.js using require(). Support for loading ES Module in require() is an experimental feature and might change at any time (Use `node --trace-warnings ...` to show where the warning was created)The examples in the tailwind docs also use extensionless imports (although their example is CJS, not sure if that makes any difference), so I think it's probably my own fault here.
I believe extensionless import is also how it's generally called here, yes ;)
When I use extensionless import, I only get a warning, but the build.js script works.
I think that warning should only be on v23 if it's from node_modules, and should not show up on v22 (v23 will have that patch later). Is this on v23? If it's from v22 that might be a bug.
Anyway, my speculation is that when you use extensionless import, you are writing faux ESM instead of native ESM (Node.js's native ESM does not support extensionless import unless the package specify the target in their export conditions, but I don't see any in tailwindcss's package.json), and maybe tailwindcss's patching generally expects that you write faux ESM when you do write ESM. If somehow your file is loaded just fine by Node.js without erroring, it is somehow not good for them because their patching code won't get a chance to run?
Hey @joyeecheung the warning was on v23.3, but give me ~20 minutes and I will come back with results from 22.12.
Anyway, my speculation is that when you use extensionless import, you are writing faux ESM instead of native ESM (Node.js's native ESM does not support extensionless import unless the package specify the target in their export conditions, but I don't see any in tailwindcss's package.json), and maybe tailwindcss's patching generally expects that you write faux ESM when you do write ESM. If somehow your file is loaded just fine by Node.js without erroring, it is somehow not good for them because their patching code won't get a chance to run?
I am honestly not sure, my understanding on the topic of imports/exports is probably above-average yet still limited, and I haven't written any CJS related code in years (migrated to full ESM long ago). So I have no clue what the folks over at tailwind might be doing.
(Node.js's native ESM does not support extensionless import unless the package specify the target in their export conditions, but I don't see any in tailwindcss's package.json
Yep, I remember reading about this a while ago, so I am not exactly sure how I ended with
.jsimport. It is worth mentioning that 22.11 supports both extension and extensionless, but that is not to say I was writing correct code.I think that warning should only be on v23 if it's from node_modules, and should not show up on v22 (v23 will have that patch later). Is this on v23? If it's from v22 that might be a bug.
Hey again, I can confirm that extensionless
import { fontFamily } from 'tailwindcss/defaultTheme';
on 22.12 does NOT produce any warnings or errors, and neither does 22.11.
And some extra info, 22.11 allows both with no errors or warnings (which is how I was using it before upgrading nodejs today):
import { fontFamily } from 'tailwindcss/defaultTheme'; import { fontFamily } from 'tailwindcss/defaultTheme.js';
Cheers!
Reacted by Joyee Cheung- addedmoduleIssues and PRs related to the module subsystem.Issues and PRs related to the module subsystem.loadersIssues and PRs related to ES module loaders.Issues and PRs related to ES module loaders.
on Dec 6, 2024 - added a commit that references this issue
on Dec 6, 2024 Tailwind uses a module called
jitito load the configuration file: https://github.com/tailwindlabs/tailwindcss/blob/f875ab9706cae8262e15e5b382580fc8e2d4197f/src/lib/load-config.ts#L34-L55That module is doing a lot of complicated things with Node.js internals, so it has probably been broken in some way. See https://github.com/unjs/jiti/blob/ad6191f04624badf2112651217bc17008a9bde50/src/eval.ts for example.
Reacted by virtuallyunknown, Krishna Mohan, Kye Russell and Brian RyuReacted by Théo LUDWIG and ExE Boss- added a commit that references this issue
on Dec 10, 2024 Whoever decided it was a good idea to push this such impactful change into a minor version (in the LTS branch !) clearly didn't think of the pain it is to have to issue a hotfix for builds failing overnight with all the tooling working against you ...
The backport of the semver-minor was requested by many people, so it's not a decision made by any individual but a large group of users and especially package maintainers who look forward to shipping ESM as-is and not having to maintain dual shipping.
The issues here is likely caused by third-party libraries patching/using the Node.js internals, in that case it's already risky business and even some small subtle refactoring of the internals in a semver-patch release can already make you have to push a hotfix to work around their bug. If a third-party library is relying on a bug or how the internals work which there is no stability guarantee for, the issue should be brought to their issue tracker. Otherwise we'll at least need a reproduction that doesn't use any third-party code and doesn't use any undocumented internals to fix anything.
Reacted by Théo LUDWIG, Fotis Papadogeorgopoulos, virtuallyunknown, John Gee and Julian WallerThis seems to be caused by some unreliable assumptions jiti makes about Node.js internals and probably has been fixed in the latest releases of jiti: unjs/jiti#346 (comment)
Reacted by Timo Behrmann and virtuallyunknownClosing since it seems to be fixed elsewhere.
- added a commit that references this issue
on Jan 23, 2025
Version
node v22.12.0(LTS)
Platform
Windows 11 23H2, 64-bit
Node.js v22.12.0
What steps will reproduce the bug?
npm install.npm run dev.How often does it reproduce? Is there a required condition?
The issue consistently reproduces every time the application is run using Node.js v22.12.0.
What is the expected behavior? Why is that the expected behavior?
The application should start without any errors.
What do you see instead?
The application fails with the error:
ReferenceError: require is not defined
const path = require("path");
^
ReferenceError: require is not defined
at file:///path/to/tailwind.config.js:1:14
Additional information
**### ## Compatibility
Node.js Compatibility
- Use Node.js v22.11.0 for a stable experience.
Workaround
To run the project successfully:
Download the Node.js v22.11.0 for a stable experience.
https://drive.google.com/file/d/1fjLXb1xUMowMj3F9FmDt1dw0XJOuYflP/view?usp=sharing