Skip to content

Commit 58e8491

Browse files
authored
fix: isolate esm async import bug (#14397)
1 parent 8426b5d commit 58e8491

File tree

7 files changed

+92
-10
lines changed

7 files changed

+92
-10
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- `[jest-mock]` Revert [#13866](https://github.com/jestjs/jest/pull/13866) as it was a breaking change ([#14429](https://github.com/jestjs/jest/pull/14429))
1313
- `[jest-mock]` Revert [#13867](https://github.com/jestjs/jest/pull/13867) as it was a breaking change ([#14429](https://github.com/jestjs/jest/pull/14429))
1414
- `[@jest/reporters]` Marks Reporter's hooks as optional ([#14433](https://github.com/jestjs/jest/pull/14433))
15+
- `[jest-runtime]` Fix dynamic ESM import module bug when loaded module through `jest.isolateModulesAsync` ([14397](https://github.com/jestjs/jest/pull/14397))
1516

1617
### Chore & Maintenance
1718

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`runs test with isolate modules async import 1`] = `
4+
"Test Suites: 1 passed, 1 total
5+
Tests: 1 passed, 1 total
6+
Snapshots: 0 total
7+
Time: <<REPLACED>>
8+
Ran all test suites."
9+
`;
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
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+
import {extractSummary} from '../Utils';
9+
import runJest from '../runJest';
10+
11+
test('runs test with isolate modules async import', () => {
12+
const {exitCode, stderr} = runJest('isolate-modules-async', [], {
13+
nodeOptions: '--experimental-vm-modules --no-warnings',
14+
});
15+
16+
const {summary} = extractSummary(stderr);
17+
18+
expect(summary).toMatchSnapshot();
19+
expect(exitCode).toBe(0);
20+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
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+
import {jest} from '@jest/globals';
8+
9+
test('should have a fresh module state in each isolateModulesAsync context', async () => {
10+
await jest.isolateModulesAsync(async () => {
11+
const {getState, incState} = await import('../main.js');
12+
expect(getState()).toBe(0);
13+
incState();
14+
expect(getState()).toBe(1);
15+
});
16+
await jest.isolateModulesAsync(async () => {
17+
const {getState, incState} = await import('../main.js');
18+
expect(getState()).toBe(0);
19+
incState();
20+
expect(getState()).toBe(1);
21+
});
22+
});

e2e/isolate-modules-async/main.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
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+
let myState = 0;
8+
9+
export function incState() {
10+
myState += 1;
11+
}
12+
13+
export function getState() {
14+
return myState;
15+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "isolate-modules-async",
3+
"type": "module",
4+
"jest": {
5+
"transform": {},
6+
"testEnvironment": "node"
7+
}
8+
}

packages/jest-runtime/src/index.ts

+17-10
Original file line numberDiff line numberDiff line change
@@ -416,12 +416,15 @@ export default class Runtime {
416416
query = '',
417417
): Promise<VMModule> {
418418
const cacheKey = modulePath + query;
419+
const registry = this._isolatedModuleRegistry
420+
? this._isolatedModuleRegistry
421+
: this._esmoduleRegistry;
419422

420423
if (this._fileTransformsMutex.has(cacheKey)) {
421424
await this._fileTransformsMutex.get(cacheKey);
422425
}
423426

424-
if (!this._esmoduleRegistry.has(cacheKey)) {
427+
if (!registry.has(cacheKey)) {
425428
invariant(
426429
typeof this._environment.getVmContext === 'function',
427430
'ES Modules are only supported if your test environment has the `getVmContext` function',
@@ -454,15 +457,15 @@ export default class Runtime {
454457
context,
455458
);
456459

457-
this._esmoduleRegistry.set(cacheKey, wasm);
460+
registry.set(cacheKey, wasm);
458461

459462
transformResolve();
460463
return wasm;
461464
}
462465

463466
if (this._resolver.isCoreModule(modulePath)) {
464467
const core = this._importCoreModule(modulePath, context);
465-
this._esmoduleRegistry.set(cacheKey, core);
468+
registry.set(cacheKey, core);
466469

467470
transformResolve();
468471

@@ -526,11 +529,11 @@ export default class Runtime {
526529
}
527530

528531
invariant(
529-
!this._esmoduleRegistry.has(cacheKey),
532+
!registry.has(cacheKey),
530533
`Module cache already has entry ${cacheKey}. This is a bug in Jest, please report it!`,
531534
);
532535

533-
this._esmoduleRegistry.set(cacheKey, module);
536+
registry.set(cacheKey, module);
534537

535538
transformResolve();
536539
} catch (error) {
@@ -539,7 +542,7 @@ export default class Runtime {
539542
}
540543
}
541544

542-
const module = this._esmoduleRegistry.get(cacheKey);
545+
const module = registry.get(cacheKey);
543546

544547
invariant(
545548
module,
@@ -563,14 +566,18 @@ export default class Runtime {
563566
return;
564567
}
565568

569+
const registry = this._isolatedModuleRegistry
570+
? this._isolatedModuleRegistry
571+
: this._esmoduleRegistry;
572+
566573
if (specifier === '@jest/globals') {
567-
const fromCache = this._esmoduleRegistry.get('@jest/globals');
574+
const fromCache = registry.get('@jest/globals');
568575

569576
if (fromCache) {
570577
return fromCache;
571578
}
572579
const globals = this.getGlobalsForEsm(referencingIdentifier, context);
573-
this._esmoduleRegistry.set('@jest/globals', globals);
580+
registry.set('@jest/globals', globals);
574581

575582
return globals;
576583
}
@@ -586,7 +593,7 @@ export default class Runtime {
586593
return this.importMock(referencingIdentifier, specifier, context);
587594
}
588595

589-
const fromCache = this._esmoduleRegistry.get(specifier);
596+
const fromCache = registry.get(specifier);
590597

591598
if (fromCache) {
592599
return fromCache;
@@ -662,7 +669,7 @@ export default class Runtime {
662669
}
663670
}
664671

665-
this._esmoduleRegistry.set(specifier, module);
672+
registry.set(specifier, module);
666673
return module;
667674
}
668675

0 commit comments

Comments
 (0)