hermes: Resolving error: property 'require' doesnt exist

Bug Description

I am working on benchmarking some javascript across different js engines. I have a single js file and I am running on node and hermes. The benchmark script reads in some data and runs a loop. I read in json data (its just an array of data) to an Object with require but hermes is saying that require does not exist. Am I missing something here about how hermes works?

Hermes version: output from hermes --version

LLVM (http://llvm.org/):
  LLVH version 8.0.0svn
  Optimized build

Hermes JavaScript compiler and Virtual Machine.
  Hermes release version: 0.12.0
  HBC bytecode version: 91

  Features:
    Debugger
    Zip file input

React Native version (if any): N/A OS version (if any): macOS 13.0 Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64): m1 Macbook

Steps To Reproduce

  1. Following the release installation instructions here
  2. Create the following script:
// forLoop.js

const data = require(process.env.DATA);

for (let i = 0; i < data.length; i++) {
    continue;
}
  1. Run hermes benchmark.js
  2. See the following output:
hermes forLoop.js
Uncaught ReferenceError: Property 'require' doesn't exist
    at global (forLoop.js:3:14)

code example:

The Expected Behavior

The code runs

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 17 (7 by maintainers)

Most upvoted comments

FWIW, you can enable CommonJS mode in Hermes by passing the --commonjs flag. This will enable require, as well as a subset of ES6 module support, but even then you won’t be able to “require” JSON data.

@matthewmturner just run Node and Hermes with an empty file, measure the startup time and subtract it after from the real measurement. When testing Hermes, don’t forget to run precompiled bytecode.

@matthewmturner you are measuring Node’s startup time, even if you run the same test with an empty .js file, you will get similar numbers. Hermes is indeed optimized for very fast startup, especially when running from precompiled bytecode. But for actual sustained performance for computation tasks, you will find v8 (NodeJS) much faster, perhaps 10x.

@ljharb yes, the Hermes CommonJS/mini-ESM implementation is different from Node’s, it aims to be completely static, i.e. all sources must be passed to the compiler at the same time and are resolved at compile time. There is technically nothing preventing us from supporting JSON files, but:

  1. At the time we didn’t even realize it was needed, IIRC, the CommonJS “spec” didn’t mention it.
  2. Since it is completely static, it is easy enough to just prepend module.exports = and use require as normal.
  3. Nobody actually uses the Hermes CommonJS implementation in production, since React Native has its own bundlers…