Esm: Is there a way to control the global object?

Created on 2 Dec 2018  路  14Comments  路  Source: standard-things/esm

I'm trying to use esm from within jsdom and while it works enough to load a module, the globals that jsdom defines on window are not present. Is there a way to get esm to use the global object from the context in which it's invoked?

The code I'm trying is something like this:

    const jsdom = new JSDOM(`<!doctype html>`, {
      runScripts: 'outside-only',
    });
    jsdom.window.require = require;
    jsdom.window.module = module;
    const s = new Script(`
      require = require('esm')(module);
      require('my-web-module');
    `);
    jsdom.runVMScript(s);
    console.log(jsdom.window.document.body.innerHTML);
question

All 14 comments

Hi @justinfagnani!

Would you create a small repo for me to check out your scenario.

Hey 馃憢

The code above is almost exactly it. I made a gist with the module I'm trying to load too: https://gist.github.com/justinfagnani/6d0f7e904c43a5ed2a213fa8e0e75f6a

Ah okay!

If you were to replace the two lines of requiring esm and loading my-test-module with

require("./check-window")

With check-window.js being

console.log(window)

and run that it will produce

/Users/jdalton/projects/demo/check-window.js:1
(function (exports, require, module, __filename, __dirname) { console.log(window)
                                                                          ^
ReferenceError: window is not defined

This is because the vm instance the jsdom script is running in is different than the one the injected require is running in.

In the short-term you can workaround this by doing

const global = require("vm").runInThisContext("global")
global.window = window

Before loading my-test-module.

In the long-term I can look into adding a global option to tackle some of that.

@jdalton any thoughts here since it sounded like you were doing some major work for the next version?

I think this seems like a reasonable option addition. I'm still trying to get the next release out though so I don't have the bandwidth to add it at the moment.

@jdalton I got custom global console instance in my project and when I activate esm, it seemes shadowed by other instance. I presume, esm somehow injects its own console instance right after me doing the same with my custom console. ~When I use another name (like console2) issue disappears.~

Can you give some tips how to get my own console visible globally across modules?

Looks similar to this #622

@StreetStrider

Can you give some tips how to get my own console visible globally across modules?

If you can provide a simple repro repo that would help me diagnose an issue or prescribe usage.

@jdalton I've put repro here. Sorry for custom dep, the issue is reproduced in callback of it.
https://github.com/StreetStrider/esm-console (zip).

Also found this:
default
however this might be just an esm's implementation detail.

Thanks for the repro @StreetStrider! I found the issue and should have a patch/fix in a day or so (traveling so there's gonna be a slight delay).

Update:

Patch and test: https://github.com/standard-things/esm/commit/1eabfd873c094c8f3891a6b4f16c8c7e47d32f1d

@jdalton thank you, will try master till release.

@jdalton, fyi, when I install from "esm": "github:standard-things/esm" I got
Error: Cannot find module 'execa' on prepare step.

It looks like a possible error or maybe just master is not intended to be installable.

v3.2.6 is released 馃帀

@jdalton works as expected now in all recently flawed scenarios. :+1:

Was this page helpful?
0 / 5 - 0 ratings