Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESM Support #1

Closed
aaronjensen opened this issue Nov 6, 2021 · 6 comments
Closed

ESM Support #1

aaronjensen opened this issue Nov 6, 2021 · 6 comments

Comments

@aaronjensen
Copy link

Hi, this is a very interesting package. I'm trying to figure out if I can get ES modules imported, but running into a fairly opaque node error that I can't track down:

  class Test < Nodo::Core
    function :test, <<~JS
      async () => {
        const x = await import('react')
      }
    JS
  end
internal/errors.js:322:in `new NodeError'
internal/process/esm_loader.js:34:in `exports.importModuleDynamicallyCallback'
Sandbox::Test:30:in `__nodo_klass__.test'

I'm on Node 14, which supports dynamic import, at least with the CLI.

From what I can tell, this should set it up to support dynamic imports, but it does not appear to be doing that. Do you have any ideas?

Thanks!

Also, I'm curious what you're using this package for?

@aaronjensen
Copy link
Author

aaronjensen commented Nov 6, 2021

I was able to get it working by requiring the file that had the import(...) in it. If I put the import(...) in the Nodo function, I get the above error.

  class Test < Nodo::Core
    require importReact: "./importReact.js"

    function :test, <<~JS
      async (props) => {
        const x = await importReact()
      }
    JS
  end

@mtgrosser
Copy link
Owner

I tried to reproduce the problem and got the following error from Node:

A dynamic import callback was not specified. (Nodo::JavaScriptError)

There are some hints on the net regarding this error, but I was unable to make the dynamic import() run properly. Sometimes the Node process even crashed, so I'm wondering what is the actual state of ESM support inside Node. Even some rather trivial code like

class Foo < Nodo::Core
  function :import_uuid, code: "async () => { return await import('uuid') }"
  function :v4, code: "async () => { const uuid = await import_uuid(); return uuid.v4() }"
end

didn't work.

The main motivation for the creation of Nodo was the need for a Ruby environment where cross-compilers and bundlers like @vue/compiler-sfc and rollup can be executed by the Rails asset pipeline, so ESM support inside Nodo itself was not a concern. It would be interesting to investigate whether it could be adapted to use a pure-ESM runtime like deno.

@aaronjensen
Copy link
Author

That's the same error that I got. It seems to boil down to the fact that importModuleDynamically must be specified when using things like compileFunction or most of the other vm related things. I'm not sure which you use, and I have no idea how to get ahold of the importModuleDynamically that is used when you simply require a cjs module. All of that stuff is node internals, which they don't like you accessing: https://github.com/nodejs/node/blob/2cc7a91a5d855b4ff78f21f1bb8d4e55131d0615/lib/internal/modules/cjs/loader.js#L1018-L1022

Interestingly enough I can just create a file that exports a function that wraps import(...) and it'll work if I require that.

@mtgrosser
Copy link
Owner

The Nodo "class" definitions are run using vm.runInThisContext (code location)

I need to do some more research regarding the importModuleDynamically option. There is an implementation example here.

@mtgrosser mtgrosser linked a pull request Nov 9, 2021 that will close this issue
@mtgrosser mtgrosser removed a link to a pull request Nov 9, 2021
mtgrosser added a commit that referenced this issue Nov 9, 2021
@mtgrosser
Copy link
Owner

Added nodo.import() which uses the regular top-level import().

@aaronjensen
Copy link
Author

That's great, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants