Aller au contenu principal
Version : 27.x

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

Vous pouvez écrire votre propre transformateur. 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;
/** A stringified version of the configuration - useful in cache busting */
configString: string;
instrument: boolean;
// names are copied from babel: https://babeljs.io/docs/en/options#caller
supportsDynamicImport: boolean;
supportsExportNamespaceFrom: boolean;
/**
* The value is:
* - `false` if Jest runs without Node ESM flag `--experimental-vm-modules`
* - `true` if the file extension is defined in [extensionsToTreatAsEsm](Configuration.md#extensionstotreatasesm-arraystring)
* and Jest runs with Node ESM flag `--experimental-vm-modules`
*
* See more at https://jestjs.io/docs/27.x/ecmascript-modules
*/
supportsStaticESM: boolean;
supportsTopLevelAwait: boolean;
/** the options passed through Jest's config by the user */
transformerConfig: OptionType;
}

type TransformedSource =
| {code: string; map?: RawSourceMap | string | null}
| string;

// Config.ProjectConfig can be seen in code [here](https://github.com/jestjs/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323)
// RawSourceMap comes from [`source-map`](https://github.com/mozilla/source-map/blob/0.6.1/source-map.d.ts#L6-L12)

Comme on peut le voir, process ou processAsync est le seul qui doit obligatoirement être implémenté, bien que nous recommandons fortement d'implémenter également getCacheKey, afin de ne pas gaspiller des ressources pour transpiler le même fichier source alors que nous pouvons lire son résultat précédent sur le disque. Vous pouvez utiliser @jest/create-cache-key-function pour vous aider à l'implémenter.

remarque

ECMAScript module support is indicated by the passed in supports* options. 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.

astuce

Assurez-vous que TransformedSource contient une source map, afin qu'il soit possible de rapporter les informations de ligne avec précision dans la couverture de code et les erreurs de test. Les source maps en ligne fonctionnent également mais sont plus lentes.

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',
},
};