Open ByteEater-pl opened 7 months ago
A possibility (new idiom?):
myRealm.evaluate((() => {
// some code
}).toString().slice(7, -1))
Much better than a string, although tools would still confuse scopes and e.g. consider identifiers in some code
to refer to outer variables.
That won’t work, because the function could close over objects from the outer realm, including the global. A string, or a host-specific specifier like in Workers, is the only option.
I wouldn't say never on module loading being async. Technically a module expression would have its module graph already resolved, so we could imagine in the future a way to synchronously evaluate them in another realm. This is definitely for future proposals to figure out.
@ljharb, what do you mean that won't work? Yes, the function closes over whatever's referenced from outer scopes, but toString
doesn't care, it only gets the expression used to define the function as string. The variable names are then interpreted in a different way inside the ShadowRealm.
Shorter alternative:
myRealm.evaluate(`(${() => {
// some code
}})()`)
It nests the anonymous function scope, but in many cases that's probably OK. Additionally, it works just as well when // some code
is just an expression and the brackets are omitted, whereas the former would require a change to e.g. slice(6)
.
@ByteEater-pl i'm confused, if it's converting the function to a string and evaling it, how is that any better than just accepting a string directly?
@ljharb, from my initial comment:
If the ECMAScript code to be evaluated is contained in a string literal (likely to be much more common than any other case), occurrences of its delimiters (", ' or backtick) in it need escaping.
Editors and other tools are unable to detect in all cases that a string literal is intended to be passed to ShadowRealm.prototype.evaluate and provide proper support (for editors it would be syntax highlighting, completion suggestions, etc.).
ah. that seems like https://github.com/hax/proposal-raw-string-literals, which was unable to achieve stage 1 - meaning, the committee didn't seem to think that problem was worth solving.
There is overlap. But here it's just about ECMAScript code, treated as such. Actually, obviating the need for escaping is a nice bonus for me, however my main motivation is to have tools, especially editors, handle the code as code (with coloring etc.), not as string literal.
If "Raw string literals" is ever revived, though, it might be worth generalizing, so that a hint for tools can be provided, indicating the language, with a predefined hint (say es
) for ECMAScript and the rest implementation-defined. To wit:
const
someECMAScript = LanguageHint.es@``requestLeave(2) // I would like to request `2 leave days`.``,
someXML = LanguageHint.xml@``<p>In ECMAScript, <code>`</code> can be used to delimit multi-line strings.</p>``
ShadowRealm.prototype.evaluate
as currently specified takes a string. This is sub-optimal.If the ECMAScript code to be evaluated is contained in a string literal (likely to be much more common than any other case), occurrences of its delimiters (
"
,'
or backtick) in it need escaping.Editors and other tools are unable to detect in all cases that a string literal is intended to be passed to
ShadowRealm.prototype.evaluate
and provide proper support (for editors it would be syntax highlighting, completion suggestions, etc.).It'd be therefore desirable to have a better syntactic alternative.
Module expressions come to mind, giving:
But modules are evaluated asynchronously. It'd probably be too confusing to carve out an exception for
ShadowRealm.prototype.evaluate
.If only source code could be extracted from a module object! Not necessarily all of them. And possibly at some phase, not yet present in ECMA-262, or without sufficient API yet. A phase that module expressions feed into. If undesirable for normal modules, perhaps a subclass could be created for module expressions which provides a property or method wrapping what's inside the brackets as string.