-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use clean global when setting up Window #2975
Conversation
Can you add a test that fails before this change, and work to pass the lint check? |
Started writing a test today, but it started to get a little gross so wanted to run it by you first. I wrote a describe block similar to jsdom/test/api/options-run-scripts.js Lines 127 to 149 in 8921128
// `globalThis` is not supported by Node 10 which makes it useful for testing
const jsSpecGlobalsPolyfillDescribe = hasNode10 ? describe : describe.skip;
jsSpecGlobalsPolyfillDescribe("JS spec polyfilled globals", () => {
afterEach(() => {
delete global.globalThis;
});
// Allows us to modify global object prior to running module code
function getFreshJsdomModule() {
delete require.cache[require.resolve("../..")];
// eslint-disable-next-line global-require
return require("../..");
}
for (const optionValue of ["outside-only", "dangerously"]) {
it(`should not include globals not available in fresh global when set to "${optionValue}"`, () => {
global.globalThis = global;
const { JSDOM: FreshJSDOM } = getFreshJsdomModule();
new FreshJSDOM(undefined, { runScripts: optionValue })
assert.doesNotThrow(() => new FreshJSDOM(undefined, { runScripts: optionValue }));
});
}
}); However there are some issues with this approach:
Which lead me to thinking.. perhaps instead of running |
This jsdom/scripts/generate-js-globals.js Lines 14 to 16 in 8921128
So this PR partly removes the optimization introduced by having it in a script anyways. Would it make sense to just do the
Doing
I don't think those ms will make a huge difference compared to just loading
This is with inlining the script into the runtime
So about 5ms slower, but it fixes this bug where global env when Generating the file in a |
I've updated the PR to generate the globals at runtime. |
@domenic ping 🙂 |
This currently fails the build and does not have a test. |
@domenic i'm waiting for feedback on the approach. |
It's hard to evaluate the approach since I don't know if it works (no new tests), or if it can be made to pass jsdom's existing tests. Sorry. |
I'm not sure if it's possible to write a proper test for this since it'll involve switching node versions. It will only fail when running an old node against the json file generated on a newer version of node. The bug is best boiled down to this, I think console.log(process.version);
global.globalThis = global;
const {JSDOM} = require('jsdom');
new JSDOM('', {runScripts: 'outside-only'});
console.log('Great success!'); Running with node 10 prints v10.20.1
evalmachine.<anonymous>:1
globalThis
^
ReferenceError: globalThis is not defined
at evalmachine.<anonymous>:1:1
at Script.runInContext (vm.js:133:20)
at Object.runInContext (vm.js:311:6)
at setupWindow (/Users/simen/repos/hhhhhu/node_modules/jsdom/lib/jsdom/browser/Window.js:51:55)
at new Window (/Users/simen/repos/hhhhhu/node_modules/jsdom/lib/jsdom/browser/Window.js:107:3)
at exports.createWindow (/Users/simen/repos/hhhhhu/node_modules/jsdom/lib/jsdom/browser/Window.js:38:10)
at new JSDOM (/Users/simen/repos/hhhhhu/node_modules/jsdom/lib/api.js:36:20)
at Object.<anonymous> (/Users/simen/repos/hhhhhu/file.js:7:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10) Running with node 12 prints v12.19.0
Great success! One possible solution is to publish new versions of JSDOM on the oldest version of node you support, but then you'd have the opposite problem - globals that should be there on newer versions of node are not there |
This seems like a great test to add. |
I don't think it'd be a valid test since the issue is that the list of globals is generated at build time and might lead to a mismatch between what I guess the test might guard against a future optimization of again going with a static list? Not sure how valuable that's in practice? CI is currently red due to attempting to run |
I'm pretty confused. You said that you have a test which fails on Node v10 on jsdom master, and would pass on Node v10 with this patch applied. If that's the case, it's a valid test. Or am I missing something?
Well, we need to make sure JSDOM continues to work in the browser, including all our existing tests. We shouldn't skip tests that pass today. For the new test, i.e. "The bug is best boiled down to this, I think", that test should also be able to pass in the browser... I don't see a reason to skip it. |
I have a script that illustrates how the current approach fails (which I pasted in the comment above), but I don't think it can be converted to a proper test. It would not fail on jsdom master unless the
Good point - it seems |
Fixes #2961.
Use a clean instance of the global object when looking for global entries to install into the jsdom environment. This avoids issues when the global object has had APIs polyfilled that aren't available within a new vm context.
Credit goes to @SimenB for helping troubleshoot!