diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index c1d12d8deef9..e51bd9c6405c 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -269,7 +269,9 @@ class ScriptTransformer { throw new Error(makeInvalidTransformerError(transformPath)); } if (isTransformerFactory(transformer)) { - transformer = transformer.createTransformer(transformerConfig); + transformer = await transformer.createTransformer( + transformerConfig, + ); } if ( typeof transformer.process !== 'function' && diff --git a/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts b/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts index 7da15d4723f7..cd8e72c33555 100644 --- a/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts +++ b/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts @@ -234,6 +234,16 @@ jest.mock( {virtual: true}, ); +jest.mock( + 'async-factory', + () => ({ + async createTransformer() { + return {process: jest.fn().mockReturnValue({code: 'code'})}; + }, + }), + {virtual: true}, +); + jest.mock( 'factory-for-async-preprocessor', () => { @@ -551,6 +561,21 @@ describe('ScriptTransformer', () => { ).toBeDefined(); }); + it('handle async createTransformer', async () => { + config = { + ...config, + transform: [['\\.js$', 'async-factory', {}]], + }; + const scriptTransformer = await createScriptTransformer(config); + expect( + await scriptTransformer.transformSourceAsync( + 'sample.js', + '', + getTransformOptions(false), + ), + ).toBeDefined(); + }); + it('throws an error if createTransformer returns object without `process` method', async () => { config = { ...config, diff --git a/packages/jest-transform/src/types.ts b/packages/jest-transform/src/types.ts index e08b9e43b5f3..c92dc453a4a4 100644 --- a/packages/jest-transform/src/types.ts +++ b/packages/jest-transform/src/types.ts @@ -149,7 +149,7 @@ export type Transformer = export type TransformerCreator< X extends Transformer, TransformerConfig = unknown, -> = (transformerConfig?: TransformerConfig) => X; +> = (transformerConfig?: TransformerConfig) => X | Promise; /** * Instead of having your custom transformer implement the Transformer interface diff --git a/website/versioned_docs/version-29.3/CodeTransformation.md b/website/versioned_docs/version-29.3/CodeTransformation.md index 8b712c7e51c9..8907f2269623 100644 --- a/website/versioned_docs/version-29.3/CodeTransformation.md +++ b/website/versioned_docs/version-29.3/CodeTransformation.md @@ -125,7 +125,7 @@ type Transformer = type TransformerCreator< X extends Transformer, TransformerConfig = unknown, -> = (transformerConfig?: TransformerConfig) => X; +> = (transformerConfig?: TransformerConfig) => X | Promise; type TransformerFactory = { createTransformer: TransformerCreator; @@ -146,7 +146,7 @@ Semi-related to this are the supports flags we pass (see `CallerTransformOptions Though not required, we _highly recommend_ implementing `getCacheKey` as well, so we do not waste resources transpiling when we could have read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. -Instead of having your custom transformer implement the `Transformer` interface directly, you can choose to export `createTransformer`, a factory function to dynamically create transformers. This is to allow having a transformer config in your jest config. +Instead of having your custom transformer implement the `Transformer` interface directly, you can choose to export `createTransformer`, a possibly asynchronous factory function to dynamically create transformers. This is to allow having a transformer config in your jest config. :::note