-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
Description
Is your feature request related to a problem? Please describe.
One of Jest's longest-standing issue are about globals in tests being different from Node's, see jestjs/jest#2549.
Short example illustrating the problem:
const {createContext, compileFunction} = require('vm');
const context = createContext({});
const code = `
const fs = require('fs');
const assert = require('assert');
try {
fs.readFileSync('/some/faulty/path', 'utf8')
} catch (error) {
assert(error instanceof Error)
}
`;
const compiledFunction = compileFunction(code, ['require'], {
parsingContext: context,
});
compiledFunction(require);Run this example, and the instanceof test will fail. Remove parsingContext option, and it will pass.
Describe the solution you'd like
Jest implements its own require etc, which works great most of the time, but in the case of node core modules, it fallbacks to requiring the module outside of the context. AFAIK the JS source of the node core modules are embedded in the binary of Node, so we cannot read them and pass them though compileFunction, SourceTextModule or some such ourselves so the globals would be the same.
It would be great if Node provided some API allowing the JS of core modules to be evaluated within a vm.Context.
(I had originally given up on this, but seeing as #30709 solves the super old #855 I thought maybe we might be lucky enough that this is possible as well? 😀)
Describe alternatives you've considered
We have tried to mess around with setting Symbol.hasInstance and just injecting globals from the outside (although that breaks the encapsulation we're aiming for by using separate Contexts in the first place) without luck. It's also a moving target as we'd have to add that property to all globals.
FWIW the Jest issue has a $500 bounty which I'd be happy to give to someone solving this in core, or the JS Foundation if that's more correct.