diff --git a/CHANGELOG.md b/CHANGELOG.md index 09845f3dadb5..7f1165f46273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixes - `[jest-runtime]` Support importing CJS from ESM using `import` statements ([#9850](https://github.com/facebook/jest/pull/9850)) +- `[jest-runtime]` Support importing parallel dynamic `import`s ([#9858](https://github.com/facebook/jest/pull/9858)) ### Chore & Maintenance diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap index 174a63b361ea..c16d98c7fafb 100644 --- a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap +++ b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap @@ -2,7 +2,7 @@ exports[`on node ^12.16.0 || >=13.2.0 runs test with native ESM 1`] = ` Test Suites: 1 passed, 1 total -Tests: 10 passed, 10 total +Tests: 11 passed, 11 total Snapshots: 0 total Time: <> Ran all test suites. diff --git a/e2e/native-esm/__tests__/native-esm.test.js b/e2e/native-esm/__tests__/native-esm.test.js index 6cf48b3811ec..05dc9e5fc328 100644 --- a/e2e/native-esm/__tests__/native-esm.test.js +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -95,3 +95,13 @@ test('handle unlinked dynamic imports', async () => { test('can import `jest` object', () => { expect(jestObject).toBeDefined(); }); + +test('handle dynamic imports of the same module in parallel', async () => { + const [{double: first}, {double: second}] = await Promise.all([ + import('../anotherDynamicImport.js'), + import('../anotherDynamicImport.js'), + ]); + + expect(first).toBe(second); + expect(first(2)).toBe(4); +}); diff --git a/e2e/native-esm/anotherDynamicImport.js b/e2e/native-esm/anotherDynamicImport.js new file mode 100644 index 000000000000..84b87a513c85 --- /dev/null +++ b/e2e/native-esm/anotherDynamicImport.js @@ -0,0 +1,8 @@ +/** + * 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. + */ + +export * from './index'; diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 39f0cbcb3cc8..33df2ba5dbe6 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -139,7 +139,7 @@ class Runtime { private _moduleMocker: typeof jestMock; private _isolatedModuleRegistry: ModuleRegistry | null; private _moduleRegistry: ModuleRegistry; - private _esmoduleRegistry: Map; + private _esmoduleRegistry: Map>; private _needsCoverageMapped: Set; private _resolver: Resolver; private _shouldAutoMock: boolean; @@ -358,11 +358,16 @@ class Runtime { }, }); - this._esmoduleRegistry.set(cacheKey, module); - - await module.link(this.linkModules.bind(this)); - - await module.evaluate(); + this._esmoduleRegistry.set( + cacheKey, + // we wanna put the linking promise in the cache so modules loaded in + // parallel can all await it. We then await it synchronously below, so + // we shouldn't get any unhandled rejections + module + .link(this.linkModules.bind(this)) + .then(() => module.evaluate()) + .then(() => module), + ); } const module = this._esmoduleRegistry.get(cacheKey);