Skip to content

Commit 7f25c06

Browse files
committed
perf(jest-runtime): load chalk only once per worker
1 parent f0dc993 commit 7f25c06

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

packages/jest-runtime/src/__tests__/runtime_internal_module.test.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ describe('Runtime', () => {
3232
runtime.requireModule(modulePath);
3333
}).toThrow(new Error('preprocessor must not run.'));
3434
});
35-
3635
it('loads internal modules without applying transforms', async () => {
3736
const runtime = await createRuntime(__filename, {
3837
transform: {'\\.js$': './test_preprocessor'},
@@ -56,7 +55,6 @@ describe('Runtime', () => {
5655
const exports = runtime.requireModule(modulePath);
5756
expect(exports).toEqual({foo: 'foo'});
5857
});
59-
6058
it('loads internal JSON modules without applying transforms', async () => {
6159
const runtime = await createRuntime(__filename, {
6260
transform: {'\\.json$': './test_json_preprocessor'},
@@ -68,5 +66,29 @@ describe('Runtime', () => {
6866
const exports = runtime.requireInternalModule(modulePath);
6967
expect(exports).toEqual({foo: 'bar'});
7068
});
69+
70+
const OPTIMIZED_MODULE_EXAMPLE = 'chalk';
71+
it('loads modules normally even if on the optimization list', () =>
72+
createRuntime(__filename).then(runtime => {
73+
const modulePath = path.resolve(
74+
path.dirname(runtime.__mockRootPath),
75+
'require-by-name.js',
76+
);
77+
const requireByName = runtime.requireModule(modulePath);
78+
expect(requireByName(OPTIMIZED_MODULE_EXAMPLE)).not.toBe(
79+
require(OPTIMIZED_MODULE_EXAMPLE),
80+
);
81+
}));
82+
it('loads internal modules from outside if on the optimization list', () =>
83+
createRuntime(__filename).then(runtime => {
84+
const modulePath = path.resolve(
85+
path.dirname(runtime.__mockRootPath),
86+
'require-by-name.js',
87+
);
88+
const requireByName = runtime.requireInternalModule(modulePath);
89+
expect(requireByName(OPTIMIZED_MODULE_EXAMPLE)).toBe(
90+
require(OPTIMIZED_MODULE_EXAMPLE),
91+
);
92+
}));
7193
});
7294
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
'use strict';
9+
10+
module.exports = moduleName => require(moduleName);

packages/jest-runtime/src/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ const defaultTransformOptions: InternalModuleOptions = {
9595
type InitialModule = Omit<Module, 'require' | 'parent' | 'paths'>;
9696
type ModuleRegistry = Map<string, InitialModule | Module>;
9797

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

661671
requireInternalModule<T = unknown>(from: Config.Path, to?: string): T {
662672
if (to) {
673+
if (INTERNAL_MODULE_REQUIRE_OUTSIDE_OPTIMIZED_MODULES.has(to)) {
674+
return nativeModule.createRequire(from)(to);
675+
}
663676
const outsideJestVmPath = decodePossibleOutsideJestVmPath(to);
664677
if (outsideJestVmPath) {
665-
return require(outsideJestVmPath);
678+
return nativeModule.createRequire(from)(outsideJestVmPath);
666679
}
667680
}
668681

0 commit comments

Comments
 (0)