@mapbox/esbuild-jest v1.1.0
@mapbox/esbuild-jest
NOTE: This is a fork of esbuild-jest with some incompatible differences.
Our Jest preset and transformer for compiling files with ESBuild and generating accurate coverage.
š¦ npm install --save-dev @mapbox/esbuild-jest esbuild
esbuild-jest is not an officially supported Mapbox product, and is developed on a best-effort basis. Issues filed from third-party contributors may not be triaged in a timely manner.
Transforms
In your Jest configuration file:
{
"transform": {
"^.+\\.(tsx?|jsx?)$": "@mapbox/esbuild-jest"
}
}You can also specify ESBuild compatible options like so:
{
"transform": {
"^.+\\.(tsx?|jsx?|css)$": [
"@mapbox/esbuild-jest",
{
"loader": {
".css": "text"
}
}
]
}
}Preset
If you'd like to follow Mapbox conventions, you can use our Jest preset.
In your Jest configuration file:
{
"preset": "@mapbox/esbuild-jest"
}In this configuration, .js, .jsx, .ts, and .tsx files are transformed by ESBuild. .css files are loaded as plaintext.
Coverage is also enabled with high (80%) thresholds.
Directory structure
Our Jest preset expects files to be laid out in a certain way:
src/- source files for coverage in this directory.test/- test files in this directory, with a suffix of either.testor.spec.- Example:
index.test.ts
- Example:
How do I use jest.mock()?
@mapbox/esbuild-jest may require code changes in two ways:
1. Calls to jest.mock() are not hoisted to the top of the file.
2. ESBuild marks ESM imports as read-only when converting to CommonJS, which is in line with the ECMAScript specification, but breaks certain calls to jest.spyOn.
There are multiple ways around this.
Option 1
Stub the entire module in a separate file that is ESM imported before other files.
test_utils/myMock.ts:
jest.mock('../../src/myFile', () => {
})myFile.test.ts:
// Important that these are first.
import './test_utils/myMock.ts';
import { myFunction } from '../src/myFile';
// ...Option 2
Use the following workaround below that "allows" a module to be mocked.
Sourced from: https://github.com/evanw/esbuild/issues/412#issuecomment-723047255
export interface HasSpyOn {
spyOn(): jest.SpyInstance;
}
export function enableSpyOn<T extends Function>(fn: T): T & HasSpyOn {
if ('process' in globalThis && globalThis.process.env.NODE_ENV === 'test') {
let name = fn.name,
obj = { [name]: fn };
(fn as any) = function (this: any) {
return obj[name].apply(this, arguments);
};
(fn as any).spyOn = () => jest.spyOn(obj, name);
}
return fn as any;
}// file.ts
import { enableSpyOn } from 'helpers/enableSpyOn';
export const fn = enableSpyOn(function fn() {});
// file_test.ts
import { fn } from './file';
let spy = fn.spyOn();License
esbuild-jest is provided under the terms of the MIT License