Aller au contenu principal
Version: 27.1

Transformation de code

Jest exécute le code de votre projet en tant que JavaScript, mais si vous utilisez une syntaxe qui n'est pas prise en charge par Node.js (comme JSX, les types de TypeScript, les templates Vue, etc.), vous devrez transformer ce code en JavaScript ordinaire, comme vous le feriez lors de la création pour les navigateurs.

Jest prend en charge ceci via l'option de configuration transform.

Un transformateur est un module qui fournit une fonction synchrone pour transformer les fichiers source. Par exemple, si vous voulez être en mesure d'utiliser une nouvelle fonctionnalité du langage dans vos modules ou tests qui ne sont pas encore pris en charge par Node, vous pouvez brancher l'un des nombreux compilateurs qui compilent une future version de JavaScript en une version actuelle.

Jest mettra en cache le résultat d'une transformation et tentera d'invalider ce résultat en fonction d'un certain nombre de facteurs, comme la source du fichier transformé et la modification de la configuration.

Defaults#

Jest est livré avec un transformateur - babel-jest. Il chargera automatiquement la configuration Babel de votre projet et transformera tout fichier correspondant à la RegEx suivante : /\.[jt]sx?$/ signifiant tout fichier .js, .jsx, .ts et .tsx. En outre, babel-jest injectera le plugin Babel nécessaire pour le montage de simulation dont on parle dans Simulation module ES.

Si vous remplacez l'option de configuration transform, babel-jest ne sera plus actif, et vous devrez l'ajouter manuellement si vous souhaitez utiliser Babel.

Écriture de transformateurs personnalisés#

You can write your own transformer. L'API d'un transformateur est la suivante :

interface SyncTransformer<OptionType = unknown> {
/**
* Indique si le transformateur est capable d'instrumenter le code pour la couverture du code.
*
* Si la couverture V8 _n'est pas_ active, et c'est à `true`, Jest supposera que le code est instrumenté.
* Si la couverture V8 _n'est pas_ active, et c'est à `false`. Jest va instrumenter le code retourné par ce transformateur en utilisant Babel.
*/
canInstrument?: boolean;
createTransformer?: (options?: OptionType) => SyncTransformer<OptionType>;
getCacheKey?: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => string;
getCacheKeyAsync?: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => Promise<string>;
process: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => TransformedSource;
processAsync?: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => Promise<TransformedSource>;
}
interface AsyncTransformer<OptionType = unknown> {
/**
* Indique si le transformateur est capable d'instrumenter le code pour la couverture du code.
*
* Si la couverture V8 _n'est pas_ active, et c'est à `true`, Jest supposera que le code est instrumenté.
* Si la couverture V8 _n'est pas_ active, et c'est à `false`. Jest va instrumenter le code retourné par ce transformateur en utilisant Babel.
*/
canInstrument?: boolean;
createTransformer?: (options?: OptionType) => AsyncTransformer<OptionType>;
getCacheKey?: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => string;
getCacheKeyAsync?: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => Promise<string>;
process?: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => TransformedSource;
processAsync: (
sourceText: string,
sourcePath: Config.Path,
options: TransformOptions<OptionType>,
) => Promise<TransformedSource>;
}
type Transformer<OptionType = unknown> =
| SyncTransformer<OptionType>
| AsyncTransformer<OptionType>;
interface TransformOptions<OptionType> {
/**
* Si un transformateur fait de la résolution de module et lit des fichiers, il devrait remplir `cacheFS` de sorte que
* Jest évite de relire les mêmes fichiers, ce qui améliore les performances. `cacheFS` stores entries of
* <file path, file contents>
*/
cacheFS: Map<string, string>;
config: Config.ProjectConfig;
/** Une version stringifiée de la configuration - utile pour la suppression du cache. */
configString: string;
instrument: boolean;
// les noms sont copiés de babel : https://babeljs.io/docs/en/options#caller
supportsDynamicImport: boolean;
supportsExportNamespaceFrom: boolean;
supportsStaticESM: boolean;
supportsTopLevelAwait: boolean;
/** les options passées par l'utilisateur à travers la configuration de Jest */
transformerConfig: OptionType;
}
type TransformedSource =
| {code: string; map?: RawSourceMap | string | null}
| string;
// Config.ProjectConfig peut être vu dans le code [ici](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323)
// RawSourceMap provient de [`source-map`](https://github.com/mozilla/source-map/blob/0.6.1/source-map.d.ts#L6-L12)

As can be seen, only process or processAsync is mandatory to implement, although we highly recommend implementing getCacheKey as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. Vous pouvez utiliser @jest/create-cache-key-function pour vous aider à l'implémenter.

Notez que le support des modules ECMAScript est indiqué par les options supports* passées. Spécifiquement supportsDynamicImport : true signifie que le transformateur peut retourner des expressions import() , qui sont prises en charge par ESM et CJS. Si supportsStaticESM : true cela signifie que les instructions de premier niveau import sont prises en charge et que le code sera interprété comme ESM et non comme CJS. Consultez la documentation de Node pour plus de détails sur les différences.

Exemples#

TypeScript avec vérification de type#

Alors que babel-jest transpile par défaut les fichiers TypeScript, Babel ne vérifie pas les types. Si vous le souhaitez, vous pouvez utiliser ts-jest.

Transformation des images vers leur chemin#

L'importation d'images est un moyen de les inclure dans le paquet de votre navigateur, mais elles ne sont pas du JavaScript valide. Une façon de le gérer dans Jest est de remplacer la valeur importée par son nom de fichier.

fileTransformer.js
const path = require('path');
module.exports = {
process(src, filename, config, options) {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
},
};
jest.config.js
module.exports = {
transform: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/fileTransformer.js',
},
};