{"id":15342,"library":"jest-environment-emit","title":"Jest Environment Emitter","description":"jest-environment-emit is a utility package for Jest that overcomes the limitation of having only one test environment per project. It provides a mechanism to add multiple event handlers to any Jest test environment, acting similarly to multiple test reporters. The package offers `WithEmitter`, a higher-order function to wrap custom environments, and pre-wrapped `TestEnvironment` classes for `jest-environment-node` and `jest-environment-jsdom` via subpath exports. Currently at version 1.2.0, released in June 2025, the package maintains a steady release cadence, frequently addressing compatibility with new Jest versions (e.g., Jest 30 support in v1.2.0) and refining import/export mechanisms for robust ESM and CJS interoperability. Its primary differentiator is enabling modular, composable event-driven logic within the Jest testing lifecycle, which is otherwise restricted to a single environment definition. It ships with full TypeScript types, enhancing developer experience.","status":"active","version":"1.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/wix-incubator/jest-environment-emit","tags":["javascript","environment","jest","jest-environment","jest-circus","typescript"],"install":[{"cmd":"npm install jest-environment-emit","lang":"bash","label":"npm"},{"cmd":"yarn add jest-environment-emit","lang":"bash","label":"yarn"},{"cmd":"pnpm add jest-environment-emit","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required by Jest test environments.","package":"@jest/environment","optional":false},{"reason":"Peer dependency for Jest's type definitions.","package":"@jest/types","optional":false},{"reason":"Core Jest framework peer dependency.","package":"jest","optional":false},{"reason":"Optional peer dependency if using the 'jest-environment-emit/jsdom' variant.","package":"jest-environment-jsdom","optional":true},{"reason":"Optional peer dependency if using the 'jest-environment-emit/node' variant.","package":"jest-environment-node","optional":true}],"imports":[{"note":"The primary higher-order function to create custom environments with event emitting capabilities. Recommended for wrapping your own base environment.","wrong":"const WithEmitter = require('jest-environment-emit').WithEmitter;","symbol":"WithEmitter","correct":"import { WithEmitter } from 'jest-environment-emit';"},{"note":"This specifically exports a `TestEnvironment` class wrapped around `jest-environment-node`. Use the subpath import `/node` for this variant.","wrong":"import { TestEnvironment } from 'jest-environment-emit';","symbol":"TestEnvironment (Node)","correct":"import { TestEnvironment } from 'jest-environment-emit/node';"},{"note":"This specifically exports a `TestEnvironment` class wrapped around `jest-environment-jsdom`. Use the subpath import `/jsdom` for this variant.","wrong":"import { TestEnvironment } from 'jest-environment-emit';","symbol":"TestEnvironment (JSDOM)","correct":"import { TestEnvironment } from 'jest-environment-emit/jsdom';"},{"note":"Type definition for the event listener function. Crucial for TypeScript users to correctly type their subscription modules.","symbol":"EnvironmentListenerFn","correct":"import type { EnvironmentListenerFn } from 'jest-environment-emit';"}],"quickstart":{"code":"/** @type {import('jest').Config} */\nmodule.exports = {\n  testEnvironment: 'jest-environment-emit/node',\n  testEnvironmentOptions: {\n    eventListeners: [\n      './jest-setup-listener.js',\n      ['./jest-parametrized-listener.js', { some: 'options', token: process.env.API_TOKEN ?? '' }],\n    ]\n  },\n};\n\n// jest-setup-listener.js\n/** @type {import('jest-environment-emit').EnvironmentListenerFn} */\nconst setupListener = function (context, options) {\n  context.testEvents\n    .on('test_environment_setup', async ({ env }) => {\n      console.log('Test environment setup initiated!');\n      env.global.__MY_CUSTOM_GLOBAL__ = 'initialized from listener';\n    })\n    .on('test_start', ({ event, state }) => {\n      console.log(`Starting test: ${event.test.name}`);\n    })\n    .on('test_environment_teardown', async ({ env }) => {\n      console.log('Test environment teardown completed!');\n      delete env.global.__MY_CUSTOM_GLOBAL__;\n    });\n};\n\nexport default setupListener;\n","lang":"typescript","description":"Demonstrates configuring Jest to use `jest-environment-emit/node` and attaching multiple event listener modules. It includes an example listener module showing how to subscribe to various Jest lifecycle events to perform custom setup, teardown, or other actions."},"warnings":[{"fix":"Ensure your `jest` peer dependency is `>=30.0.0` or compatible. Review Jest's own breaking changes between your previous version and Jest 30.","message":"Version 1.2.0 introduced support for Jest 30. While this is a feature, environments relying on older Jest versions or custom Jest configurations might require updates to ensure full compatibility. Always verify your Jest setup when upgrading.","severity":"breaking","affected_versions":">=1.2.0"},{"fix":"Always use specific subpath imports like `jest-environment-emit/node` or `jest-environment-emit/jsdom` for the pre-wrapped `TestEnvironment` classes.","message":"Incorrect subpath imports for built-in environments. Trying to `import { TestEnvironment } from 'jest-environment-emit'` will fail as the main export is `WithEmitter`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to `jest-environment-emit@1.0.8` or newer, which includes fixes to make listeners resilient to errors. Ensure your listener functions handle their own errors gracefully.","message":"Earlier versions (prior to 1.0.8) could have listeners that were not resilient to errors, potentially causing entire test runs to fail if an individual listener threw an unhandled exception.","severity":"gotcha","affected_versions":"<1.0.8"},{"fix":"Upgrade to `jest-environment-emit@1.0.5` or newer. This version introduced fixes for `module.exports.default` fallback and ensured exclusive use of default and named exports, improving import reliability.","message":"Versions prior to 1.0.3/1.0.5 had issues with ESM/CJS export collisions and quirky import patterns, potentially leading to 'undefined' imports or incorrect module resolution, especially in mixed environments.","severity":"gotcha","affected_versions":"<1.0.5"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Use the correct subpath import for the desired environment, e.g., `import { TestEnvironment } from 'jest-environment-emit/node';`.","cause":"Attempting to import `TestEnvironment` directly from the main `jest-environment-emit` package, which only exports `WithEmitter` by default.","error":"TypeError: (0, jest_environment_emit_1.TestEnvironment) is not a constructor"},{"fix":"Ensure `jest-environment-emit` is installed. If using a specific subpath (e.g., `jest-environment-emit/node`), verify the path is correct and accessible from your Jest configuration file. This often happens if the package isn't in `node_modules` or a symlink is broken.","cause":"The package `jest-environment-emit` or its specific subpath export is not correctly resolved by Node/Jest.","error":"Jest: `testEnvironment` must be a path to a Node module. Error: Cannot find module 'jest-environment-emit'"},{"fix":"Verify that your listener module is correctly listed in `testEnvironmentOptions.eventListeners` in your Jest config and that it exports the listener function as a `default` export.","cause":"The `context.testEvents` object within your event listener function is `undefined` because the listener function was not called by `jest-environment-emit`.","error":"TypeError: Cannot read properties of undefined (reading 'on') at subscription (my-listener.js)"}],"ecosystem":"npm"}