Importing ES6 modules

We're trying to embed Spidermonkey76 - will look move to 78 ESR at some point - into a software that isn't a web browser. We've been looking at support for ES6 features and aren't sure about modules.

Attempts to use local path identifiers with import commands (import MyFunc from "./whatever";) provoke an "import declarations may only appear at the top level of a module" message.

There was a similar post a couple of years ago. One response suggested the usage of JS::CompileModule (instead of JS::Compile<Script>). How do we know that we have a module a-priori, rather than a script? 

Is the solution then to use a module resolve hook? Would it be possible to find an example? The JS API user guide doesn't include much on this topic.

Thanks very much.
0
Shankar
9/1/2020 9:30:15 AM
mozilla.dev.tech.js-engine 2054 articles. 0 followers. Post Follow

3 Replies
12 Views

Similar Articles

[PageSpeed] 22

Hi,

In general, JavaScript requires that you know certain code is a module a-pr=
iori. There are examples of code that parse as both Script and as Module ye=
t have different results. SpiderMonkey will not try to guess. If your appli=
cation wishes to take a guess, it could first try parsing as Script (since =
that has semantics that most people expect) and if parsing fails it could t=
ry again as Module. Your choice here would depend on what is acceptable for=
 your application in terms of performance and predictable behaviour.

Note as well that using the `CompileModule` API you must also call  ModuleI=
nstantiate in order to trigger loading and parsing of other modules that ar=
e imported. This all happens before executing the top-level JS code itself.

I've added an example to the embedding-examples repo. You can see the pull-=
request here: https://github.com/mozilla-spidermonkey/spidermonkey-embeddin=
g-examples/pull/32

--Ted

On Tuesday, September 1, 2020 at 5:30:16 AM UTC-4, Shankar wrote:
> We're trying to embed Spidermonkey76 - will look move to 78 ESR at some p=
oint - into a software that isn't a web browser. We've been looking at supp=
ort for ES6 features and aren't sure about modules.=20
>=20
> Attempts to use local path identifiers with import commands (import MyFun=
c from "./whatever";) provoke an "import declarations may only appear at th=
e top level of a module" message.=20
>=20
> There was a similar post a couple of years ago. One response suggested th=
e usage of JS::CompileModule (instead of JS::Compile<Script>). How do we kn=
ow that we have a module a-priori, rather than a script?=20
>=20
> Is the solution then to use a module resolve hook? Would it be possible t=
o find an example? The JS API user guide doesn't include much on this topic=
..=20
>=20
> Thanks very much.
0
tcam
9/1/2020 2:27:32 PM
On Tue, Sep 1, 2020 at 9:30 AM tcampbell wrote:
> There are examples of code that parse as both Script and as Module yet
have different results. SpiderMonkey will not try to guess. If your
application wishes to take a guess, it could first try parsing as Script
(since that has semantics that most people expect) and if parsing fails it
could try again as Module.

To clarify, the difference involves modules like this:

    function foo() {
      console.log("hello world");
    }

You can run this as a script. It declares a global function `foo`.

You can run this as a module too. But since it doesn't import or export
anything, it won't do anything useful. The function `foo` is module-scope
rather than global. Other scripts and modules can't see it.

That's why if you really don't know, it's best to try parsing it as a
script first, then module as a fallback. But it's even better to just have
clear rules about which files are treated as scripts and which ones are
modules. Your JS developers will probably expect such rules=E2=80=94they'll=
 be
familiar with HTML, for example, where a <script> is always a script,
unless the tag actually says <script type=3D"module">.

-j
0
Jason
9/1/2020 3:03:30 PM
This is a real problem, with no perfect solution.  In my case, I mandate 
that developers use a different file extension for modules. That makes 
it super easy, and the error it throws if you try and compile a module 
as a script is hopefully informative enough that they can fix it.

Also something to consider doing: Use JS::SetModuleResolveHook() so that 
you can have some control over where the interpreter looks for modules 
to load.  I'm not sure how intelligent SpiderMonkey is about module 
resolution without it.
On 9/1/2020 4:30 AM, Shankar wrote:
> We're trying to embed Spidermonkey76 - will look move to 78 ESR at some point - into a software that isn't a web browser. We've been looking at support for ES6 features and aren't sure about modules.
>
> Attempts to use local path identifiers with import commands (import MyFunc from "./whatever";) provoke an "import declarations may only appear at the top level of a module" message.
>
> There was a similar post a couple of years ago. One response suggested the usage of JS::CompileModule (instead of JS::Compile<Script>). How do we know that we have a module a-priori, rather than a script?
>
> Is the solution then to use a module resolve hook? Would it be possible to find an example? The JS API user guide doesn't include much on this topic.
>
> Thanks very much.
> _______________________________________________
> dev-tech-js-engine mailing list
> dev-tech-js-engine@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-tech-js-engine
0
kent
9/10/2020 1:55:42 PM
Reply: