skip to Main Content

I have a Scheme interpreter written in JavaScript called LIPS. It’s all ES Module. But as part of the standard library I’ve created require function that use code like this:

import { createRequire } from 'module';
const require = createRequire(import.meta.url);

But you can’t import esm package with require. So I need to implement import.

The problem is that import is not global variable. For some reason it’s accessible but not in window or global. So to get access it from scheme you need (using JavaScript syntax)

eval("import")("fs")

But eval don’t create ES context and this throw an error:

Uncaught SyntaxError: Cannot use import statement outside a module

I want to know if you can create ES context with eval, so I can access dynamic import with the need to modify the library JavaScript code.

2

Answers


  1. Chosen as BEST ANSWER

    Just found the way to use import with eval:

    await global.eval("(function(x) { return import(x); })")("fs");
    

    or shorter with arrow function:

    await global.eval("(x) => import(x)")("fs");
    

  2. The eval function operates in the current execution context (which is either the global scope or a function scope), but it does not treat the code as an ES Module. This is a limitation of how eval works—it runs the code as if it were part of the script context in which it is called, and it doesn’t provide the necessary module context that import statements require.

    As a workaround, you can use something like this:

    const dynamicImport = (module) => {
      return import(module);
    };
    
    // Usage:
    dynamicImport('fs').then((fs) => {
      console.log(fs);
    }).catch((error) => {
      console.error(error);
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search