Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add import.meta.jest #12698

Merged
merged 4 commits into from Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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