From 4fd65cd6b06b6d75ac0aa26ef63e6ee7656e6eb2 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 27 Jan 2021 09:42:44 -0800 Subject: [PATCH 01/12] feature: use ESM for test environment --- packages/jest-runner/src/runTest.ts | 33 ++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index d68c7cfb7677..7901d0e7df2c 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -6,6 +6,7 @@ * */ +import {pathToFileURL} from 'url'; import chalk = require('chalk'); import * as fs from 'graceful-fs'; import sourcemapSupport = require('source-map-support'); @@ -104,9 +105,35 @@ async function runTestInternal( } const transformer = new ScriptTransformer(config); - const TestEnvironment: typeof JestEnvironment = interopRequireDefault( - transformer.requireAndTranspileModule(testEnvironment), - ).default; + let TestEnvironment: typeof JestEnvironment; + try { + TestEnvironment = interopRequireDefault( + transformer.requireAndTranspileModule(testEnvironment), + ).default; + } catch (err) { + try { + const configUrl = pathToFileURL(testEnvironment); + + // node `import()` supports URL, but TypeScript doesn't know that + const importedConfig = await import(configUrl.href); + + if (!importedConfig.default) { + throw new Error( + `Jest: Failed to load mjs config file ${testEnvironment} - did you use a default export?`, + ); + } + + TestEnvironment = importedConfig.default; + } catch (innerError) { + if (innerError.message === 'Not supported') { + throw new Error( + `Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${testEnvironment}`, + ); + } + + throw innerError; + } + } const testFramework: TestFramework = interopRequireDefault( transformer.requireAndTranspileModule( process.env.JEST_JASMINE === '1' ? 'jest-jasmine2' : config.testRunner, From 92ed5b56baa41ef2f8e0c6b93f4e3bb741f643b2 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 27 Jan 2021 09:50:33 -0800 Subject: [PATCH 02/12] chore: add entry for 11033 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11beba266b50..98c58396fced 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - `[jest-transform]` Pass config options defined in Jest's config to transformer's `process` and `getCacheKey` functions ([#10926](https://github.com/facebook/jest/pull/10926)) - `[jest-worker]` Add support for custom task queues and adds a `PriorityQueue` implementation. ([#10921](https://github.com/facebook/jest/pull/10921)) - `[jest-worker]` Add in-order scheduling policy to jest worker ([10902](https://github.com/facebook/jest/pull/10902)) +- `[jest-runner]` Possibility to use ESM for test environment ([11033](https://github.com/facebook/jest/pull/11033)) ### Fixes From 6dac94afd0ca39dcd5cd9cb3035cfd2520c14a19 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 7 Apr 2021 10:19:30 -0700 Subject: [PATCH 03/12] fix: check for ESM error type --- packages/jest-runner/src/runTest.ts | 44 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index 63564a8b1191..396bd6c415f7 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -112,27 +112,31 @@ async function runTestInternal( transformer.requireAndTranspileModule(testEnvironment), ).default; } catch (err) { - try { - const configUrl = pathToFileURL(testEnvironment); - - // node `import()` supports URL, but TypeScript doesn't know that - const importedConfig = await import(configUrl.href); - - if (!importedConfig.default) { - throw new Error( - `Jest: Failed to load mjs config file ${testEnvironment} - did you use a default export?`, - ); - } - - TestEnvironment = importedConfig.default; - } catch (innerError) { - if (innerError.message === 'Not supported') { - throw new Error( - `Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${testEnvironment}`, - ); + if (err.code === 'ERR_REQUIRE_ESM') { + try { + const configUrl = pathToFileURL(testEnvironment); + + // node `import()` supports URL, but TypeScript doesn't know that + const importedConfig = await import(configUrl.href); + + if (!importedConfig.default) { + throw new Error( + `Jest: Failed to load mjs config file ${testEnvironment} - did you use a default export?`, + ); + } + + TestEnvironment = importedConfig.default; + } catch (innerError) { + if (innerError.message === 'Not supported') { + throw new Error( + `Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${testEnvironment}`, + ); + } + + throw innerError; } - - throw innerError; + } else { + throw err; } } const testFramework: TestFramework = interopRequireDefault( From 08dfd90b3c14bf7f885d31042ffbff203ccfc9f6 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 7 Apr 2021 10:29:15 -0700 Subject: [PATCH 04/12] test: dummy test using dummy ESM test env --- e2e/test-environment-esm/EnvESM.js | 16 ++++++++++++++++ .../__tests__/testUsingESMTestEnv.test.js | 11 +++++++++++ e2e/test-environment-esm/package.json | 5 +++++ 3 files changed, 32 insertions(+) create mode 100644 e2e/test-environment-esm/EnvESM.js create mode 100644 e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js create mode 100644 e2e/test-environment-esm/package.json diff --git a/e2e/test-environment-esm/EnvESM.js b/e2e/test-environment-esm/EnvESM.js new file mode 100644 index 000000000000..ab1391889ba0 --- /dev/null +++ b/e2e/test-environment-esm/EnvESM.js @@ -0,0 +1,16 @@ +/** + * 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. + */ + +import NodeEnvironment from 'jest-environment-node'; + +export default class Env extends NodeEnvironment { + constructor() { + super(); + this.global = global; + this.moduleMocker = {}; + } +} diff --git a/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js new file mode 100644 index 000000000000..e94d811f3306 --- /dev/null +++ b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js @@ -0,0 +1,11 @@ +/** + * 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. + */ +'use strict'; + +test('dummy', () => { + expect(1).toBe(1); +}); diff --git a/e2e/test-environment-esm/package.json b/e2e/test-environment-esm/package.json new file mode 100644 index 000000000000..351d1129865d --- /dev/null +++ b/e2e/test-environment-esm/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "/EnvESM.js" + } +} From 6fe357a5ea74cba7620675578f5c782f564c39d3 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 7 Apr 2021 12:00:59 -0700 Subject: [PATCH 05/12] chore: add prepare to build --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 2ce3d6be52db..045c260b733f 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "which": "^2.0.1" }, "scripts": { + "prepare": "yarn build", "build-clean": "rimraf './packages/*/build' './packages/*/tsconfig.tsbuildinfo'", "build": "yarn build:js && yarn build:ts", "build:js": "node ./scripts/build.js", From 94ec8de670e5986b72efde3a0599f3ab4caefaf1 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 7 Apr 2021 12:09:47 -0700 Subject: [PATCH 06/12] chore: cleanup prepare script --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 045c260b733f..2ce3d6be52db 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,6 @@ "which": "^2.0.1" }, "scripts": { - "prepare": "yarn build", "build-clean": "rimraf './packages/*/build' './packages/*/tsconfig.tsbuildinfo'", "build": "yarn build:js && yarn build:ts", "build:js": "node ./scripts/build.js", From f0e03c192c204133d4df1ed1d2307808aed10f77 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 21 Apr 2021 16:59:39 -0700 Subject: [PATCH 07/12] fix: alphabetical order --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 487c55308b83..357983b666b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - `[jest-runner]` [**BREAKING**] set exit code to 1 if test logs after teardown ([#10728](https://github.com/facebook/jest/pull/10728)) - `[jest-runner]` [**BREAKING**] Run transforms over `runnner` ([#8823](https://github.com/facebook/jest/pull/8823)) - `[jest-runner]` [**BREAKING**] Run transforms over `testRunnner` ([#8823](https://github.com/facebook/jest/pull/8823)) +- `[jest-runner]` Possibility to use ESM for test environment ([11033](https://github.com/facebook/jest/pull/11033)) - `[jest-runtime]` Support for async code transformations ([#11191](https://github.com/facebook/jest/pull/11191) & [#11220](https://github.com/facebook/jest/pull/11220)) - `[jest-reporters]` Add static filepath property to all reporters ([#11015](https://github.com/facebook/jest/pull/11015)) - `[jest-snapshot]` [**BREAKING**] Make prettier optional for inline snapshots - fall back to string replacement ([#7792](https://github.com/facebook/jest/pull/7792)) @@ -34,7 +35,6 @@ - `[jest-transform]` Support transpiled transformers ([#11193](https://github.com/facebook/jest/pull/11193)) - `[jest-worker]` Add support for custom task queues and adds a `PriorityQueue` implementation. ([#10921](https://github.com/facebook/jest/pull/10921)) - `[jest-worker]` Add in-order scheduling policy to jest worker ([10902](https://github.com/facebook/jest/pull/10902)) -- `[jest-runner]` Possibility to use ESM for test environment ([11033](https://github.com/facebook/jest/pull/11033)) ### Fixes From e1e71d136d684d7eb220122fbf71bf7f3034dda2 Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 21 Apr 2021 17:02:16 -0700 Subject: [PATCH 08/12] fix: test using a global var --- e2e/test-environment-esm/EnvESM.js | 1 + e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/e2e/test-environment-esm/EnvESM.js b/e2e/test-environment-esm/EnvESM.js index ab1391889ba0..ff8b0b97f535 100644 --- a/e2e/test-environment-esm/EnvESM.js +++ b/e2e/test-environment-esm/EnvESM.js @@ -11,6 +11,7 @@ export default class Env extends NodeEnvironment { constructor() { super(); this.global = global; + this.global.someVar = 42; this.moduleMocker = {}; } } diff --git a/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js index e94d811f3306..4fa1b72a9c13 100644 --- a/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js +++ b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js @@ -7,5 +7,5 @@ 'use strict'; test('dummy', () => { - expect(1).toBe(1); + expect(globalThis.someVar).toBe(1); }); From bc05a509ea6e5411f339a892e7637770d029786e Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Wed, 21 Apr 2021 17:02:30 -0700 Subject: [PATCH 09/12] fix: this package is a module --- e2e/test-environment-esm/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/test-environment-esm/package.json b/e2e/test-environment-esm/package.json index 351d1129865d..50f9418173ea 100644 --- a/e2e/test-environment-esm/package.json +++ b/e2e/test-environment-esm/package.json @@ -1,4 +1,5 @@ { + "type": "module", "jest": { "testEnvironment": "/EnvESM.js" } From a4b00c215230a150f95f162a71501089cec0829a Mon Sep 17 00:00:00 2001 From: Gilles Yvetot Date: Thu, 22 Apr 2021 15:47:43 -0700 Subject: [PATCH 10/12] fix: remove unused variables --- e2e/test-environment-esm/EnvESM.js | 2 -- e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/e2e/test-environment-esm/EnvESM.js b/e2e/test-environment-esm/EnvESM.js index ff8b0b97f535..642e2ef86abf 100644 --- a/e2e/test-environment-esm/EnvESM.js +++ b/e2e/test-environment-esm/EnvESM.js @@ -10,8 +10,6 @@ import NodeEnvironment from 'jest-environment-node'; export default class Env extends NodeEnvironment { constructor() { super(); - this.global = global; this.global.someVar = 42; - this.moduleMocker = {}; } } diff --git a/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js index 4fa1b72a9c13..de0c9a9d38c6 100644 --- a/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js +++ b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js @@ -7,5 +7,5 @@ 'use strict'; test('dummy', () => { - expect(globalThis.someVar).toBe(1); + expect(global.someVar).toBe(1); }); From 2b1bff272c1975ae29e21cc2c29f23c9df581441 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 30 Apr 2021 09:58:28 +0200 Subject: [PATCH 11/12] actually run the e2e test --- e2e/__tests__/testEnvironmentEsm.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 e2e/__tests__/testEnvironmentEsm.ts diff --git a/e2e/__tests__/testEnvironmentEsm.ts b/e2e/__tests__/testEnvironmentEsm.ts new file mode 100644 index 000000000000..1b604d3f9273 --- /dev/null +++ b/e2e/__tests__/testEnvironmentEsm.ts @@ -0,0 +1,20 @@ +/** + * 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. + */ + +import {resolve} from 'path'; +import {onNodeVersions} from '@jest/test-utils'; +import runJest from '../runJest'; + +// The versions where vm.Module exists and commonjs with "exports" is not broken +onNodeVersions('^12.16.0 || >=13.7.0', () => { + it('support test environment written in ESM', () => { + const DIR = resolve(__dirname, '../test-environment-esm'); + const {exitCode} = runJest(DIR); + + expect(exitCode).toBe(0); + }); +}); From 567de0d1982e0eab0f63c24ab7d3de9f391a1fbc Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 30 Apr 2021 10:00:18 +0200 Subject: [PATCH 12/12] fix test --- e2e/test-environment-esm/EnvESM.js | 4 ++-- .../__tests__/testUsingESMTestEnv.test.js | 2 +- e2e/test-environment-esm/package.json | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/e2e/test-environment-esm/EnvESM.js b/e2e/test-environment-esm/EnvESM.js index 642e2ef86abf..daf46b97fd90 100644 --- a/e2e/test-environment-esm/EnvESM.js +++ b/e2e/test-environment-esm/EnvESM.js @@ -8,8 +8,8 @@ import NodeEnvironment from 'jest-environment-node'; export default class Env extends NodeEnvironment { - constructor() { - super(); + constructor(...args) { + super(...args); this.global.someVar = 42; } } diff --git a/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js index de0c9a9d38c6..b60ff5d6d94f 100644 --- a/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js +++ b/e2e/test-environment-esm/__tests__/testUsingESMTestEnv.test.js @@ -7,5 +7,5 @@ 'use strict'; test('dummy', () => { - expect(global.someVar).toBe(1); + expect(global.someVar).toBe(42); }); diff --git a/e2e/test-environment-esm/package.json b/e2e/test-environment-esm/package.json index 50f9418173ea..32b3c79ef350 100644 --- a/e2e/test-environment-esm/package.json +++ b/e2e/test-environment-esm/package.json @@ -1,6 +1,7 @@ { "type": "module", "jest": { - "testEnvironment": "/EnvESM.js" + "testEnvironment": "/EnvESM.js", + "transform": {} } }