Skip to content

Incompatibility with Node.js v22.12.0: ReferenceError: require is not defined (But Works with v22.11.0) #56155

Description

@Vanakeethan

Version

node v22.12.0(LTS)

Platform

Windows 11 23H2, 64-bit
Node.js v22.12.0

What steps will reproduce the bug?

  1. Install Node.js v22.12.0.
  2. Clone the repository.
  3. Run npm install.
  4. Run 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

  • This project is currently incompatible with Node.js v22.12.0 due to stricter module handling.
    - Use Node.js v22.11.0 for a stable experience.

Workaround

To run the project successfully:

  1. Install Node.js v22.11.0:
    nvm install 22.11.0
    nvm use 22.11.0 
    

Download the Node.js v22.11.0 for a stable experience.

https://drive.google.com/file/d/1fjLXb1xUMowMj3F9FmDt1dw0XJOuYflP/view?usp=sharing

Activity

  1. 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
  2. joyeecheung commented on Dec 6, 2024

    @joyeecheung
    Member

    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 .js file using require, 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 use tailwind.config.cjs, or use ESM syntax in your .js file)

  3. virtuallyunknown commented on Dec 6, 2024

    @virtuallyunknown

    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 .cjs allows build.js to 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 .cjs the 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.js file, 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],
                }
            },
        },
    }
  4. joyeecheung commented on Dec 6, 2024

    @joyeecheung
    Member

    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.

  5. virtuallyunknown commented on Dec 6, 2024

    @virtuallyunknown

    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.

    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.js script 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.

  6. joyeecheung commented on Dec 6, 2024

    @joyeecheung
    Member

    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?

  7. virtuallyunknown commented on Dec 6, 2024

    @virtuallyunknown

    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 .js import. It is worth mentioning that 22.11 supports both extension and extensionless, but that is not to say I was writing correct code.

  8. virtuallyunknown commented on Dec 6, 2024

    @virtuallyunknown

    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!

  9. added
    moduleIssues and PRs related to the module subsystem.
    loadersIssues and PRs related to ES module loaders.
    on Dec 6, 2024
  10. added a commit that references this issue on Dec 6, 2024
  11. targos commented on Dec 7, 2024

    @targos
    Member

    Tailwind uses a module called jiti to load the configuration file: https://github.com/tailwindlabs/tailwindcss/blob/f875ab9706cae8262e15e5b382580fc8e2d4197f/src/lib/load-config.ts#L34-L55

    That 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.

  12. id6tm-mteterel commented on Dec 11, 2024

    @id6tm-mteterel

    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 ...

  13. joyeecheung commented on Dec 11, 2024

    @joyeecheung
    Member

    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.

  14. joyeecheung commented on Dec 17, 2024

    @joyeecheung
    Member

    This 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)

  15. joyeecheung commented on Jan 7, 2025

    @joyeecheung
    Member

    Closing since it seems to be fixed elsewhere.

  16. added a commit that references this issue on Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    loadersIssues and PRs related to ES module loaders.moduleIssues and PRs related to the module subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions