From 79d87a663478530d394977419d2e38a01116a4b9 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 22 Apr 2020 09:25:19 +0200 Subject: [PATCH] fix(esm): handle parallel imports --- CHANGELOG.md | 1 + .../__snapshots__/nativeEsm.test.ts.snap | 2 +- e2e/native-esm/__tests__/native-esm.test.js | 10 ++++++++++ e2e/native-esm/anotherDynamicImport.js | 8 ++++++++ packages/jest-runtime/src/index.ts | 17 +++++++++++------ 5 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 e2e/native-esm/anotherDynamicImport.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 02728ab400e6..4a9a97423f9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,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 ### Chore & Maintenance diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap index be56a4394e76..ca20b5785769 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 runs test with native ESM 1`] = ` Test Suites: 1 passed, 1 total -Tests: 9 passed, 9 total +Tests: 10 passed, 10 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 8f1800e57c12..f21670b89b86 100644 --- a/e2e/native-esm/__tests__/native-esm.test.js +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -90,3 +90,13 @@ test('handle unlinked dynamic imports', async () => { expect(deepDouble(4)).toBe(8); }); + +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 001de2f98ec9..6d3a81c53240 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -133,7 +133,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; @@ -357,11 +357,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);