'Can asynchronous module definitions be used with abstract syntax trees on v8 engine to read third party dependencies? This is for Cloudflare Workers

I understand eval string-to-function is impossible to use on the browsers' application programming interfaces, but there must be another strategy to use third party dependencies without node.js on v8 engine, given Cloudflare does it in-house, unless they disable the exclusive method by necessity or otherwise on their edge servers for Workers. I imagine I could gather the AST of the commonjs module, as I was able to by rollup watch, but what might the actual steps be, by tooling? I mention AMD for it seems to rely on string-to-function (to-which I've notice Mozilla MDN says nothing much about it).

I have been exploring the require.js repositories, and they either use eval or AST

function DEFNODE(type, props, methods, base) {
    if (arguments.length < 4) base = AST_Node;
    if (!props) props = [];
    else props = props.split(/\s+/);
    var self_props = props;
    if (base && base.PROPS) props = props.concat(base.PROPS);
    var code = "return function AST_" + type + "(props){ if (props) { ";
    for (var i = props.length; --i >= 0; ) {
      code += "this." + props[i] + " = props." + props[i] + ";";
    }
    var proto = base && new base();
    if ((proto && proto.initialize) || (methods && methods.initialize))
      code += "this.initialize();";
    code += "}}";
    //constructor
    var cnstor = new Function(code)();
    if (proto) {
      cnstor.prototype = proto;
      cnstor.BASE = base;
    }
    if (base) base.SUBCLASSES.push(cnstor);
    cnstor.prototype.CTOR = cnstor;
    cnstor.PROPS = props || null;
    cnstor.SELF_PROPS = self_props;
    cnstor.SUBCLASSES = [];
    if (type) {
      cnstor.prototype.TYPE = cnstor.TYPE = type;
    }
    if (methods)
      for (i in methods)
        if (HOP(methods, i)) {
          if (/^\$/.test(i)) {
            cnstor[i.substr(1)] = methods[i];
          } else {
            cnstor.prototype[i] = methods[i];
          }
        }
    //a function that returns an object with [name]:method
    cnstor.DEFMETHOD = function (name, method) {
      this.prototype[name] = method;
    };
    if (typeof exports !== "undefined") exports[`AST_${type}`] = cnstor;

    return cnstor;
  }

  var AST_Token = DEFNODE(
    "Token",
    "type value line col pos endline endcol endpos nlb comments_before file raw",
    {},
    null
  );

https://codesandbox.io/s/infallible-darwin-8jcl2k?file=/src/mastercard-backbank/uglify/index.js

https://www.youtube.com/watch?v=EF7UW9HxOe4 HTML5/JavaScript with Maven



Solution 1:[1]

Andreas Rossberg - is AST parsing, or initialize node.js abstraction for native c++, enough?

v8::String::NewFromUtf8(isolate, "Index from C++!");

Rising Stack - Node Source

"a macro implicit" parameter - bridge object between
C++ and JavaScript runtimes 
extract a function's parameters and set the return value.
#include <nan.h>

int build () {
  NAN_METHOD(Index) {
    info.GetReturnValue().Set(
      Nan::New("Index from C++!").ToLocalChecked()
    );
  }
}

  // Module initialization logic
NAN_MODULE_INIT(Initialize) {
  /*Export the `Index` function
    (equivalent to `export function Index (...)` in JS)*/
  NAN_EXPORT(target, Index);
}

New module "App" Initialize function from NAN_MODULE_INIT (an atomic?-macro)

"__napi_something doesn't exist."

"node-addon-API module for C++ code (N-API's C code's headers)"

NODE_MODULE(App, Initialize);

Sep 17, 2013, 4:42:17 AM to [email protected] "This comes up frequently, but the answer remains the same: scrap the idea. ;) Neither the V8 parser nor its AST are designed for external interfacing. In particular (1) V8's AST does not necessarily reflect JavaScript syntax 1-to-1, (2) we change it all the time, and (3) it depends on various V8 internals. And since all these points are important for V8, don't expect the situation to change.

/Andreas"

V8 c++: How to import module via code to script context (5/28/22, edit)

"The export keyword may only be used in a module interface unit. The keyword is attached to a declaration of an entity, and causes that declaration (and sometimes the definition) to become visible to module importers[ - except for] the export keyword in the module-declaration, which is just a re-use of the keyword (and does not actually “export” ...entities)."

SyntheticModule::virtual

ScriptCompiler::CompileModule() - "Corresponds to the ParseModule abstract operation in the ECMAScript specification."

Local<Function> foo_func = ...;//external
Local<Module> module = Module::CreateSyntheticModule(
    isolate, name,
    {String::NewFromUtf8(isolate, "foo")},
    [](Local<Context> context, Local<Module> module) {
      module->SetSyntheticModuleExport(
        String::NewFromUtf8(isolate, "foo"), foo_func
      );
    });

Context-Aware addons from node.js' commonjs modules

export module index;
export class Index {
  public:
    const char* app() {              
      return "done!";
    }
};
import index;
import <iostream>;

int main() {
    std::cout << Index().app() << '\n';
}

node-addon-api (new)

native abstractions (old)

"Thanks to the crazy changes in V8 (and some in Node core), keeping native addons compiling happily across versions, particularly 0.10 to 0.12 to 4.0, is a minor nightmare. The goal of this project is to store all logic necessary to develop native Node.js addons without having to inspect NODE_MODULE_VERSION and get yourself into a macro-tangle[ macro = extern atomics?]."

Scope Isolate (v8::Isolate), variable Local (v8::Local)

typed_array_to_native.cc

"require is part of the Asynchronous Module Definition AMD API[, without "string-to-function" eval/new Function()]," node.js makes objects, for it is written in C++.

"According to the algorithm, before finding ./node_modules/_/index.js, it tried looking for express in the core Node.js modules. This didn’t exist, so it looked in node_modules, and found a directory called _. (If there was a ./node_modules/_.js, it would load that directly.) It then loaded ./node_modules/_/package.json, and looked for an exports field, but this didn’t exist. It also looked for a main field, but this didn’t exist either. It then fell back to index.js, which it found. ...require() looks for node_modules in all of the parent directories of the caller."

But java?

I won't accept this answer until it works, but this looks promising:

https://developer.oracle.com/databases/nashorn-javascript-part1.html

If not to run a jar file or something, in the Worker:

https://github.com/nodyn/jvm-npm

require and build equivalent in maven, first, use "dist/index.js".

Specifically: ScriptEngineManager

https://stackoverflow.com/a/15787930/11711280

Actually: js.commonjs-require experimental

https://docs.oracle.com/en/graalvm/enterprise/21/docs/reference-manual/js/Modules/

Alternatively/favorably: commonjs builder in C (v8 and node.js)

https://www.reddit.com/r/java/comments/u7elf4/what_are_your_thoughts_on_java_isolates_on_graalvm/

Here I will explore v8/node.js src .h and .cc for this purpose

https://codesandbox.io/s/infallible-darwin-8jcl2k?file=/src/c.cpp

I'm curious why there is near machine-level C operability in Workers if not to use std::ifstream, and/or build-locally, without node.js require.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1