Skip to content

Commit

Permalink
perf(jest-runtime): load chalk only once per worker
Browse files Browse the repository at this point in the history
  • Loading branch information
jeysal committed Feb 9, 2021
1 parent f0dc993 commit 7f25c06
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
Expand Up @@ -32,7 +32,6 @@ describe('Runtime', () => {
runtime.requireModule(modulePath);
}).toThrow(new Error('preprocessor must not run.'));
});

it('loads internal modules without applying transforms', async () => {
const runtime = await createRuntime(__filename, {
transform: {'\\.js$': './test_preprocessor'},
Expand All @@ -56,7 +55,6 @@ describe('Runtime', () => {
const exports = runtime.requireModule(modulePath);
expect(exports).toEqual({foo: 'foo'});
});

it('loads internal JSON modules without applying transforms', async () => {
const runtime = await createRuntime(__filename, {
transform: {'\\.json$': './test_json_preprocessor'},
Expand All @@ -68,5 +66,29 @@ describe('Runtime', () => {
const exports = runtime.requireInternalModule(modulePath);
expect(exports).toEqual({foo: 'bar'});
});

const OPTIMIZED_MODULE_EXAMPLE = 'chalk';
it('loads modules normally even if on the optimization list', () =>
createRuntime(__filename).then(runtime => {
const modulePath = path.resolve(
path.dirname(runtime.__mockRootPath),
'require-by-name.js',
);
const requireByName = runtime.requireModule(modulePath);
expect(requireByName(OPTIMIZED_MODULE_EXAMPLE)).not.toBe(
require(OPTIMIZED_MODULE_EXAMPLE),
);
}));
it('loads internal modules from outside if on the optimization list', () =>
createRuntime(__filename).then(runtime => {
const modulePath = path.resolve(
path.dirname(runtime.__mockRootPath),
'require-by-name.js',
);
const requireByName = runtime.requireInternalModule(modulePath);
expect(requireByName(OPTIMIZED_MODULE_EXAMPLE)).toBe(
require(OPTIMIZED_MODULE_EXAMPLE),
);
}));
});
});
10 changes: 10 additions & 0 deletions packages/jest-runtime/src/__tests__/test_root/require-by-name.js
@@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

module.exports = moduleName => require(moduleName);
15 changes: 14 additions & 1 deletion packages/jest-runtime/src/index.ts
Expand Up @@ -95,6 +95,16 @@ const defaultTransformOptions: InternalModuleOptions = {
type InitialModule = Omit<Module, 'require' | 'parent' | 'paths'>;
type ModuleRegistry = Map<string, InitialModule | Module>;

// These are modules that we know
// * are safe to require from the outside (not stateful, not prone to errors passing in instances from different realms), and
// * take sufficiently long to require to warrant an optimization.
// When required from the outside, they use the worker's require cache and are thus
// only loaded once per worker, not once per test file.
// Note that this only applies when they are required in an internal context;
// users who require one of these modules in their tests will still get the module from inside the VM.
// Prefer listing a module here only if it is impractical to use the jest-resolve-outside-vm-option where it is required,
// e.g. because there are many require sites spread across the dependency graph.
const INTERNAL_MODULE_REQUIRE_OUTSIDE_OPTIMIZED_MODULES = new Set(['chalk']);
const JEST_RESOLVE_OUTSIDE_VM_OPTION = Symbol.for(
'jest-resolve-outside-vm-option',
);
Expand Down Expand Up @@ -660,9 +670,12 @@ export default class Runtime {

requireInternalModule<T = unknown>(from: Config.Path, to?: string): T {
if (to) {
if (INTERNAL_MODULE_REQUIRE_OUTSIDE_OPTIMIZED_MODULES.has(to)) {
return nativeModule.createRequire(from)(to);
}
const outsideJestVmPath = decodePossibleOutsideJestVmPath(to);
if (outsideJestVmPath) {
return require(outsideJestVmPath);
return nativeModule.createRequire(from)(outsideJestVmPath);
}
}

Expand Down

0 comments on commit 7f25c06

Please sign in to comment.