`--std` versus `->std()`
Closed this issue · 7 comments
I use a javascript program abc2svg that I call using a wrapper script chordproabc.js
. This works fine:
$ qjs --std chordproabc.js lib/abc2svg foo.html foo.abc
Unlike the qjs --std
option, the JavaScript::QuickJS std()
method enables but does not import. So I add two import lines
import * as std from 'std'
import * as os from 'os'
Now the script fails somewhere in the guts of abc2svg. It doesn't matter whether I import something or everything from std or os, as soon as I have an import it fails.
Much to my surprise this is reproducible with qjs, when I invoke the script with the imports:
$ qjs --std chordproabc.js lib/abc2svg foo.html foo.abc
TypeError: not a function
at abc_cmd (lib/abc2svg/cmdline.js:148)
at <anonymous> (chordproabc.js:77)
I don't have a clue what is going on but it must be related to the difference between --std
and ->std()
. What is the reason to make these different?
I've attached a zip with the necessary files to reproduce this.
qq.zip
UPDATE: Same failure with quickjs-ng.
qjs
will, by default, detect whether the executed file—in your case, chordproabc.js
—is a module or a script. By adding the import
statements you’re subtly making qjs
parse your file as an ES6 module, which means that var abc2svg
is no longer global. Thus, loadjs
is the no-op function in abc2svg-1.js
, not the “useful” one in chordproabc.js
.
You can mitigate this by doing globalThis.abc2svg = { …
in chordproabc.js
, but I think globalThis
is an implementation detail of QuickJS and likely not something to depend on.
Really, I think it’s an oversight that std
and os
are only available to modules and not plain scripts. That said, it should be fairly easy to accommodate in your code by just doing a dynamic import, e.g., import('std')->then( std => { … } )
.
Interesting. How does globalThis relate to the set_globals() function?
For the embedding, I would like to replace the chordproabc.js script by perl code. Can you shed some light?
Thanks!
qq2.zip
How does globalThis relate to the set_globals() function?
TBH I’m not sure … play around with it?
I would like to replace the chordproabc.js script by perl code. Can you shed some light?
Looks like you’re on the right path.
What would be required for a switch to quickjs-ng?
I haven’t looked at qjs-ng, but in theory, it should be as simple as just swapping out the repos.
If you look, you’ll see that I’ve applied a couple of quickjs patches in this project: a couple in git, and a few more via Makefile.PL. Ideally, those should all be upstream before any switchover.
I’ve pushed version 0.19, which matches qjs
’s behaviour in creating std
(and os
) globals.
By odd coincidence, Fabrice merged some patches today—the first quickjs updates in almost 2 years. One of them fixes a CVE, so you should update.
For the record, globalThis is actually the standardised works everywhere version of what window/document/et. al. were in browser contexts.
(apologies for thread necro but it seemed worth leaving here as a note)