Skip to content

ReferenceError: require is not defined #33741

Description

@jibrail-idris

What steps will reproduce the bug?

  1. Download LTS 12.18.0 from https://nodejs.org/dist/v12.18.0/node-v12.18.0-linux-x64.tar.xz
  2. Untar compressed file
  3. Save a js file with the following code: (Let's called it test.js)
    console.log(require)
  4. Run //node-v12.18.0-linux-x64/bin/node test.js
  5. Node returns error output stating that require is not defined.

How often does it reproduce? Is there a required condition?

All the time.

What is the expected behavior?

The behavior should be similar to node executing the same one liner in REFL interactive shell.

$ node
Welcome to Node.js v12.18.0.
Type ".help" for more information.
> console.log(require)
[Function: require] {
  resolve: [Function: resolve] { paths: [Function: paths] },
  main: undefined,
  extensions: [Object: null prototype] {
    '.js': [Function],
    '.json': [Function],
    '.node': [Function]
  },
  cache: [Object: null prototype] {}
}

What do you see instead?

$ node test.js
(node:13608) ExperimentalWarning: The ESM module loader is experimental. file:///somedirectory/test.js:1 console.log(require); ^ ReferenceError: require is not defined

Additional information

The issue does not happen in older node versions. See text output below

$ node --version
v8.10.0
$ node test.js
{ [Function: require]
  resolve: { [Function: resolve] paths: [Function: paths] },
  main:
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: '/somedirectory/test.js',
     loaded: false,
     children: [],
     paths:
      [ '/somedirectory/node_modules',
      ...,
      ...,
        '/node_modules' ] },
  extensions: { '.js': [Function], '.json': [Function], '.node': [Function] },
  cache:
   { '/somedirectory/test.js':
      Module {
        id: '.',
        exports: {},
        parent: null,
        filename: '/somedirectory/test.js',
        loaded: false,
        children: [],
        paths: [Array] } } }

Activity

  1. richardlau commented on Jun 5, 2020

    @richardlau
    Member

    cc @nodejs/modules-active-members

  2. benjamingr commented on Jun 5, 2020

    @benjamingr
    Member

    Hey thank you for the report and engaging, this is actually intentional. You cannot require from an ESM module - you need to use createRequire :]

    import { createRequire } from 'module';
    const require = createRequire(import.meta.url);
    // can now use `require` in an ESM

    See this section in the docs regarding why and how to work around it.

    (I'm closing since I don't think this is a bug - as usual, if anyone feels strongly feel free to reopen)

  3. hybrist commented on Jun 5, 2020

    @hybrist
    Contributor

    Can you verify that this happens in any directory? By default a .js file shouldn’t be treated as a module. I suspect that you may be in a directory (or nested directory below) where a package.json has a “type” field set to “module”.

  4. benjamingr commented on Jun 5, 2020

    @benjamingr
    Member

    BTW: Apologies, I somehow missed that OP did not realize they were running inside module context 🙏 Thanks for the comment Jan.

  5. BridgeAR commented on Jun 5, 2020

    @BridgeAR
    Member

    Let's reopen for now.

  6. jibrail-idris commented on Jun 5, 2020

    @jibrail-idris
    Author

    @jkrems You are right. The module "type" was causing the issue. Thank you for flagging that out.

  7. GeoffreyBooth commented on Jun 5, 2020

    @GeoffreyBooth
    Member

    We could perhaps expand the error message to include something like “file.js is loaded as an ES module due to /path/to/package.json containing "type": "module"”

  8. jibrail-idris commented on Jun 6, 2020

    @jibrail-idris
    Author

    We could perhaps expand the error message to include something like “file.js is loaded as an ES module due to /path/to/package.json containing "type": "module"”

    Yes. That will be very helpful!

  9. benjamingr commented on Jun 6, 2020

    @benjamingr
    Member

    Let's reopen it the meantime for the error message improvement.

  10. juanarbol commented on Jun 16, 2020

    @juanarbol
    Member

    I could work on this

  11. baselsoftwaredev commented on Oct 9, 2020

    @baselsoftwaredev

    Thanks for this thread, was facing the same issue. More precise error message would definitely help people.

  12. 13 remaining items

  13. reuben4310 commented on Jun 23, 2021

    @reuben4310

    Hey thank you for the report and engaging, this is actually intentional. You cannot require from an ESM module - you need to use createRequire :]

    import { createRequire } from 'module';
    const require = createRequire(import.meta.url);
    // can now use `require` in an ESM

    See this section in the docs regarding why and how to work around it.
    (I'm closing since I don't think this is a bug - as usual, if anyone feels strongly feel free to reopen)

    Thanks so much, I was having this issue using a type:module in package.json but now it's working thanks to your solution.

    Not working for me

  14. iva2k commented on Jul 29, 2021

    @iva2k

    There's an interesting problem with node checking package.json for type: module when a package is built with a help of a script which is run by node, e.g.:

    package.json
    	...
    	"type": "module",
    	"scripts": {
    		"build": "npm run increment && ...",
    		"increment": "node scripts/increment_version.js",
    	...

    Then node throws the error "ReferenceError: require is not defined" inside the scripts/increment_version.js. Removing "type": "module", line removes the error, however, the resulting package is not correct as it needs "type": "module", in package.json.

    Is there a work-around for that? If not, then please reopen this issue to fix for the normal use of js scripts in package build time.

  15. ljharb commented on Jul 29, 2021

    @ljharb
    SponsorMember

    @iva2k either name the script .cjs, or better, remove type entirely and name your ESM files as .mjs.

  16. iva2k commented on Jul 29, 2021

    @iva2k

    @ljharb - not my package, it is existing github repo I cloned and plan PR to add a feature. Changing whole build setup (which involves CI and CD) and renaming all files in the package is very steep price to pay. Is there a better fix, e.g. I'm pondering to add package.json file without "type: module" to scripts/ dir.

  17. ljharb commented on Jul 29, 2021

    @ljharb
    SponsorMember

    @iva2k that's another option (specifically, you'd need scripts/package.json to have "type": "commonjs"), but in a type:module package, you might as well use .cjs for your CJS files.

  18. iva2k commented on Jul 29, 2021

    @iva2k

    It turns out an empty {} package.json in scripts/ solved that particular problem. I added "type: common" to be more specific, and that is clean enough workaround for this situation, works too.

    Anyhow, it seems too far-fetched conclusion that node makes based on package.json contents. What is its rationale?

  19. iva2k commented on Jul 29, 2021

    @iva2k

    I jumped to conclusion too early that stub package.json works. Now npm run build fails in another .js file, now it is failing in node_modules, log snippet:

    > webpack -p --env.production
    
    ./node_modules/webpack-cli/bin/cli.js:93
    				throw err;
    				^
    
    Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./webpack.config.js
    

    Throwing package.json files around node_modules tree is not an easy workaround.
    Also chasing few hundred package maintainers trying to convince them to rename all their .js files sounds like a terrible idea.

  20. ljharb commented on Jul 29, 2021

    @ljharb
    SponsorMember

    type in a package.json only affects that package's boundary. If you have type module, a webpack config probably needs to be named .cjs also.

  21. iva2k commented on Jul 29, 2021

    @iva2k

    webpack-cli does not seem to find .cjs config file.

    So the summary:
    In a "type: module" package should not even try calling any of commonly used cli devDependencies, like webpack-cli - they will all break because node now infers that all .js executed are type: module based on project's package.json.
    what a pickle!

  22. ljharb commented on Jul 29, 2021

    @ljharb
    SponsorMember

    unfortunately type module causes nothing but problems ¯\_(ツ)_/¯

  23. iva2k commented on Jul 29, 2021

    @iva2k

    so module npm packages are a bad idea

    what is the node's changelog that brought this change?
    (this problematic project's travis.yml has "node_js: - '11'", and I have global node v12.20.0)

  24. aduh95 commented on Jul 29, 2021

    @aduh95
    Contributor

    The rationale was to allow users to write ES modules using .js as file extension. In the browser, we can use <script type="module"> to tell the JS engine to parse the file as an ES module rather than a script, it was decided that using package.json would be the Node.js equivalent of that.

    For your particular issue, here's the solutions that could work:

    • Remove "type": "module" from the package.json and use the .mjs extension for all ES modules as @ljharb suggested.
    • Rename the Webpack config to webpack.config.cjs and create a webpack.config.js that simply contains export { default } from './webpack.config.cjs';
    • Convert your webpack.config.js to an ES module by hand. You might be able to do that by replacing module.exports with export default and adding this snippet at the top of the file:
      import { createRequire } from 'module';
      import { fileURLToPath } from 'url';
      import { dirname } from 'path';
      const require = createRequire(import.meta.url);
      const __filename = fileURLToPath(import.meta.url);
      const __dirname = dirname(__filename);
  25. reuben4310 commented on Jul 29, 2021

    @reuben4310
  26. benjamingr commented on Dec 27, 2021

    @benjamingr
    Member

    @reuben4310 you are getting the emails because you commented on this post here: #33741 (comment)

    @ArashAmini345 please open a new issue in the help repo https://github.com/nodejs/help/issues :)

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

    errorsIssues and PRs related to JavaScript errors originating in Node.js core.esmIssues and PRs related to the ECMAScript Modules implementation.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions