fix: isolate esm async import bug (#14397)

This commit is contained in:
cin 2023-08-21 20:08:55 +08:00 committed by GitHub
parent 8426b5d9bc
commit 58e84910f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 92 additions and 10 deletions

View File

@ -12,6 +12,7 @@
- `[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))
- `[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))
- `[@jest/reporters]` Marks Reporter's hooks as optional ([#14433](https://github.com/jestjs/jest/pull/14433))
- `[jest-runtime]` Fix dynamic ESM import module bug when loaded module through `jest.isolateModulesAsync` ([14397](https://github.com/jestjs/jest/pull/14397))
### Chore & Maintenance

View File

@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`runs test with isolate modules async import 1`] = `
"Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites."
`;

View File

@ -0,0 +1,20 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {extractSummary} from '../Utils';
import runJest from '../runJest';
test('runs test with isolate modules async import', () => {
const {exitCode, stderr} = runJest('isolate-modules-async', [], {
nodeOptions: '--experimental-vm-modules --no-warnings',
});
const {summary} = extractSummary(stderr);
expect(summary).toMatchSnapshot();
expect(exitCode).toBe(0);
});

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {jest} from '@jest/globals';
test('should have a fresh module state in each isolateModulesAsync context', async () => {
await jest.isolateModulesAsync(async () => {
const {getState, incState} = await import('../main.js');
expect(getState()).toBe(0);
incState();
expect(getState()).toBe(1);
});
await jest.isolateModulesAsync(async () => {
const {getState, incState} = await import('../main.js');
expect(getState()).toBe(0);
incState();
expect(getState()).toBe(1);
});
});

View File

@ -0,0 +1,15 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
let myState = 0;
export function incState() {
myState += 1;
}
export function getState() {
return myState;
}

View File

@ -0,0 +1,8 @@
{
"name": "isolate-modules-async",
"type": "module",
"jest": {
"transform": {},
"testEnvironment": "node"
}
}

View File

@ -416,12 +416,15 @@ export default class Runtime {
query = '',
): Promise<VMModule> {
const cacheKey = modulePath + query;
const registry = this._isolatedModuleRegistry
? this._isolatedModuleRegistry
: this._esmoduleRegistry;
if (this._fileTransformsMutex.has(cacheKey)) {
await this._fileTransformsMutex.get(cacheKey);
}
if (!this._esmoduleRegistry.has(cacheKey)) {
if (!registry.has(cacheKey)) {
invariant(
typeof this._environment.getVmContext === 'function',
'ES Modules are only supported if your test environment has the `getVmContext` function',
@ -454,7 +457,7 @@ export default class Runtime {
context,
);
this._esmoduleRegistry.set(cacheKey, wasm);
registry.set(cacheKey, wasm);
transformResolve();
return wasm;
@ -462,7 +465,7 @@ export default class Runtime {
if (this._resolver.isCoreModule(modulePath)) {
const core = this._importCoreModule(modulePath, context);
this._esmoduleRegistry.set(cacheKey, core);
registry.set(cacheKey, core);
transformResolve();
@ -526,11 +529,11 @@ export default class Runtime {
}
invariant(
!this._esmoduleRegistry.has(cacheKey),
!registry.has(cacheKey),
`Module cache already has entry ${cacheKey}. This is a bug in Jest, please report it!`,
);
this._esmoduleRegistry.set(cacheKey, module);
registry.set(cacheKey, module);
transformResolve();
} catch (error) {
@ -539,7 +542,7 @@ export default class Runtime {
}
}
const module = this._esmoduleRegistry.get(cacheKey);
const module = registry.get(cacheKey);
invariant(
module,
@ -563,14 +566,18 @@ export default class Runtime {
return;
}
const registry = this._isolatedModuleRegistry
? this._isolatedModuleRegistry
: this._esmoduleRegistry;
if (specifier === '@jest/globals') {
const fromCache = this._esmoduleRegistry.get('@jest/globals');
const fromCache = registry.get('@jest/globals');
if (fromCache) {
return fromCache;
}
const globals = this.getGlobalsForEsm(referencingIdentifier, context);
this._esmoduleRegistry.set('@jest/globals', globals);
registry.set('@jest/globals', globals);
return globals;
}
@ -586,7 +593,7 @@ export default class Runtime {
return this.importMock(referencingIdentifier, specifier, context);
}
const fromCache = this._esmoduleRegistry.get(specifier);
const fromCache = registry.get(specifier);
if (fromCache) {
return fromCache;
@ -662,7 +669,7 @@ export default class Runtime {
}
}
this._esmoduleRegistry.set(specifier, module);
registry.set(specifier, module);
return module;
}