Skip to content

Commit

Permalink
feat: add import.meta.jest (#12698)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Apr 20, 2022
1 parent 6c068ff commit d67f783
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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))
Expand Down
7 changes: 6 additions & 1 deletion docs/ECMAScriptModules.md
Expand Up @@ -23,14 +23,19 @@ 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';

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.
2 changes: 2 additions & 0 deletions e2e/native-esm/__tests__/native-esm.test.js
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions packages/jest-environment/src/index.ts
Expand Up @@ -28,6 +28,10 @@ export type ModuleWrapper = (
...sandboxInjectedGlobals: Array<Global.Global[keyof Global.Global]>
) => unknown;

export interface JestImportMeta extends ImportMeta {
jest: Jest;
}

export interface JestEnvironmentConfig {
projectConfig: Config.ProjectConfig;
globalConfig: Config.GlobalConfig;
Expand Down
14 changes: 13 additions & 1 deletion packages/jest-runtime/src/index.ts
Expand Up @@ -27,6 +27,7 @@ import stripBOM = require('strip-bom');
import type {
Jest,
JestEnvironment,
JestImportMeta,
Module,
ModuleWrapper,
} from '@jest/environment';
Expand Down Expand Up @@ -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;
},
});

Expand Down Expand Up @@ -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;
},
});
Expand Down

0 comments on commit d67f783

Please sign in to comment.