diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index aafff4c113fe..1f7506b7af0e 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -9,7 +9,7 @@ import crypto from 'crypto'; import path from 'path'; import vm from 'vm'; import {Config} from '@jest/types'; -import {createDirectory} from 'jest-util'; +import {createDirectory, isPromise} from 'jest-util'; import fs from 'graceful-fs'; import {transformSync as babelTransform} from '@babel/core'; // @ts-ignore: should just be `require.resolve`, but the tests mess that up @@ -51,6 +51,17 @@ const projectCaches: WeakMap< // To reset the cache for specific changesets (rather than package version). const CACHE_VERSION = '1'; +async function waitForPromiseWithCleanup( + promise: Promise, + cleanup: () => void, +) { + try { + await promise; + } finally { + cleanup(); + } +} + export default class ScriptTransformer { static EVAL_RESULT_VARIABLE: 'Object.'; private _cache: ProjectCache; @@ -435,10 +446,18 @@ export default class ScriptTransformer { return fileSource; } - async requireAndTranspileModule( + requireAndTranspileModule( + moduleName: string, + callback?: (module: ModuleType) => void, + ): ModuleType; + requireAndTranspileModule( + moduleName: string, + callback?: (module: ModuleType) => Promise, + ): Promise; + requireAndTranspileModule( moduleName: string, callback?: (module: ModuleType) => void | Promise, - ): Promise { + ): ModuleType | Promise { // Load the transformer to avoid a cycle where we need to load a // transformer in order to transform it in the require hooks this.preloadTransformer(moduleName); @@ -467,9 +486,19 @@ export default class ScriptTransformer { ); const module: ModuleType = require(moduleName); + if (!callback) { + revertHook(); + + return module; + } + try { - if (callback) { - await callback(module); + const cbResult = callback(module); + + if (isPromise(cbResult)) { + return waitForPromiseWithCleanup(cbResult, revertHook).then( + () => module, + ); } } finally { revertHook();