From e0f8c1f82ba1ed3105d060caa4a5f66e7c00f2e3 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 11 Oct 2020 19:43:28 +0200 Subject: [PATCH] fix(esm): evaluate node core modules on dynamic import (#10622) --- CHANGELOG.md | 5 +-- .../__snapshots__/nativeEsm.test.ts.snap | 2 +- e2e/native-esm/__tests__/native-esm.test.js | 7 ++++ packages/jest-runtime/src/index.ts | 34 +++++++++---------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f75ab1c33046..26afbc282af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,10 @@ ### Fixes -- `[jest-runner, jest-runtime]` fix: `require.main` undefined with `createRequire()` ([#10610](https://github.com/facebook/jest/pull/10610)) +- `[jest-runner, jest-runtime]` `require.main` should not be `undefined` with `createRequire()` ([#10610](https://github.com/facebook/jest/pull/10610)) - `[jest-runtime]` add missing `module.path` property ([#10615](https://github.com/facebook/jest/pull/10615)) -- `[jest-runtime]` fix: add `mainModule` instance variable to runtime ([#10621](https://github.com/facebook/jest/pull/10621)) +- `[jest-runtime]` Add `mainModule` instance variable to runtime ([#10621](https://github.com/facebook/jest/pull/10621)) +- `[jest-runtime]` Evaluate Node core modules on dynamic `import()` ([#10622](https://github.com/facebook/jest/pull/10622)) - `[jest-validate]` Show suggestion only when unrecognized cli param is longer than 1 character ([#10604](https://github.com/facebook/jest/pull/10604)) - `[jest-validate]` Validate `testURL` as CLI option ([#10595](https://github.com/facebook/jest/pull/10595)) diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap index 280552b01f3f..84c3778f0791 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.7.0 runs test with native ESM 1`] = ` Test Suites: 1 passed, 1 total -Tests: 13 passed, 13 total +Tests: 14 passed, 14 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 fe0470fa4842..d9c834fb0d7c 100644 --- a/e2e/native-esm/__tests__/native-esm.test.js +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -49,6 +49,13 @@ test('should support importing node core modules', () => { }); }); +test('should support importing node core modules dynamically', async () => { + // it's important that this module has _not_ been imported at the top level + const assert = await import('assert'); + + expect(typeof assert.strictEqual).toBe('function'); +}); + test('dynamic import should work', async () => { const {double: importedDouble} = await import('../index'); diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 8977865777ce..b8c2fee5da1f 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -466,7 +466,7 @@ class Runtime { return this.loadEsmModule(modulePath, query); } - private async loadCjsAsEsm( + private loadCjsAsEsm( from: Config.Path, modulePath: Config.Path, context: VMContext, @@ -483,13 +483,7 @@ class Runtime { {context, identifier: modulePath}, ); - await module.link(() => { - throw new Error('This should never happen'); - }); - - await module.evaluate(); - - return module; + return evaluateSyntheticModule(module); } requireModule( @@ -1159,7 +1153,7 @@ class Runtime { private _importCoreModule(moduleName: string, context: VMContext) { const required = this._requireCoreModule(moduleName); - return new SyntheticModule( + const module = new SyntheticModule( ['default', ...Object.keys(required)], function () { // @ts-expect-error: TS doesn't know what `this` is @@ -1172,6 +1166,8 @@ class Runtime { // should identifier be `node://${moduleName}`? {context, identifier: moduleName}, ); + + return evaluateSyntheticModule(module); } private _getMockedNativeModule(): typeof nativeModule.Module { @@ -1667,7 +1663,7 @@ class Runtime { return {...this.getGlobalsFromEnvironment(), jest}; } - private async getGlobalsForEsm( + private getGlobalsForEsm( from: Config.Path, context: VMContext, ): Promise { @@ -1695,13 +1691,7 @@ class Runtime { {context, identifier: '@jest/globals'}, ); - await module.link(() => { - throw new Error('This should never happen'); - }); - - await module.evaluate(); - - return module; + return evaluateSyntheticModule(module); } private getGlobalsFromEnvironment(): JestGlobals { @@ -1753,4 +1743,14 @@ function notEmpty(value: T | null | undefined): value is T { return value !== null && value !== undefined; } +async function evaluateSyntheticModule(module: SyntheticModule) { + await module.link(() => { + throw new Error('This should never happen'); + }); + + await module.evaluate(); + + return module; +} + export = Runtime;