diff --git a/CHANGELOG.md b/CHANGELOG.md index af72967aaa80..68d80297ca28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ - `[jest-runtime]` [**BREAKING**] `Runtime.createHasteMap` now returns a promise ([#12008](https://github.com/facebook/jest/pull/12008)) - `[jest-runtime]` Calling `jest.resetModules` function will clear FS and transform cache ([#12531](https://github.com/facebook/jest/pull/12531)) - `[jest-runtime]` [**BREAKING**] Remove `Context` type export, it must be imported from `@jest/test-result` ([#12685](https://github.com/facebook/jest/pull/12685)) +- `[jest-runtime]` Add `import.meta.jest` ([#12698](https://github.com/facebook/jest/pull/12698)) - `[@jest/schemas]` New module for JSON schemas for Jest's config ([#12384](https://github.com/facebook/jest/pull/12384)) - `[@jest/source-map]` Migrate from `source-map` to `@jridgewell/trace-mapping` ([#12692](https://github.com/facebook/jest/pull/12692)) - `[jest-transform]` [**BREAKING**] Make it required for `process()` and `processAsync()` methods to always return structured data ([#12638](https://github.com/facebook/jest/pull/12638)) diff --git a/docs/ECMAScriptModules.md b/docs/ECMAScriptModules.md index b4ad17d411b4..199b7ff61b8c 100644 --- a/docs/ECMAScriptModules.md +++ b/docs/ECMAScriptModules.md @@ -23,7 +23,7 @@ With the warnings out of the way, this is how you activate ESM support in your t ## Differences between ESM and CommonJS -Most of the differences are explained in [Node's documentation](https://nodejs.org/api/esm.html#esm_differences_between_es_modules_and_commonjs), but in addition to the things mentioned there, Jest injects a special variable into all executed files - the [`jest` object](JestObjectAPI.md). To access this object in ESM, you need to import it from the `@jest/globals` module. +Most of the differences are explained in [Node's documentation](https://nodejs.org/api/esm.html#esm_differences_between_es_modules_and_commonjs), but in addition to the things mentioned there, Jest injects a special variable into all executed files - the [`jest` object](JestObjectAPI.md). To access this object in ESM, you need to import it from the `@jest/globals` module or use `import.meta`. ```js import {jest} from '@jest/globals'; @@ -31,6 +31,11 @@ import {jest} from '@jest/globals'; jest.useFakeTimers(); // etc. + +// alternatively +import.meta.jest.useFakeTimers(); + +// jest === import.meta.jest => true ``` Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. diff --git a/e2e/native-esm/__tests__/native-esm.test.js b/e2e/native-esm/__tests__/native-esm.test.js index 73a652bdac5e..4a4088a7c2c2 100644 --- a/e2e/native-esm/__tests__/native-esm.test.js +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -28,8 +28,10 @@ test('should have correct import.meta', () => { expect(typeof require).toBe('undefined'); expect(typeof jest).toBe('undefined'); expect(import.meta).toEqual({ + jest: expect.anything(), url: expect.any(String), }); + expect(import.meta.jest).toBe(jestObject); expect( import.meta.url.endsWith('/e2e/native-esm/__tests__/native-esm.test.js'), ).toBe(true); diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index 67b57c37fa03..3005b3ef9a59 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -28,6 +28,10 @@ export type ModuleWrapper = ( ...sandboxInjectedGlobals: Array ) => unknown; +export interface JestImportMeta extends ImportMeta { + jest: Jest; +} + export interface JestEnvironmentConfig { projectConfig: Config.ProjectConfig; globalConfig: Config.GlobalConfig; diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 49eb7b38fe5b..c98f97f0c3a7 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -27,6 +27,7 @@ import stripBOM = require('strip-bom'); import type { Jest, JestEnvironment, + JestImportMeta, Module, ModuleWrapper, } from '@jest/environment'; @@ -499,8 +500,18 @@ export default class Runtime { return this.linkAndEvaluateModule(module); }, - initializeImportMeta(meta: ImportMeta) { + initializeImportMeta: (meta: JestImportMeta) => { meta.url = pathToFileURL(modulePath).href; + + let jest = this.jestObjectCaches.get(modulePath); + + if (!jest) { + jest = this._createJestObjectFor(modulePath); + + this.jestObjectCaches.set(modulePath, jest); + } + + meta.jest = jest; }, }); @@ -625,6 +636,7 @@ export default class Runtime { return this.linkAndEvaluateModule(module); }, initializeImportMeta(meta: ImportMeta) { + // no `jest` here as it's not loaded in a file meta.url = specifier; }, });