Donc celui-ci était un peu dur pour travailler. La solution est assez simple mais il m'a fallu du temps pour la faire fonctionner.Le problème est que chaque fois que vous utilisez un module en plaisantant
- Configuration Fichiers
- Framework Setup Files
- test Fichiers
- fichiers Module
Ils sont tous chargés en dessous de façon
({"Objet.": Fonction (module, exportations, require, __ dirname, __ filen ame, global, jest) {/* Code du module à l'intérieur */ }});
Si vous avez un oeil à node_modules/jest-runtime/build/index.js:495:510
const dirname = (_path || _load_path()).default.dirname(filename);
localModule.children = [];
localModule.parent = mockParentModule;
localModule.paths = this._resolver.getModulePaths(dirname);
localModule.require = this._createRequireImplementation(filename, options);
const transformedFile = this._scriptTransformer.transform(
filename,
{
collectCoverage: this._coverageOptions.collectCoverage,
collectCoverageFrom: this._coverageOptions.collectCoverageFrom,
collectCoverageOnlyFrom: this._coverageOptions.collectCoverageOnlyFrom,
isInternalModule,
mapCoverage: this._coverageOptions.mapCoverage },
this._cacheFS[filename]);
this._createRequireImplementation(filename, options);
donne tous les modules d'une commande nécessite objet. Donc, en tant que tel, vous n'obtenez pas la fonction natif nécessaire du tout, n'importe où. Une fois que jest a commencé, chaque module chargé à partir de ce moment aura la fonction require
personnalisée de jest.
Lorsque nous chargeons un module, les méthodes requireModule
du jest-runtime
sont appelées. Voici un extrait de la même
moduleRegistry[modulePath] = localModule;
if ((_path || _load_path()).default.extname(modulePath) === '.json') {
localModule.exports = this._environment.global.JSON.parse(
(0, (_stripBom || _load_stripBom()).default)((_gracefulFs || _load_gracefulFs()).default.readFileSync(modulePath, 'utf8')));
} else if ((_path || _load_path()).default.extname(modulePath) === '.node') {
// $FlowFixMe
localModule.exports = require(modulePath);
} else {
this._execModule(localModule, options);
}
Comme vous pouvez le voir si l'extension du fichier est .node
il charge le module directement, sinon il appelle le _execModule
. Cette fonction est le même code que je posté plus tôt, qui fait la transformation de code
const isInternalModule = !!(options && options.isInternalModule);
const filename = localModule.filename;
const lastExecutingModulePath = this._currentlyExecutingModulePath;
this._currentlyExecutingModulePath = filename;
const origCurrExecutingManualMock = this._isCurrentlyExecutingManualMock;
this._isCurrentlyExecutingManualMock = filename;
const dirname = (_path || _load_path()).default.dirname(filename);
localModule.children = [];
localModule.parent = mockParentModule;
localModule.paths = this._resolver.getModulePaths(dirname);
localModule.require = this._createRequireImplementation(filename, options);
Maintenant, quand nous voulons modifier require
fonction pour notre test, nous avons besoin _execModule
d'exporter notre code directement. Ainsi, le code devrait être similaire au chargement d'un .node
modules
} else if ((_path || _load_path()).default.extname(modulePath) === '.mjs') {
// $FlowFixMe
require = require("@std/esm")(localModule);
localModule.exports = require(modulePath);
} else {
Mais ce faisant, cela signifierait patcher le code, que nous voulons éviter. Donc, ce que nous faisons à la place est d'éviter d'utiliser la commande jest directement, et de créer notre propre jestload.js
et de l'exécuter. Le code de plaisanterie de chargement est simple
#!/usr/bin/env node
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
cli = require('jest/bin/jest');
Maintenant, nous voulons modifier le _execModule
avant le chargement cli.Nous ajoutons donc ci-dessous le code
const jestRuntime = require("jest-runtime");
oldexecModule = jestRuntime.prototype._execModule;
jestRuntime.prototype._execModule = function (localModule, options) {
if (localModule.id.indexOf(".mjs") > 0) {
localModule.exports = require("@std/esm")(localModule)(localModule.id);
return localModule;
}
return oldexecModule.apply(this, [localModule, options]);
};
cli = require('jest/bin/jest');
maintenant temps pour un test
//__test__/sum.test.js
sum = require('../sum.mjs').sum;
test('adds 1 + 2 to equal 3',() => {
expect(sum(1, 2)).toBe(3);
});
test('adds 2 + 3 to equal 5',() => {
expect(sum(3, 2)).toBe(5);
});
Et un fichier sum.mjs
export function sum (x, y) { return x + y }
Maintenant, nous courons le test
La solution est disponible sur ci-dessous repo
https://github.com/tarunlalwani/jest-overriding-require-function-stackoverflow
Vous pouvez cloner et tester la solution en exécutant npm test
.
['transformer'] (https://facebook.github.io/jest/docs/fr/configuration.html#transform-object-string-string)? –
@OrB - merci, mais non, malheureusement. Ce dont j'ai besoin, c'est d'un niveau inférieur. Vous voulez remplacer le Node racine par un loader avec un loader qui supporte ES6. Mais compte tenu de mon édition, je ne suis même pas certain que Node utilise le résolveur de nœud racine, donc cela peut même pas être possible –
De votre utilisation de script npm, le [jest-cli] (https://github.com/facebook/jest /blob/77744a24816d0978b6c478987426c36d615864bd/packages/jest-cli/bin/jest.js) devrait être la première chose qui fonctionne. Vous pouvez essayer de modifier ce fichier localement, en corrigeant la fonction require avec 'require (" @ std/esm ")', avant 'require ('../ build/cli'). Run();'. Si cela fonctionne, vous pouvez au moins confirmer que votre idée est bonne. –