boa_module::register uses global namespace / realm, unlike normal javascript modules? #5412
-
|
(This is a follow-up of #5410 (comment), since while I got the correct and accurate answer, I am still struggling with my actual source of the problem.) My motivation for using boa_module was to be able to namespace Class types (so that they won't collide with a Class in global namespace with same name), however I have no idea how to make it behave like a normal JavaScript module, which has it's own namespace as far as I know. Is this per design, or I am doing something wrong? Sorry if the answer might be obvious, but I still didn't manage to figure it myself. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
I think the confusing part is that there are two different namespaces involved here. A JavaScript module has its own module environment / module namespace for its exports. So from JS you can do: import * as fs from "/advancedfx/fs.mjs";
fs.readDir(".");and those exports are namespaced under fs. But Class::from_data(...) is not looking up an exported module binding. It needs the native class registration/prototype from Boa’s registered-class map for the current realm. That registration is realm-level, not module-local. That is why the previous fix works: fs::boa_register(realm.clone(), context)?;
Ok(fs::boa_module(realm, context)?)but it also makes the class visible through the realm/global registration mechanism. In other words, boa_module(...) gives you module exports, while boa_register(...) registers the native classes/functions into the realm/context so from_data(...) can construct objects with the right prototype. So I do not think #[boa_module] currently gives native classes a private per-module class registry in the same sense that source JS modules have private lexical bindings. If the goal is only to avoid collisions in JavaScript user code, one practical workaround is:
For example, JS users would still consume it as: import * as fs from "/advancedfx/fs.mjs";
const dir = fs.readDir(".");and not as a global ReadDir. If the goal is stronger isolation, then a separate Realm may be the right abstraction, but that also means you need to decide which host globals/runtime features, such as console, should be registered into that realm as well. A new realm will not automatically be “the same global object but with private module classes”; it is a separate realm with its own intrinsics/global environment. So my current understanding is:
|
Beta Was this translation helpful? Give feedback.
I think the confusing part is that there are two different namespaces involved here.
A JavaScript module has its own module environment / module namespace for its exports. So from JS you can do:
and those exports are namespaced under fs.
But Class::from_data(...) is not looking up an exported module binding. It needs the native class registration/prototype from Boa’s registered-class map for the current realm. That registration is realm-level, not module-local.
That is why the previous fix works:
but it also makes the class visible through the realm/glo…