Jest: Meta : prise en charge native des modules ES

Créé le 19 janv. 2020  ·  131Commentaires  ·  Source: facebook/jest

EDIT : guide rapide pour commencer : https://jestjs.io/docs/en/ecmascript-modules

Le support ESM ne sera pas signalé dans une future version de Node 12 (peut-être pas avant avril https://github.com/nodejs/node/pull/29866#issuecomment-574055057) et il est déjà non signalé dans Node 13.2, donc je pense que c'est temps d'évaluer comment nous pouvons ajouter un support natif dans Jest. Je vais essayer de répertorier les fonctionnalités actuellement fournies par Jest qui sont affectées par le support ESM, et comment nous pouvons les résoudre/étudier.

Il y a le problème n°4842, mais je pense qu'il s'agit davantage d'un problème de discussion, alors que ce problème sera orienté vers la mise en œuvre effective du support et plus approprié à suivre pour ceux qui souhaitent simplement obtenir l'état de mise en œuvre actuel. Tous les commentaires ajoutés à ce problème _non_ liés à la façon dont nous pouvons mettre en œuvre la prise en charge des fonctionnalités énumérées ci-dessous seront marqués comme spam - veuillez orienter les solutions de contournement/discussions vers des problèmes distincts. N'hésitez pas non plus à nous dire si quelque chose en rapport avec les fonctionnalités d'ESM manque dans la liste !

Veuillez noter que Jest utilisera l'API vm (https://nodejs.org/api/vm.html) et au moment de la rédaction (nœud v13.6), les parties ESM de cette API sont toujours signalées ( --experimental-vm-modules ). Donc, dire que l'ESM n'est pas signalé est un peu abusif pour le moment. Mais je pense que nous devrions commencer à expérimenter et éventuellement fournir des commentaires au groupe de travail sur les

Enfin, j'écris ce numéro principalement pour les personnes qui mettront en œuvre le support, il sera donc un peu bas et spécifique au fonctionnement de Jest. Pour les personnes qui _juste_ veulent savoir si le support a atterri ou non, je recommande d'utiliser la merveilleuse "notification personnalisée" de GH et de ne s'abonner aux notifications qu'à la fermeture/réouverture.


  • [x] Exécuter le module dans le bon contexte

Nous réalisons des bacs à sable en exécutant un script dans un vm.Context (fourni par JSDOM ou par les API Node Core). Nous devons faire la même chose pour ESM, mais nous aurons besoin d'accéder au context pendant la construction du module, pas seulement lors de l'exécution du module. J'ai ouvert #9428 qui ajoute les API nécessaires à JestEnvironment .

  • [x] Globals

expect , test , beforeEach etc seront toujours ajoutés en tant que globals, rien ne devrait changer ici. jasmine global sera également toujours là.

  • [x] jest propriété "globale"

Ce n'est pas vraiment un global - c'est injecté dans la portée du module. Étant donné que la portée du module a disparu dans ESM, nous devons la déplacer quelque part. L'ajouter à import.meta semble naturel - il existe une option appelée initializeImportMeta que nous pouvons utiliser.

EDIT: La solution ici est de le récupérer via import {jest} from '@jest/globals' . Nous pourrions encore l'ajouter via import.meta à l'avenir, mais cela devrait suffire pour le moment.

  • [ ] jest.(do|un)mock

Étant donné qu'ESM a différentes "étapes" lors de l'évaluation d'un module, jest.mock ne fonctionnera pas pour les importations statiques. Cela peut cependant fonctionner pour les importations dynamiques, donc je pense que nous devons simplement être clairs dans la documentation sur ce qu'il prend en charge et ce qu'il ne prend pas en charge.

jest.mock appels import 'thing' en import('thing') ce qui devrait permettre au levage de fonctionner, mais c'est alors asynchrone. L'utilisation de await haut niveau est probablement une nécessité pour une telle approche. Je pense aussi que c'est suffisamment invasif pour justifier une option distincte. Quelque chose à discuter - nous n'avons pas besoin de prendre en charge tout ce que jest.mock peut faire pour une version initiale.

  • [ ] jest.requireActual

Je ne sais pas si cela devrait se comporter dans ESM. Devrions-nous fournir un jest.importActual et laisser requireActual évaluer en CJS ?

  • [x] import.meta

Le nœud a url comme seule propriété (pour l'instant, au moins). Nous devons nous assurer qu'il est également peuplé à Jest. Nous fournissons identifier au lieu de filename lors de la construction du module, donc je ne pense pas que cela se produira automatiquement, mais url est essentiellement filename passé bien que pathToFileURL .

Il y a aussi un PR ouvert pour import.meta.resolve : https://github.com/nodejs/node/pull/31032

  • [x] import thing from 'thing'

Cela devrait en fait être assez simple, nous avons juste besoin d'implémenter un linker où nous pouvons également transformer la source avant de la renvoyer, ce qui signifie que nous n'avons pas besoin de l'API de chargement (qui n'existe pas encore). Cela nous permet également de renvoyer des mocks (bien qu'ils devront provenir d'un répertoire __mocks__ ).

  • [x] import('thing')

Essentiellement le même que ci-dessus, mais passé en tant que importModuleDynamically lors de la construction du module. Prendra également en charge jest.mock , jest.resetModules etc plus proprement, donc susceptible d'être utilisé un peu.

Cela peut également être fait pour vm.Script via la même option.

  • [ ] Gestion des erreurs lors de l'évaluation

À l'heure actuelle, il s'agit d'une erreur d'exécution (par exemple, module introuvable), mais ce n'est pas nécessairement vrai avec ESM. Est-ce important pour nous ? Nous devrions vérifier que les erreurs sont toujours belles.

  • [x] module.createRequire

Nous devons gérer cela pour les personnes souhaitant utiliser CJS d'ESM. J'ai ouvert #9426 pour suivre cela séparément, car sa mise en œuvre n'est pas vraiment liée à la prise en charge d'ESM.

EDIT : implémenté dans #9469

  • [ ] module.syncBuiltinESMExports

https://nodejs.org/api/modules.html#modules_module_syncbuiltinesmexports. Est-ce qu'on s'en soucie, ou est-ce qu'il suffit d'en faire un no-op assez ? Je ne sais pas quel serait le cas d'utilisation dans Jest. Jouer avec les fonctions intégrées brise déjà le bac à sable et je ne pense pas que cela devrait avoir de l'importance.

EDIT: # 9469 en a fait un no-op. Je pense que c'est bien ?

  • [ ] Détecter si un fichier est censé être en mode ESM ou CJS

L'inspection du champ type dans le package.json un module semble raisonnable : https://nodejs.org/api/esm.html#esm_enabling. Devrions-nous également avoir notre propre indicateur de configuration ? Doit également respecter les fins de fichier.

https://github.com/nodejs/modules/issues/393

  • [x] moduleNameMapper

Je ne sais pas si cela a un impact sur quoi que ce soit. Je _pense_ pas puisque nous allons lier les modules ensemble nous-mêmes. Nécessite une enquête, cependant.

EDIT : C'est toute la logique de résolution, que nous contrôlons. Donc pas de changement ici.

  • [x] jest.config.mjs

Via #9291, nous soutenons jest.config.cjs - avons-nous besoin de faire quelque chose de spécial pour .mjs ? Utilisez probablement import('path/to/configFile.mjs') ce qui signifie qu'il devra être asynchrone. Est-ce un problème ? Cela pourrait valoir la peine de faire une résolution de configuration async dans Jest 25, donc ce n'est pas un bloqueur pour la prise en charge incrémentielle d'ESM dans Jest 25.

EDIT : #9431

  • [ ] Exportations de packages

Node prend en charge les exportations de packages , qui correspondent en quelque sorte au moduleNameMapper de Jest , mais fournit également des fonctionnalités d'encapsulation. Espérons que resolve implémentera cela, mais s'ils ne le font pas, nous devrons faire quelque chose. Peut-être suffira-t-il d'utiliser l'option pathFilter ? Incertain.

  • [ ] Module JSON/WASM

https://nodejs.org/api/esm.html#esm_experimental_json_modules. Avons-nous besoin de nous en soucier ? Probablement, surtout pour json . Il est trivial pour nous de prendre en charge import thing from './package.json' puisque nous contrôlons la phase de liaison, mais nous ne devrions probablement pas le faire par défaut car cela différera du nœud par défaut. Devrions-nous forcer les gens à définir une transformation pour cela ?

  • [x] Couverture de code

Est-ce que ça importe? Je ne pense pas que cela soit affecté car nous pouvons toujours transformer la source avec babel (peut-être que cela sera confondu par des déclarations import , probablement pas) et la couverture V8 ne devrait certainement pas s'en soucier. Il faudrait quand même vérifier.

  • [ ] Résolution de code asynchrone

Ce n'est absolument pas un bloqueur car la résolution de synchronisation fonctionnera très bien. Mais nous _pouvons_ utiliser une résolution asynchrone maintenant, ce qui est génial. Je me demande si nous devrions envisager d'utiliser à nouveau le module resolve hors de npm, car il prend déjà en charge l'async. Voir #9505.

  • [ ] Transformation de code asynchrone

Semblable à ci-dessus, ne bloquant pas, mais ce serait bien de le prendre en charge. Cela pourrait également rendre @jest/transformer plus utilisable dans d'autres environnements. Voir #9504.

  • [ ] Mauvaise performance lors de l'accès aux globals

En raison de #5163, nous avons l'option extraGlobals comme solution de contournement - cette solution de contournement n'est plus viable dans ESM. J'ai ouvert et problème avec le nœud ici : https://github.com/nodejs/node/issues/31658

ES Modules

Commentaire le plus utile

J'ai obtenu un support très basique avec #9772. Je n'ai testé que les cas les plus simples, et il existe de nombreuses limitations connues (notamment pas jest support d'objet

Tous les 131 commentaires

J'ai obtenu un support très basique avec #9772. Je n'ai testé que les cas les plus simples, et il existe de nombreuses limitations connues (notamment pas jest support d'objet

25.4.0 a été publié avec les premiers éléments de support. En plus du #9772 mentionné ci-dessus, j'ai également inclus #9842. En _théorie_, le mixage CJS et ESM devrait maintenant fonctionner correctement (🤞).

La principale fonctionnalité manquante est la prise en charge de l'objet jest . Je n'ai pas décidé si nous devions nous en tenir à import.meta ou obliger les gens à l'importer via import {jest} from '@jest/globals' . Commentaires appréciés !

Je n'ai pas encore écrit de docs pour cela, mais pour l'activer, vous devez faire 3 choses

  1. assurez-vous de ne pas exécuter les instructions de transformation import (définissez transform: {} dans la configuration ou assurez-vous que babel ne transforme pas le fichier en CJS, par exemple en évitant le modules option à preset-env)
  2. Exécutez node@^12.16.0 || >=13.2.0 avec le drapeau --experimental-vm-modules
  3. Faites votre test avec jest-environment-node ou jest-environment-jsdom-sixteen

Veuillez l'essayer et donner votre avis ! Si vous signalez des bogues, ce serait formidable si vous pouviez également inclure comment exécuter le même code (moins tout code spécifique au test) s'exécute dans Node. J'ai lu https://nodejs.org/api/esm.html _beaucoup_ au cours des dernières semaines, mais j'ai probablement raté quelque chose.

La principale caractéristique manquante est la prise en charge de l'objet de plaisanterie. Je n'ai pas décidé si nous devions le coller à import.meta ou obliger les gens à l'importer via import {jest} depuis '@jest/globals'.

Pour le cas d'utilisation dactylographié, il est préférable d'avoir une importation explicite.

Oui, j'ai ajouté (et je l'ai temporairement annulé) un package @jest/globals qui prend en charge cela, il sera donc disponible malgré tout. Je me demande s'il est logique de l'_également_ l'exposer sur import.meta . Je penche actuellement pour ne pas le faire, principalement parce qu'il est plus facile d'ajouter que de supprimer plus tard (et je ne suis personnellement pas fan des globals)

+1 pour l'import explicite, c'est un peu plus verbeux mais plus simple à comprendre

J'obtiens ceci dans Node 13.2 et Jest 25.4 : ES Modules are only supported if your test environment has the getVmContext function Qu'est-ce que je manque ?

@zandaqo Oh désolé, j'ai oublié ce point. Ajouté ci-dessus, mais c'est

Faites vos tests avec jest-environment-node ou jest-environment-jsdom-sixteen

ReferenceError: jest is not defined Je suppose que cela est dû au @jest/globals manquant

Oui, comme mentionné, cela ne fonctionnera que si vous n'utilisez pas l'objet jest .
Les mocks sont aussi probablement cassés, je ne les ai pas testés

J'ai compilé un projet très basique à partir de ce que je vois dans le répertoire de tests e2e ( e2e/native-esm/__tests__/native-esm.test.js ) et dans ce numéro. Et malheureusement, je n'arrive toujours pas à le faire fonctionner 🙃 Quelqu'un peut-il le vérifier par hasard ?

https://drive.google.com/file/d/1vyDZjsVKOTu6j55QA11GjO9E7kM5WX8_/view?usp=sharing

  • [x] blague version 25.4.0
  • [x] version de nœud v13.12.0
  • [x] package.json contient les options de plaisanterie recommandées et aucune transformation babel ne semble être en place

Exécution d'un exemple de script (juste en important la fonction double et en imprimant double(2) ):

npm run main

> [email protected] main /Users/ilya/Projects/jest-esm
> node src/main.js

(node:16961) ExperimentalWarning: The ESM module loader is experimental.
4

Lancer une blague avec un seul test pour la double fonction :

npm run test

> [email protected] test /Users/ilya/Projects/jest-esm
> jest

 FAIL  __tests__/native-esm.test.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/ilya/Projects/jest-esm/__tests__/native-esm.test.js:8
    import {double} from '../src/index.js';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime._execModule (node_modules/jest-runtime/build/index.js:1074:58)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.542s
Ran all test suites.

Vous devez exécuter le nœud avec --experimental-vm-modules et nommer soit .mjs soit "type": "module" dans package.json .

EDIT : vous avez probablement ce dernier étant donné qu'il fonctionne en dehors de Jest pour vous, il manque juste le drapeau expérimental vers Node

@SimenB oh wow il y a --experimental-vm-modules ET --experimental-modules . J'étais confus par le fait que --experimental-modules n'est pas requis à partir d'une version du nœud 13. Merci!

TLDR : node --experimental-vm-modules node_modules/jest/bin/jest.js fonctionne pour moi

Ouais, de l'OP

Veuillez noter que Jest utilisera l'API vm (https://nodejs.org/api/vm.html) et au moment de la rédaction (nœud v13.6), les parties ESM de cette API sont toujours signalées ( --experimental-vm-modules ). Donc, dire que l'ESM n'est pas signalé est un peu abusif pour le moment.

Génial que cela fonctionne pour vous, cependant!

(Je marquerai ces commentaires comme résolus)

@SimenB Merci pour ça ! Deux problèmes que je vois jusqu'à présent.

Numéro 1

  • Le fichier de test unitaire ESM importe la valeur par défaut du fichier ESM (fn en cours de test)
  • Le fichier ESM en cours de test importe par défaut à partir d'un package, qui exporte uniquement CJS
  • Résultats en erreur : ReferenceError: module is not defined dans le fichier de package CJS

Donc je pense que cela peut ne pas être correctement mis en œuvre?

Une instruction import peut référencer un module ES ou un module CommonJS

Cela fonctionne très bien lors de l'exécution de l'application. Les exportations nommées de CJS ne peuvent être importées qu'à l'aide de createRequire, mais les exportations par défaut peuvent simplement être importées.

Numéro 2

Lorsque je ne rencontre pas l'erreur ci-dessus, je frappe celle-ci :

TypeError: _vm(...).SyntheticModule is not a constructor

      at Runtime._importCoreModule (node_modules/jest-runtime/build/index.js:1198:12)

Détails du projet

  • Nœud 12.14.1
  • Blague et babel-blague 25.4.0
  • Dernière Babel avec targets: { node: 12 } et 2 plugins : babel-plugin-transform-import-meta et rewire-exports . (J'ai essayé de supprimer le plugin import-meta mais j'ai obtenu une erreur disant de le rajouter.)
  • testEnvironment: "node" est à peu près la seule configuration
  • node --experimental-vm-modules node_modules/jest/bin/jest.js

Si un dépôt de reproduction serait utile, faites-le moi savoir.

Merci @aldeed !

Je vais me pencher sur le problème 1, qui ressemble effectivement à un bug. EDIT : devrait être corrigé via #9850

Le problème 2 nécessite le nœud 12.16.0 : https://nodejs.org/docs/latest-v12.x/api/vm.html#vm_class_vm_syntheticmodule

Je vais changer le contrôle dans Jest (en ce moment, il vérifie vm.SourceTextModule qui est disponible dans plus de versions, mais nous avons également besoin de SyntheticModule ).

Confirmé que l'exécution avec 12.16.0 résout mon problème 2. Je testerai à nouveau le problème 1 après la publication de ce correctif. Sinon, j'attends l'objet jest pour des tests supplémentaires, et je suis d'accord pour qu'il doive être importé.

Super travail, @SimenB ! J'essaie cela sur un petit projet mais j'ai rencontré des problèmes avec les importations dynamiques. C'est l'erreur que je vois :

Module status must not be unlinked or linkingError [ERR_VM_MODULE_STATUS]: Module status must not be unlinked or linking

Si je supprime les importations dynamiques, le test s'exécutera (mais échouera pour d'autres raisons, bien sûr). Le même test fonctionne actuellement avec Mocha (qui a fourni le support ESM assez récemment).

Si cela peut aider, les importations dynamiques en question peuvent être vues ici : https://github.com/beejunk/firn.js/blob/switch-to-jest/lib/renderPage.js#L43 -L55

Le fichier de test est ici : https://github.com/beejunk/firn.js/blob/switch-to-jest/test/build.test.js. La version fonctionnelle de Mocha peut être vue sur la branche master.

Faites-moi savoir s'il y a d'autres informations qui pourraient être utiles.

Merci @beejunk ! Je me demandais s'il pouvait y avoir des conditions de concurrence entre import s qui importent le même module avant qu'il ne soit entièrement lié. Il semble que c'est ce que vous frappez ici. Je vais corriger ça aujourd'hui, merci pour le rapport !

EDIT : Corrigé dans #9858. J'ai copié le correctif dans votre dépôt :
image

Quelqu'un a-t-il réussi à le faire fonctionner avec TypeScript ? node --experimental-vm-modules node_modules/jest/bin/jest.js renvoie le même SyntaxError: Cannot use import statement outside a module , même si mon package.json a "type": "module" .

babel.config.cjs

module.exports = {
  presets: [
    '@babel/preset-typescript',
  ],
};

jest.config.cjs

module.exports = {
  testEnvironment: 'jest-environment-node',
  transform: {},
};

@dandv Vous rencontrez essentiellement ce cas : https://github.com/facebook/jest/pull/9772/files#r407255029

Pourriez-vous ouvrir un autre sujet ? Devra savoir quoi faire avec les extensions non-js

@SimenB : #9860. Merci d'avoir jeté un coup d'œil.

@aldeed @beejunk 25.5.0 a été publié avec des correctifs pour vos problèmes. Gardez les rapports de bugs à venir

Oh, en plus, cela inclut le support pour import { jest } from '@jest/globals' pour ceux d'entre vous qui attendent ça 👍

Merci pour le travail rapide sur tout ça, @SimenB ! Je pense avoir rencontré un autre problème.

J'ai expérimenté l'utilisation de paramètres de requête dans un chemin d'importation comme moyen de supprimer le cache du module sur un serveur de développement. L'idée est d'avoir un observateur de fichiers qui détecte les modifications dans un composant, puis met à jour le chemin d'importation avec un paramètre de requête arbitraire afin que le nouveau code soit immédiatement extrait lors du prochain chargement de la page sans avoir à redémarrer le serveur. Cela fonctionne lors de l'exécution du serveur de développement. Cependant, Jest renvoie l'erreur suivante :

Cannot find module '/path/to/project/components/BasePage.js?cache=0' from 'renderPage.js'

Voici un exemple d'utilisation des paramètres de requête : https://github.com/beejunk/firn.js/blob/switch-to-jest/lib/renderPage.js#L55 -L56

Si je supprime les paramètres de requête, les tests réussiront, mais pas de manière cohérente. Si j'exécute une seule suite (par exemple, npm test -- test/build.test.js ), les tests réussissent, mais si j'exécute tous les tests en même temps, ils échoueront la plupart du temps avec des erreurs ambiguës. Je suis toujours en train de creuser le problème des tests incohérents, mais je pensais d'abord signaler le problème du paramètre de requête.

Merci pour le rapport @beejunk. #6282 est censé gérer cela, mais cela veut aussi transmettre la requête aux transformateurs et autres, dont nous n'avons pas besoin ici. Il peut donc être judicieux de simplement prendre en charge la requête en interne dans l'environnement d'exécution pour le moment, et de laisser #6282 s'occuper de la transmission de cette requête.

J'ai ajouté un peu de code pour faire varier le cache du module par requête : https://github.com/facebook/jest/blob/d425a49bd575e7167bc786f3c4f2833589091fa1/packages/jest-runtime/src/index.ts#L330 -L334

Mais aucun code ne l'appelle jamais avec une requête. Je pense que nous devrions être capables de faire des resolvePath.split('?') et que tout devrait fonctionner.

En ce qui concerne les erreurs incohérentes, je regarderai si ce repo le reproduit. Je n'ai pas testé le code ESM avec des tests en parallèle, un seul test. Je ne sais pas pourquoi cela aurait un impact sur les choses, mais qui sait

Chose de requête

J'ai un problème qui, je pense, peut être lié à cela, mais je n'ai pas été résolu dans 25.X .

Je vais essayer de résumer le scénario ci-dessous :

  • Vous avez un test avec un script d'installation
  • Ce script d'installation nécessitera un fichier dynamiquement, comme dans :
    { default: generator } = require(path.resolve(f))
  • Tout ce qui se trouve à l'intérieur de f n'est pas transpilé, ce qui provoque une "erreur d'importation d'identifiant inattendue".

Cela se produit également si j'essaye avec import()

Puisque vous mentionnez la transpilation ; si vous avez une configuration qui transpile import en require ce problème n'est pas au bon endroit - ce problème concerne le support natif.


Cela dit, vous ne pouvez pas require ESM, et je n'ai pas encore pu ajouter de support pour import() de CJS car Node n'a pas d'API pour cela. La prise en charge de cela a atterri sur Node master, mais n'est pas encore publiée : https://github.com/nodejs/node/pull/32985. Comme on peut le voir dans les PR de la version liée, il viendra en 13.14.0 et 14.1.0. À ce stade, je mettrai en œuvre un support pour cela 👍

Vous devriez cependant pouvoir utiliser un fichier d'installation .mjs .

@SimenB C'est super, il semble fonctionner dans plusieurs fichiers de test maintenant ! C'est un peu un processus pour résoudre les différences entre les importations Babel et Node dans chaque fichier, ajouter une importation jest, etc., je peux donc rencontrer plus de problèmes en le faisant sur des centaines de fichiers de test.

Quelques choses qui sont plus de questions:

  • ce que vous avez dit dans votre commentaire précédent sur la prise en charge de import() de cjs, cela permettra-t-il également au fichier de configuration Jest d'être nommé jest.config.js ? Cela ne fonctionne actuellement que pour moi lorsqu'il est nommé jest.config.cjs et en utilisant module.exports = (l'erreur est TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: A dynamic import callback was not specified )
  • Le nom "@jest/globals" échoue à la règle eslint node/no-extraneous-import car il ne s'agit pas d'un package répertorié dans package-lock . Y a-t-il une raison à cette convention de nommage ? Est-il possible d'utiliser jest sans le @ ? Il est facile d'ignorer la règle, mais je me pose la question.
  • Question connexe, pourquoi jest global est-il différent des fns magiques comme test , describe , before , etc. ? Est-ce que tous ceux-ci devraient être importés maintenant aussi?
  • Lorsque cela sera finalisé, sera-t-il possible pour Jest de définir le drapeau --experimental-vm-modules ? Cela donne l'impression que cela n'est pas standard si cela ne fonctionne pas uniquement avec la commande jest . Si vous n'êtes pas en mesure de passer directement des indicateurs, vous pouvez éventuellement définir/modifier la variable d'environnement NODE_OPTIONS ?
  • Il semble maintenant que j'obtienne une erreur légèrement différente de celle d'avant lorsque j'essayais cela sur un nœud plus ancien, mais aucune erreur n'était claire sur le fait que la version minimale du nœud était le problème. Est-il facile d'ajouter une vérification de la version minimale avec un message d'erreur plus utile ?

cela permettra-t-il également au fichier de configuration Jest de s'appeler jest.config.js ?

Il peut être nommé .js si son package.json plus proche a type: 'module' . Sinon, pour utiliser ESM dans le fichier de configuration, il doit être nommé .mjs . Voir https://nodejs.org/api/esm.html#esm_enabling. Notez que le fichier de configuration s'exécute en dehors de Jest, nous n'avons donc pas beaucoup de contrôle. Pour le moment, nous ne prenons pas en charge la configuration asynchrone, mais await ing une promesse exportée serait trivial, PR bienvenue 🙂 #8357 est au point mort.

Je suis très surpris que vous obteniez A dynamic import callback was not specified cependant, nous ne chargeons pas le fichier de configuration dans une machine virtuelle... Pourriez-vous ouvrir un problème séparé ?

Le nom "@jest/globals" échoue à la règle eslint node/no-extraneous-import car il ne s'agit pas d'un package répertorié dans package-lock . Y a-t-il une raison à cette convention de nommage ? Est-il possible d'utiliser jest sans le @ ? Il est facile d'ignorer la règle, mais je me pose la question.

Vous devez ajouter un devDependency sur @jest/globals . Le package lui-même ne contient que des définitions de type. Il s'agit d'un package distinct de jest afin que les définitions de type fonctionnent correctement et que nous puissions générer une erreur s'il est chargé en dehors de l'environnement d'exécution Jest.

Je n'ai actuellement aucun plan pour changer cela, mais nous pourrions éventuellement déprécier ce package et exporter les types de jest . C'est un changement majeur, alors voyons plus tard

Question connexe, pourquoi jest global est-il différent des fns magiques comme test , describe , before , etc. ? Est-ce que tous ceux-ci devraient être importés maintenant aussi?

jest est comme require ou module objet de CJS en ce sens qu'il est unique par fichier, ce n'est pas réellement un global (c'est- globalThis.jest === undefined dire jest.mock('../../file.js') etc de fonctionner correctement par rapport au fichier dans lequel il a été injecté. Vous pouvez également choisir d'importer les globals réels, mais ils sont toujours disponibles en tant que globalThis.expect etc.

Lorsque cela sera finalisé, sera-t-il possible pour Jest de définir le drapeau --experimental-vm-modules ?

Je pense que nous attendrons que le nœud les désactive plutôt que de les définir en silence - ils sont signalés pour une raison, l'API peut changer à un moment donné. Nous pourrions ajouter une option qui définit NODE_OPTIONS Je suppose, je ne sais pas si cela change le runtime actuel ? Quoi qu'il en soit, aucun plan actuel pour cela.

Il semble maintenant que j'obtienne une erreur légèrement différente de celle d'avant lorsque j'essayais cela sur un nœud plus ancien, mais aucune erreur n'était claire sur le fait que la version minimale du nœud était le problème. Est-il facile d'ajouter une vérification de la version minimale avec un message d'erreur plus utile ?

Oui, j'ajouterai un meilleur message d'erreur ainsi qu'une documentation une fois que l'implémentation se stabilisera un peu. Étant donné que l'implémentation est protégée par un indicateur expérimental, je ne pense pas que quiconque trébuchera dessus.

@SimenB , j'ai mis à jour Jest vers 25.5.2 et maintenant tous les tests réussissent. Les paramètres de requête fonctionnent et les erreurs intermittentes que je voyais plus tôt ne se produisent plus. Merci encore pour tout votre travail!

D'accord, j'ai revu les erreurs lors de ma dernière exécution des tests, donc cela se produit toujours. Je vais voir si je peux trouver un moyen de reproduire et de rendre compte de manière cohérente.

Je pense avoir trouvé un moyen cohérent de reproduire le problème. Voici la branche à partir de laquelle je travaille : https://github.com/beejunk/firn.js/tree/switch-to-jest

Reproduire:

  1. Supprimez le cache Jest s'il existe. Je viens de supprimer manuellement /tmp/jest_rs .
  2. Exécutez npm test trois fois. Les deux premiers runs devraient réussir. Cependant, la troisième exécution devrait échouer.

Voici la trace de la pile que je vois lorsque l'erreur se produit :

    Error: 
        at invariant (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:1866:11)
        at Runtime.loadEsmModule (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:480:7)
        at Runtime.linkModules (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:548:19)
        at importModuleDynamicallyWrapper (internal/vm/module.js:397:21)
        at htmPreactPath (internal/process/esm_loader.js:31:14)
        at renderPage (/home/brian/Projects/firn.js/lib/renderPage.js:53:15)
        at map (/home/brian/Projects/firn.js/lib/build.js:43:12)
        at Array.map (<anonymous>)
        at build (/home/brian/Projects/firn.js/lib/build.js:36:43)
        at Object.<anonymous> (/home/brian/Projects/firn.js/test/build.test.js:57:5)

L'erreur semble provenir des importations dynamiques. Il n'y a pas de message d'erreur, donc je ne suis pas tout à fait sûr de ce qui se passe.

Remarque supplémentaire : si j'efface le cache de Jest et que je mets à jour le script de test en ajoutant --no-cache , je ne parviens pas à reproduire le problème.

Heh, j'étais paresseux là-bas et je n'ai pas fourni de message d'erreur approprié. Le problème est que l'environnement de test a été détruit, donc je suppose qu'il manque un await quelque part. Je n'ai rien vu en parcourant votre code, donc je vais devoir creuser un peu plus

@SimenB Voici une reproduction de ce problème de configuration ESM : https://github.com/facebook/jest/issues/9935

@SimenB J'ai créé un exemple minimal pour reproduire les erreurs Jest que j'ai mentionnées ci-dessus lors de l'utilisation d'importations dynamiques :

https://github.com/beejunk/jest-esm-dynamic-import-error

Merci pour la superbe reproduction @beejunk ! J'ai passé plus d'heures que je veux bien l'admettre ici, sans vraiment comprendre s'il s'agit d'un bug dans Jest ou dans Node. J'ai reproduit le comportement en utilisant uniquement des modules de noyau de nœud et l'ai signalé en amont, alors voyons ce qu'ils disent : https://github.com/nodejs/node/issues/33216

Merci de vous y être penché, @SimenB. Les tests semblent réussir systématiquement si j'ajoute le drapeau --no-cache , ce qui convient à mon cas d'utilisation. J'apprécie tout le travail !

Oui, j'ai remarqué ça aussi. Je pense que c'est une sorte de problème de synchronisation - sans cache, les choses sont suffisamment lentes pour que cela fonctionne.

@SimenB Merci d'avoir résolu #9935. J'y ai mentionné une deuxième préoccupation qui, je pense, est toujours valable. Lorsque type: "module" , jest --init génère toujours le fichier de configuration contenant module.exports . C'est relativement mineur à changer manuellement si vous savez ce que vous faites, mais je pense que si ESM n'est pas signalé dans Node et que beaucoup de gens commencent à faire des projets ESM, cela commencera à ressembler davantage à un bogue déroutant (c'est-à-dire un chemin heureux de jest --init && jest sur un nouveau projet ESM générera une erreur). Dois-je soumettre un problème différent spécifiquement sur l'amélioration de la logique d'initialisation ?

@aldeed es-tu sûr ? Le test en ce moment me donne un fichier mjs avec export default dedans. Je suppose que nous pourrions générer js et pas mjs , mais quand même. Il utilise la syntaxe ESM

@SimenB Eh bien, j'étais sûr jusqu'à ce que vous le demandiez. J'ai essayé et tu as raison. Peut-être que je l'ai d'abord fait avec une ancienne version de Node ou Jest ? Mépris.

C'est génial! Je viens de retravailler les tests dans l'une de mes bibliothèques pour utiliser les modules ES et j'ai abandonné Babel. Merci @SimenB !

Détecter si un fichier est censé être en mode ESM ou CJS

En parlant de cela, il existe de nombreux packages orientés navigateur/bundle qui utilisent la syntaxe "module":"<path to es module>" pour désigner leurs exportations de module ES. Il peut être prudent d'avoir un moyen de spécifier comment résoudre un package donné quels que soient les propres paramètres du package. Quelque chose comme moduleNameMapper mais pour spécifier si c'est CJS ou ESM.

salut @SimenB , une fois ce problème clos, cela signifie que ts-jest peut également annuler commonjs n'est-ce pas ? L'extension de fichier est-elle requise pour changer du côté du transformateur pour fonctionner avec esm ?

Par exemple, maintenant ts-jest compile ts en js pour commonjs , est-ce que esm nécessite l'extension de fichier mjs lors de la compilation à partir de ts à js ?

@zandaqo, nous ne prendrons pas en charge le champ modules , nous suivrons les spécifications du nœud et utiliserons exports : #9771. Vous pouvez cependant brancher votre propre résolveur pour prendre en charge modules si vous le souhaitez : https://jestjs.io/docs/en/configuration#resolver -string. Nous pourrions ajouter une autre option ( mainFields , comme webpack peut-être ?), mais cela viendra plus tard lorsque l'implémentation se stabilisera et que nous aurons moins d'inconnues inconnues 🙂


@ahnpnl #9860

Ciao les gars !
Juste une question : le billet de blog mentionne que, puisque les modules ES6 sont statiques, ils ne peuvent pas être moqués ; donc, en fait, il n'y a aucun moyen de se moquer d'un module A importé par un module B dans ES6 ?

@gabrieledarrigo j'utilise moduleNameMapper pour ça, par exemple :

    "moduleNameMapper": {
      "moduleA": "<rootDir>/test/moduleA-mock.js"
    },

@gabrieledarrigo tu peux faire

jest.mock('the-thing-i-want-to-mock', () => /* do whatever in here */);

let importedThing;

beforeAll(async () => {
  importedThing = await import('thing-that-imports-mocked-module');
});

Il vous suffit donc de rendre l'importation non statique et la moquerie fonctionnera.

Je ne suis pas sûr que cela fonctionne maintenant, car je n'ai pas encore câblé de résolutions fictives dans le chemin de code ESM. Je le ferai bientôt. Mais c'est _probablement_ que nous allons documenter les simulations de module pour l'ESM natif.

Comme mentionné dans les pots de blog, nous documenterons ces modèles à un moment donné, nous devons juste les comprendre 🙂

Une idée que nous avions était d'attendre le plus haut niveau d'attente, puis nous pourrions le faire avec un plugin babel.

@SimenB Tout d'abord, merci pour le travail génial ici :)

En fait, je suis confronté à un problème lorsque je souhaite créer un environnement personnalisé étendu à partir de jest-environment-node . J'ai besoin d'y importer l'implémentation de mon serveur, qui est écrite sous la forme esm. Mais il semble que l'environnement doit être défini comme cjs .
Ma question est la suivante : existe-t-il une option pour définir un environnement de test personnalisé en tant qu'esm pour pouvoir importer mon module de serveur ? Merci pour tout conseil.

@kuka-radovan pourriez-vous ouvrir une demande de fonctionnalité distincte pour cela ?

MISE À JOUR : ce problème est désormais suivi sur https://github.com/facebook/jest/issues/10025

@SimenB Merci pour les jest.mock conseils ci-dessus. Il se trouve que je convertis quelques fichiers qui en ont besoin aujourd'hui. Je peux confirmer que votre exemple fonctionne lorsque le module moqué est un package node_modules , mais cela ne fonctionne pas pour moi en moquant un module dans le même projet.

Voici un exemple simple :

// main.js
import secondary from "./secondary.js";

export default function main() {
  return secondary();
}

// secondary.js
export default function secondary() {
  return true;
}

// test.js
import { jest } from "@jest/globals";

jest.mock("./secondary.js");

let main;
let secondary;
beforeAll(async () => {
  ({ default: main } = await import("./main.js"));
  ({ default: secondary } = await import("./secondary.js"));
});

test("works", () => {
  secondary.mockReturnValueOnce(false); // TypeError: Cannot read property 'mockReturnValueOnce' of undefined
  expect(main()).toBe(false);
});

Exactement le même modèle fonctionne lorsque "./secondary.js" est un nom de package à la place. (Je pense que le package que j'ai essayé avec exporte CommonJS, si cela compte.)

Jest 26.0.1 avec nœud 12.16.3

Des idées, ou devrais-je soumettre un numéro complet séparé ?

EDIT : transform: {} dans la config, donc pas de Babel du tout

EDIT 2 : ça ne marche pas non plus :

jest.mock("./secondary.js", () => ({
  default: jest.fn()
}));

Un travail incroyable à ce sujet.

Cependant, à moins que je fasse quelque chose de mal, il ne semble pas encore possible d'utiliser import() dans un fichier de test CJS.

Je lance Jest avec node --experimental-vm-modules node_modules/jest/bin/jest.js et j'ai testEnvironment: 'node', transform: {} dans jest.config.js . C'est sur le nœud 14.2.0.

L'expression d'importation produit une erreur :

TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]:
A dynamic import callback was not specified.

Est-ce une limitation connue actuellement ? Je vois que https://github.com/nodejs/node/pull/32985 a maintenant atterri dans Node 14.1.0.

Oui, je ne l'ai pas encore mis en œuvre. Je vais probablement l'atterrir ce week-end.

@aldeed pourriez-vous ouvrir un problème séparé ? Je dois passer en revue et m'assurer que les simulations font partie de la résolution, et votre exemple semble être un bon cas de test 🙂

@SimenB Merci pour la réponse rapide. Je surveillerai quand il atterrira.

Étant donné que import dans les scripts peuvent être annulés en raison d'une régression (https://github.com/nodejs/node/issues/33166), attendons jusqu'à ce que cela s'installe

J'ai des problèmes en essayant de l'utiliser avec des fichiers de test .mjs . Si j'ai __tests__/my-test.mjs , j'obtiens

$ yarn test
yarn run v1.22.4
$ node --experimental-vm-modules node_modules/jest/bin/jest.js
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In C:\Users\Domenic\Dropbox\Programming\WIP\remember-to-eat
  1 file checked.
  testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 0 matches
  testPathIgnorePatterns: \\node_modules\\ - 1 match
  testRegex:  - 0 matches
Pattern:  - 0 matches
error Command failed with exit code 1.

Si j'ajoute

"testMatch": ["**/__tests__/**/*.mjs"]

à mon package.json, je reçois

$ yarn test
yarn run v1.22.4
$ node --experimental-vm-modules node_modules/jest/bin/jest.js
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In C:\Users\Domenic\Dropbox\Programming\WIP\remember-to-eat
  1 file checked.
  testMatch: **/__tests__/**/*.mjs - 0 matches
  testPathIgnorePatterns: \\node_modules\\ - 1 match
  testRegex:  - 0 matches
Pattern:  - 0 matches
error Command failed with exit code 1.

Cependant, si je supprime le "testMatch" puis renomme mon fichier en __tests__/my-test.js , cela fonctionne.

J'aimerais pouvoir utiliser systématiquement les extensions .mjs dans mon projet. Est-ce possible avec Jest ?

@domenic j'ai rencontré ça aussi. La solution est d'ajouter à la configuration "moduleFileExtensions": ["js", "mjs"] (en plus de "testMatch" ).

J'ai jeté un coup d'œil, et moduleFileExtensions est en effet nécessaire.

Jest obtient une liste de tous les fichiers du projet en exécutant hasteFS.getAllFiles() ici :

https://github.com/facebook/jest/blob/2460c059ad1dbf124466ac25c8d5ccfd74ae9f25/packages/jest-core/src/SearchSource.ts#L159 -L164

hasteFS est créé dans le cadre de la HasteMap avec la configuration extensions :

https://github.com/facebook/jest/blob/2460c059ad1dbf124466ac25c8d5ccfd74ae9f25/packages/jest-runtime/src/index.ts#L291


Cependant, je ne pense pas qu'il soit nécessaire de spécifier moduleFileExtensions dans ce cas. Nous forçons déjà à trouver .snap , devrions-nous également forcer les extensions JS bien connues ? Ceux-ci étant (à ma tête) js , mjs , cjs , jsx , ts et tsx ? Cela ralentira le crawl, mais je ne pense pas que cela ait un impact énorme. Je me trompe peut-être ? Par défaut, cela ne devrait pas être beaucoup plus lent car seuls cjs et mjs ne font pas déjà partie des modèles par défaut, mais pour les personnes qui ont des modèles personnalisés, cela pourrait ralentir les choses ?

Oui, ce serait idéal si, au moins en mode modules ES, .mjs fonctionnait simplement, sans avoir à ajouter moduleFileExtensions ou à modifier le testMatch par défaut.

Ce serait aussi bien si je pouvais exclure les fichiers .js ; quand j'ai essayé, j'ai eu

 Validation Error:

  moduleFileExtensions must include 'js':
  but instead received:
    ["mjs"]
  Please change your configuration to include 'js'.

Je me demande s'il est logique d'avoir un "mode ESM" qui ajouterait les extensions de fichier esm du nœud et aiderait également à compiler vers js en utilisant esm pour s'inscrire (#9860).


Sans js certaines choses se cassent en interne que nous chargeons dans le bac à sable (car elles utilisent la même implémentation require etc.). Nous devrions probablement corriger cela afin que l'utilisateur ne puisse pas nous casser.

Concernant le ralentissement, c'est déjà assez lent sur les gros projets, mais je ne sais pas si le nombre d'extensions impacte autant. Mais je suis d'accord pour que mjs et cjs soient ajoutés par défaut. Spécifier moduleFileExtensions: ['js'] écraserait les valeurs par défaut et accélérerait les choses, n'est-ce pas ? Alors peut-être documentez-le simplement comme un ajustement des performances.

Merci pour tout ce travail ! C'est certainement incroyable. J'ai suivi les 3 étapes ( "type": "module" sur mon package.json, "testEnvironment": "jest-environment-node" dans ma config jest et --experimental-vm-modules sur la CLI) et cela semble aussi bien fonctionner 🎉

Mais ensuite, j'essaie de lire et d'utiliser import.meta comme décrit dans la documentation Node.js (et qui semble déjà être implémenté à en juger par la case à cocher) pour créer __dirname , mais cela ressemble à import.meta échoue :

console.log(import.meta);

SyntaxError: [PATH]/files.test.js: Support for the experimental syntax 'importMeta' isn't currently enabled (31:20):
    Add @babel/plugin-syntax-import-meta (https://git.io/vbKK6) to the 'plugins' section of your Babel config to enable parsing.

Je n'ai pas de babel et je pensais que babel était laissé pour compte avec ce travail. Je reviendrai pour signaler si je peux le réparer d'une manière ou d'une autre sans installer babel.

Node.js v14.3.0, Jest v25.5.4

J'ai trouvé une solution de contournement pour le moment. Étant donné que j'exécute le script à partir du même répertoire où se trouve mon fichier dans ma bibliothèque , je peux simplement faire :

const __dirname = process.cwd();
const __filename = __dirname + "/files.test.js";

Je suivrai ce dépôt au cas où il y aurait une mise à jour, merci encore de l'avoir fait !

Vous devez explicitement désactiver Babel en utilisant transform: {} comme configuration

@SimenB Je peux confirmer que l'ajout de transform: {} fonctionné, merci ! J'ai mal compris ce point comme "ne pas ajouter de transformations" et non comme "supprimer les transformations" comme prévu.

BTW, les tests sont passés de 2,4 secondes à seulement 1,3 secondes et ils se sentent toujours plus rapides.

Le nœud 12 a été publié avec ESM non signalé (https://nodejs.org/en/blog/release/v12.17.0/). Comme indiqué dans l'OP, les API utilisées par Jest ne sont _pas_ signalées

@SimenB J'ai parcouru ce fil plusieurs fois mais je suis toujours bloqué (en utilisant le nœud 12.17).

Lors de l'exécution de Jest 26.0.1, j'obtiens cette erreur :

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /app/tests/setup.js
require() of ES modules is not supported.
require() of /app/tests/setup.js from /app/node_modules/@jest/transform/build/ScriptTransformer.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename setup.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /app/package.json.

J'ai transform: {}, et je fonctionne avec node --experimental-vm-modules node_modules/jest/bin/jest.js .

Qu'est-ce que je rate?

@aldarund pas sûr, pourriez-vous

@SimenB voici un yarn test https://github.com/aledalgrande/jest-example - J'ai essayé avec Node 13/14 et c'est le même résultat. Il me semble que le flux de la configuration globale n'a pas été mis à jour pour fonctionner avec ESM.

aussi, vous avez mentionné quelqu'un d'autre 😆

~Pas @simenB , mais @aledalgrande vous semblez avoir tout correct ici d'après ce que j'ai essayé, voyez mon projet entièrement exécuté sur ESM pour comparaison (configuration de plaisanterie dans le package.json ).~

~ Pour le déboguer si possible, je suggérerais de simplifier votre configuration de plaisanterie pour _seulement_ avoir les deux propriétés pertinentes, peut-être même dans le premier package.json . Ajoutez ensuite chacune des autres propriétés dont vous disposez actuellement pour voir laquelle fonctionne/n'a pas fonctionné.~

Ah le deuxième commentaire mentionne globalSetup et pas des tests normaux, nvm mon commentaire alors. Si je supprime la clé globalSetup dans Jest, le test s'exécute comme prévu dans cet exemple, mais la clé globalSetup ne fonctionne pas comme vous l'avez dit.

Aha, j'ai oublié la configuration globale et le démontage. Peut réparer

Salut @SimenB , encore moi. Les exportations nommées sont-elles prises en charge ? Avec Node.js, je peux importer et utiliser un package comme celui-ci :

import { customAlphabet } from "nanoid";

Cependant, lorsque vous essayez de faire un test, ce même code donne cette erreur :

SyntaxError: The requested module 'nanoid' does not provide an export named 'customAlphabet'

Pour les tests, je peux changer le code en ceci et cela fonctionne :

import nanoid from "nanoid";
const { customAlphabet } = nanoid;

Mais ensuite, la version Node.js cesse de fonctionner car il n'y a en fait aucun sport par défaut (mais pour une raison quelconque, l'exportation par défaut fonctionne avec Jest) :

SyntaxError: The requested module 'nanoid' does not provide an export named 'default'

Le code publié (le dépôt semble être en pleine évolution en ce moment) nanoid se termine ainsi, sans exportation par défaut :

export { nanoid, customAlphabet, customRandom, urlAlphabet, random }

Jest ne consomme que le point d'entrée "principal". « exportations » n'est pas encore pris en compte. Vous venez d'importer la version commonjs qui n'a que l'exportation par défaut.

Ah je vois, le package.json semble inclure ceci :

  "main": "index.cjs",
  "module": "index.js",
  "exports": {
    "./package.json": "./package.json",
    ".": {
      "require": "./index.cjs",
      "import": "./index.js",
      "browser": "./index.browser.js"
    },
    ...
  }
  ...

Donc, probablement, Node.js trouve la version du module, tandis que Jest utilise la version CommonJS qui n'a pas d'exportation nommée, n'est-ce pas ?

Je vais attendre que Package Exports soit vérifié, puis le tester, merci encore pour tout le travail ! Marquer ces 2 commentaires comme résolus jusque-là. Le test auquel je fais référence est celui-ci .

Je revisite cela pour voir comment cela fonctionne - mis à niveau vers Jest 26.0.1 et le nœud 14.4. Définissez package.json sur le type de module, définissez transform sur {} , env sur jest-environment-node et exécutez avec node --experimental-vm-modules . Maintenant, j'obtiens cette nouvelle erreur :

ES Modules are only supported if your test environment has the `getVmContext` function

Je n'ai pas pu trouver d'informations à ce sujet, à l'exception d'un journal des modifications de Jest indiquant que getVmContext avait été ajouté il y a quelque temps.

Des idées?

Pourriez-vous partager les parties pertinentes de votre package.json s'il vous plaît @cyberwombat ? Y compris le script de lancement que vous utilisez pour Jest.

Pour référence, voici à quoi cela ressemble pour moi sur un projet de travail :

{
  ...
  "type": "module",
  "scripts": {
    ...
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
  },
  "jest": {
    "transform": {},
    "testEnvironment": "jest-environment-node"
  },
  ...

Puis lancez-le avec npm test

@franciscop La mienne est fondamentalement la même. Nœud 14.4.0. Je peux exécuter le vôtre très bien. Je vais plonger dans les choses pour voir la différence.
package.json

{
  "type": "module",
  "devDependencies": {
    "jest": "^26.0.1",
  },
}

jest.config.js

export default {
  testEnvironment: 'jest-environment-node',
  setupFilesAfterEnv: ['./test/bootstrap.js'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/config/', '/<rootDir>/src/'],
  testRegex: '(\\.|/)(test|spec)\\.[jt]sx?$',
  transform: {
//    '^.+\\.jsx?$': 'babel-jest' // esm someday
  },
  transformIgnorePatterns: [],
  modulePaths: [
    '<rootDir>/test',
    '<rootDir>/src',
    '<rootDir>'
  ]
}

Scénario:
node --experimental-vm-modules node_modules/jest/bin/jest.js

Pas sûr, mais j'essaierais de travailler dans l'autre sens. Supprimez tout sauf transform: {} et testEnvironment: 'jest-environment-node' , et commencez à ajouter chacune des options jusqu'à ce que vous voyiez laquelle déclenche l'erreur précédente. Je soupçonne spécialement que transformIgnorePatterns _pourrait_ être en conflit avec transform , mais je ne suis pas très familier avec les options de plaisanterie.

Bonjour à tous! J'ai rencontré un problème lors de l'utilisation de Jest pour tester une application Express. Plus de détails ici . Je ne sais pas si cela est utile pour ce que vous faites/suivez ici :roll_eyes:

@x80486 J'ai rencontré exactement le même problème hier . J'ai répondu dans StackOverflow avec une explication plus longue de ma compréhension.

Edit: j'ai dévoilé mon commentaire précédent car il semble qu'il puisse être pertinent, ce "exports" semble être populaire, très probablement à partir de cet article sur les packages hybrides .

exports est suivi dans #9771

@franciscop ok problème résolu - il s'avère qu'il y a un conflit dans les packages - j'ai installé serverless-bundle ce qui provoque l'erreur ES Modules are only supported if your test environment has the getVmContext function . Je ne sais pas pourquoi - je suppose que son installation ne provoquerait pas de conflit en cours avec Jest, mais de toute évidence, c'est le cas.

@franciscop Je pense que la raison pour laquelle les problèmes liés à pkg.exports commencent à faire surface maintenant est que cette fonctionnalité n'a pas été signalée dans Node.js 14.x et que certains responsables de paquet (comme moi pour uuid ) ont commencé en ajoutant des champs pkg.exports . Ainsi, alors que vous aviez besoin d'un indicateur de ligne de commande pour activer cette fonctionnalité dans Node.js 12.x vous obtenez maintenant ce comportement par défaut.

Il faudra un certain temps pour que l'ensemble de l'écosystème s'adapte, alors merci d'avoir signalé des problèmes autour de ce sujet !

Pour ceux qui publient sur exports , au cas où il aurait été perdu dans le long fil de ce numéro, mon problème fermé à ce sujet (https://github.com/facebook/jest/issues/9565) a un exemple de la moduleNameMapper solution

Le problème globalSetup signalé en mai est probablement toujours là (Jest 26.1.0) ? Obtenir les mêmes erreurs que dans l'exemple de dépôt @aledalgrande fournit :

$ git clone [email protected]:aledalgrande/jest-example.git
$ cd jest-example
$ npm test

> @ test /Users/asko/Temp/jest-example
> node --experimental-vm-modules node_modules/jest/bin/jest.js --config=./jest.config.js

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/asko/Temp/jest-example/tests/setup.js
require() of ES modules is not supported.
require() of /Users/asko/Temp/jest-example/tests/setup.js from /Users/asko/Temp/jest-example/node_modules/@jest/transform/build/ScriptTransformer.js 

Pas de précipitation. Vérifié CHANGELOG et il n'a pas mentionné de correctif pour globalSetup/globalTeardown avec ES6.

Node.js 14.4.0, Jest 26.1.0


Mise à jour (13-août-20):

Toujours pas possible, Node.js 14.7.0, Jest 26.4.0

Côté avis mais cette question doit-elle être une question épinglée puisque c'est l'objet de la plaisanterie en ce moment ?

Avez-vous une idée de ce qui doit être fait pour consommer les reporters de test écrits dans les modules ES ?...
avec la dernière version de jest, j'obtiens une erreur qui indique essentiellement que testScheduler attend un journaliste personnalisé au format commonjs.


voir l'erreur

~/projects/esw-ts/lib/dist/test/testReporter.js:1
importer le système d'exploitation à partir de « os » ;
^^^^^^

SyntaxError : impossible d'utiliser l'instruction import en dehors d'un module
à wrapSafe (interne/modules/cjs/loader.js:1116:16)
à Module._compile (internal/modules/cjs/loader.js:1164:27)
à Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
à Module.load (internal/modules/cjs/loader.js:1049:32)
à Function.Module._load (internal/modules/cjs/loader.js:937:14)
à Module.require (internal/modules/cjs/loader.js:1089:19)
at require (internal/modules/cjs/helpers.js:73:18)
à /Users/manish.gowardipe/Desktop/projects/esw-ts/lib/node_modules/@jest/core/build/TestScheduler.js:418:65
à Array.forEach ()
à TestScheduler._addCustomReporters (/Users/manish.gowardipe/Desktop/projects/esw-ts/lib/node_modules/@jest/core/build/TestScheduler.js:411:15)

Bonjour, je souhaite tester le support natif des modules ES dans mon petit projet, mais je suis nouveau sur NodeJS et je me suis perdu dans ce numéro, j'aimerais avoir des conseils s'il vous plaît.

  • node --version : v14.5.0
  • yarn jest --version : 26.1.0
  • J'essaye de tester ce petit projet , c'est très simple.
  • J'ai mes fichiers comme ceci :

package.json

{
"jest": {
    "transform": {},
    "testEnvironment": "jest-environment-node"
  }
}

markov.test.js

const fs = require("fs");
const Markov = require("./markov.mjs");
// import fs from "fs";
// import Markov from "./markov.mjs";

const file = fs.readFileSync("text.txt", "utf8");
const markov = new Markov(file.toString());

test("Generates sentence with especified words", () => {
  expect(markov.makeSentence(8).length).toBe(8);
});
  • Je lance yarn jest . et cela me donne cette erreur :
    imagen

  • J'ai essayé avec node node_modules/jest/bin/jest.js . et cela me donne la même erreur.

@pepetorres1998 Ce fil concerne l'exécution de Jest avec des modules esm natifs, ce qui implique l'exécution de certains indicateurs/options - voir le commentaire ci-dessus pour savoir quoi faire (et définir "type": "module" dans package.json). Honnêtement, à ce stade, ce n'est pas tout à fait prêt pour les heures de grande écoute, donc si vous avez besoin que votre projet fonctionne, je pourrais rester avec Babel. Il existe un certain nombre de problèmes non contrôlés qui sont de véritables freins au spectacle. J'ai essayé joyeusement de changer il y a quelques semaines et je suis revenu en pleurant à Babel.

Est-ce que quelqu'un d'autre obtient un ReferenceError: jest is not defined en essayant de faire des choses comme jest.setTimeout(...) dans un fichier de test avec cette configuration ? Essayer de déterminer si cela est lié à l'environnement du module es, à la version du nœud, à la version jest ou à une combinaison de ces éléments. (Actuellement en utilisant le nœud v14.5.0, jest 26.1.0, environnement jest-environment-node)

ÉDITER
Je vois maintenant la case non cochée dans la description du problème pour la propriété jest 'global'. ??

@bdentino Je pense que vous pouvez essayer de l'importer explicitement import {jest} from '@jest/globals';

25.4.0 a été publié avec les premiers éléments de support. En plus du #9772 mentionné ci-dessus, j'ai également inclus #9842. En _théorie_, le mixage CJS et ESM devrait maintenant fonctionner correctement (🤞).

La principale fonctionnalité manquante est la prise en charge de l'objet jest . Je n'ai pas décidé si nous devions nous en tenir à import.meta ou obliger les gens à l'importer via import {jest} from '@jest/globals' . Commentaires appréciés !

Je n'ai pas encore écrit de docs pour cela, mais pour l'activer, vous devez faire 3 choses

  1. assurez-vous de ne pas exécuter les instructions de transformation import (définissez transform: {} dans la configuration ou assurez-vous que babel ne transforme pas le fichier en CJS, par exemple en évitant le modules option à preset-env)
  2. Exécutez node@^12.16.0 || >=13.2.0 avec le drapeau --experimental-vm-modules
  3. Faites votre test avec jest-environment-node ou jest-environment-jsdom-sixteen

Veuillez l'essayer et donner votre avis ! Si vous signalez des bogues, ce serait formidable si vous pouviez également inclure comment exécuter le même code (moins tout code spécifique au test) s'exécute dans Node. J'ai lu https://nodejs.org/api/esm.html _beaucoup_ au cours des dernières semaines, mais j'ai probablement raté quelque chose.

@SimenB
Ce fil est devenu énorme, et je pense que ceux qui veulent commencer avec des modules de plaisanterie / utiliser ES - auront des difficultés à trouver et à comprendre les directives de base pour commencer à le faire.
Y a-t-il une explication formelle dans la documentation sur l'ajout de jest à un projet de modules ES (ou un « démarrage rapide ») ?

@aldeed Concernant votre problème avec les modules moqueurs du même projet, avez-vous trouvé un correctif ? j'ai exactement le même problème

(Au fait, nous utilisons également reactioncommerce, alors bravo à ça haha)

@guilhermetelles non, et c'est suivi dans https://github.com/facebook/jest/issues/10025 maintenant.

J'utilise Jest 26.1.0, node version 14.6.0 avec --experimental-vm-modules , mais je vois toujours ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING lors de l'utilisation de import() dans CommonJS . Dois-je essayer de proposer une reproduction minimale et d'ouvrir un nouveau problème ?

En passant, existe-t-il un moyen simple de yarn link une copie de jest packages dans un projet maintenant que Jest utilise laine berry ? Je voulais essayer le dernier master juste au cas où cela aurait été implémenté par pas encore publié. J'essayais de faire quelque chose comme path/to/facebook/jest/.yarn/releases/yarn-sources.cjs link --all path/to/jest , mais cela échouerait. Exécuter manuellement quelque chose comme cd node_modules; for p in jest*; do if [[ -d path/to/jest/packages/$p ]]; then rm -rf $p; ln -s path/to/jest/packages/$p; fi; done ne fonctionnait pas non plus, je ne sais pas pourquoi.

@vvanpo import() dans CJS a été rétabli dans Node, vous pouvez suivre https://github.com/nodejs/node/issues/31860

En ce qui concerne l'exécution locale, je désinstalle généralement jest du projet que je veux tester et je fais ../jest/jest . Potentiellement nose ../jest/packages/jest/bin/jest.js . Assurez-vous simplement d'exécuter yarn et yarn build:js premier. Si ces instructions ne fonctionnent pas (j'écris de mémoire sur un téléphone dans un avion), veuillez ouvrir un problème (ou PR) afin que nous puissions correctement l'écrire dans le fichier CONTRIBUTING.md

Envisagez-vous de soutenir les importations cycliques ?

Si j'ai un fichier de test factice qui n'importe qu'un des deux fichiers qui ne s'importent que l'un l'autre, j'obtiens RangeError: Maximum call stack size exceeded . Si je supprime l'une des importations, le test réussit. Repo qui reproduit le problème .

Hey! J'ai configuré cela dans un projet de nœud vide et cela a très bien fonctionné, mais dans notre configuration de production, j'obtiens le message d'erreur suivant lorsque j'essaie d'exécuter des tests :

ES Modules are only supported if your test environment has the 'getVmContext' function

J'ai vu quelqu'un d'autre avoir le problème dans une réponse précédente (par @cyberwombat ), mais le paquet qu'ils ont trouvé coupable n'est pas présent dans notre fichier package.json . Comment en déduire le package (ou paramètre) qui pose problème ? J'ai essayé de supprimer systématiquement tous les paramètres de plaisanterie qui ne sont pas nécessaires pour que cela fonctionne, mais je n'ai pas réussi.

MISE À JOUR : J'ai réussi à progresser en faisant un léger changement dans jest-runtime . J'ai arrêté le débogueur à la ligne qui essaie d'accéder au contexte de la machine virtuelle et bien que la fonction n'existe pas vraiment, this.context (qu'elle devrait renvoyer), j'ai donc modifié cette ligne pour accéder directement à la propriété. Je sais que ce n'est probablement pas idéal, mais peut-être que @SimenB pourrait vous donner une idée de ce qui ne va pas ?

Merci d'avance pour toute aide

Envisagez-vous de soutenir les importations cycliques ?

Définitivement! Pourriez-vous ouvrir un autre sujet ?


@zsombro semble que vous exécutez une ancienne version de l'environnement de test. Si vous exécutez jest --show-config , qu'est-ce qui est affiché par testEnvironment ?

semble que vous exécutez une ancienne version de l'environnement de test. Si vous exécutez jest --show-config , qu'est-ce qui est affiché par testEnvironment ?

@SimenB, il dit ce qui suit :

"testEnvironment": "/Users/zberki/git/project-name/node_modules/jest-environment-node/build/index.js",
"testEnvironmentOptions": {},

Je viens de le régler sur jest-environment-node fonction de vos instructions

Avant de commencer ce processus, j'ai mis à jour jest en utilisant yarn add jest@latest . Dois-je mettre à niveau l'environnement séparément ?

MISE À JOUR : Il s'avère que je devais le faire. J'ai supprimé node_modules et yarn.lock pour effectuer une nouvelle installation et cela ne fonctionnait toujours pas. Cependant, si je l'ajoute manuellement en utilisant yarn add -D jest-environment-node cela semble fonctionner. Existe-t-il une meilleure façon de gérer cela? J'ai fait un projet de test minimaliste avant de le faire sur notre base de code et je n'ai pas eu à le faire

yarn list jest-environemnt-node (ou npm list jest-environemnt-node ) en listera probablement plusieurs, je suppose

├─ [email protected]
│  └─ [email protected]
└─ [email protected]

la version 26.2.0 est probablement celle que j'ai installée manuellement (au moins sur la base de package.json , ce qui signifie que jest-config a installé une version qui est apparemment obsolète ?

Vous avez quelque chose d'autre dans une ancienne version de jest-config ( react-scripts peut-être (une partie de create-react-app ) ?). Cette question n'est pas le lieu d'en discuter, tho 🙂

Ne pas pouvoir utiliser les modules ES dans mon globalSetup commence à faire mal.

Deux points:

  • cela doit-il être mentionné comme une case à cocher au début de ce numéro (afin qu'il soit suivi) ?
  • s'il y a un alpha/beta je pourrais essayer, prêt à le faire

JE:

  • J'ai vérifié que j'exécute la dernière version de Jest (26.4.0)
  • Jest-environment-node ajouté à mon projet
  • Vérifié qu'il n'est pas dupliqué en inspectant le fichier de verrouillage
  • Ajout de "testEnvironment": "jest-environment-node", dans jest.config.json
  • Ajout de import { jest } from '@jest/globals'; partout où la plaisanterie a été utilisée
  • Exécutez le paramètre de commande de test --experimental-vm-modules en les exécutant avec NODE_OPTIONS='--experimental-vm-modules' yarn jest

Et ça plante sur le code suivant :

jest.mock('../../some/other/path', () => ({
  someOtherMethod: jest.fn().mockImplementation(…),
}));

avec l'erreur suivante (raccourci - notez "Objets autorisés" !) :

ReferenceError: src/foo/bar.spec.js: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: jest
Allowed objects: Array, …, jest, …, unescape.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` (case insensitive) are permitted.

Je ne peux pas utiliser Babel, car il analyse de manière incorrecte les importations que j'ai corrigées pour qu'elles s'exécutent sur le nœud 14 sans Babel :

-import { map } from 'lodash';
+import lodash from 'lodash';
+const { map } = lodash;

Ce qui est malheureusement mal analysé par @babel/preset-env , ce qui donne TypeError: Cannot destructure property 'map' of '_lodash.default' as it is undefined. .

Quelqu'un peut-il m'aider à contourner ce problème s'il vous plaît ?

Edit : il semble que vous puissiez utiliser Jest + Babel sur du code compatible avec les modules ES natifs à l'aide d'importations CommonJS en effectuant ce correctif absolument dégoûtant :

jest.mock('common-js-module', () => ({
  __esModule: false,
  ...jest.requireActual('common-js-module'),
}));

Par ici,

import lodash from 'lodash';
const { map } = lodash;

est parfaitement consommé par le Node 14, et le code résultant de l'exécution de Jest+Babel,

var _lodash = _interopRequireDefault(require("lodash"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const {
  map
} = _lodash.default;

court aussi.

nous avons réussi à convertir tous nos tests de plaisanterie pour utiliser et importer notre code ES6, mais nous sommes restés bloqués sur quelques packages : à savoir puppeteer et uuid

L'application ne fonctionne que si nous les importons dans un objet (comme import uuid from 'uuid' ), mais les tests ne s'exécuteront pas de cette façon. Cependant, si nous remplaçons cette importation par la syntaxe de déconstruction (comme import { v4 } from 'uuid' , alors c'est l'inverse : le test fonctionne, mais l'application lève une exception.

à l'origine, nous avons suivi le guide et désactivé chaque transformation, mais nous avons également essayé de créer un espace de travail de fil où nous avons installé babel avec une configuration de nœud minimale, mais cela n'a pas résolu (ou aggravé) ce problème spécifique

Cependant, si nous remplaçons cette importation par la syntaxe de déconstruction (telle que import { v4 } de 'uuid', alors c'est l'inverse : le test fonctionne, mais l'application lève une exception.

Cela ressemble à votre application est compilée en CommonJS et n'utilise pas de modules dans la pratique. De "vrai" ESM import uuid from 'uuid' ne devrait pas fonctionner car uuid n'a pas d'exportation par défaut et expose une version ESM pour node .

@SimenB , pensez-vous qu'une documentation préliminaire à ce sujet serait une bonne idée ?

@grantcarthew définitivement ! J'avais espéré pouvoir passer plus de temps là-dessus et le stabiliser pour Jest 27, mais je doute que je pourrai le faire. Mais rédiger une page de documentation sur ce qui existe actuellement (et que c'est expérimental) semble être une bonne idée

@SimenB Je ne sais pas quel est l'état actuel du problème et si Jest devrait déjà travailler avec mon cas ou non, mais cela peut peut-être vous aider d'une manière ou d'une autre.

J'essaie de charger une bibliothèque uniquement esm (leur extension est cjs mais le type est module et le nœud semble convenir à cela) mais Jest ne parvient pas à la charger correctement avec l'erreur :

    C:\dev\codemirror-next-repro-cra\test-in-jest-esm\node_modules\style-mod\dist\style-mod.cjs:15
    export var StyleModule = function StyleModule(spec, options) {

Voici le problème que j'ai initialement ouvert https://github.com/codemirror/codemirror.next/issues/310. Et une repro pour Jest + ESM échoué avec le nœud 14.13.1 https://github.com/dubzzz/codemirror-next-repro-cra/tree/main/test-in-jest-esm

@dubzzz vous ne pouvez pas avoir ESM dans un fichier cjs . Le nœud échoue également

$ node node_modules/style-mod/dist/style-mod.cjs
(node:48829) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/simen/repos/codemirror-next-repro-cra/test-in-jest-esm/node_modules/style-mod/dist/style-mod.cjs:15
export var StyleModule = function StyleModule(spec, options) {
^^^^^^

SyntaxError: Unexpected token 'export'
    at wrapSafe (internal/modules/cjs/loader.js:1172:16)
    at Module._compile (internal/modules/cjs/loader.js:1220:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
    at Module.load (internal/modules/cjs/loader.js:1105:32)
    at Function.Module._load (internal/modules/cjs/loader.js:967:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

Oups désolé, j'ai essayé trop vite côté nœud. @nicolo-ribaudo a déjà signalé ce problème à l'auteur de la lib.
Vraiment merci beaucoup pour votre réponse rapide.

J'ai ouvert un PR pour certains (assez stub) docs ici: #10611. Je n'ai pas pris la peine d'énumérer les fonctionnalités/bugs manquants car je pense qu'il sera difficile de rester en phase avec la réalité, et examiner les problèmes de github est une meilleure approche car ils sont (espérons-le…) à jour.

@Pomax comme nouveau numéro, s'il vous plaît

Je viens d'ouvrir #10620 qui ajoute la prise en charge de import() de CJS. Demandé quelques fois sont comme https://github.com/facebook/jest/issues/9430#issuecomment -626054595

Bonjour. Il m'est assez difficile d'embrasser rapidement toute l'histoire derrière ESM dans node/jest, donc, probablement, je demande quelque chose d'évident ou de déjà répondu. Ai-je bien compris que le cas suivant n'est pas encore pris en charge ? Ou, j'espère, je fais quelque chose qui n'est pas correct ? Je le vis comme si import x from 'x' fonctionnait, mais pas la import { sub } from 'x' déstructuration.

package.json :

{
  "name": "jest-uuid",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "test": "node --experimental-vm-modules node_modules/.bin/jest"
  },
  "devDependencies": {
    "jest": "26.5.2"
  },
  "dependencies": {
    "uuid": "8.3.1"
  }
}

f.spec.js

import { v4 } from 'uuid';
test('', () => {});

test npm

> npm test

> [email protected] test /Users/igoro/p/tmp/jest-uuid
> node --experimental-vm-modules node_modules/.bin/jest

 FAIL  ./f.spec.js
  ● Test suite failed to run

    SyntaxError: The requested module 'uuid' does not provide an export named 'v4'

      at jasmine2 (node_modules/jest-jasmine2/build/index.js:228:5)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.879 s
Ran all test suites.
(node:94492) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
npm ERR! Test failed.  See above for more details.

Vous attendez le #9771. Avant cela, Jest ne sait pas qu'il est prudent de charger uuid tant qu'ESM (ou plutôt, quel fichier charger à quel moment il saurait qu'il s'agit d'ESM)

Cela suivra-t-il la propre convention de Node, où CJS ne peut être chargé que comme espace de noms, ou cela "améliorera-t-il" cela en autorisant une syntaxe qui ne fonctionne pas réellement dans Node lui-même ? (par exemple, Node n'autorise pas import { readdirSync } from "fs-extra" car il s'agit d'un package CJS, mais il autorise import fs from "fs-extra"; qui peut ensuite être décompressé à l'aide de const { readdirSync } = fs ).

(par exemple, Node n'autorise pas l'importation de { spawn } à partir de "child_process" car il s'agit d'un package CJS, mais il autorise l'importation de child_process à partir de "child_process" ; qui peut ensuite être décompressé à l'aide de const { spawn } = child_process ;).

C'est un exemple malheureux car le nœud considère "child_process" comme un module "intégré" (et non CJS), donc les exportations nommées fonctionnent. Le dernier nodejs utilise également une heuristique pour faire fonctionner de nombreuses exportations nommées pour les modules CJS. C'est peut-être la partie la plus difficile à imiter.

exemple mis à jour pour utiliser fs-extra place. Mais si l'exportation nommée figure sur la feuille de route de Node pour atterrir soit dans cette majeure, soit dans la prochaine majeure, alors Jest préemptant cela a du sens.

Cela devrait déjà être implémenté - Les modules de base de Node exposent des exportations nommées, contrairement à CJS "normal".

Le dernier nodejs utilise également une heuristique pour faire fonctionner de nombreuses exportations nommées pour les modules CJS. C'est peut-être la partie la plus difficile à imiter.

Avez-vous un lien avec le PR qui le met en œuvre ? Nous devrions essayer de l'imiter au moins 🙂

Le PR est ici : https://github.com/nodejs/node/pull/35249

L'heuristique sous- jacente est publiée sous la forme cjs-module-lexer (https://github.com/guybedford/cjs-module-lexer) mais @guybedford pourrait en savoir plus sur les écarts potentiels.

Je viens de jeter un œil à ceci et il semble que fs-extra utilise un modèle d'exportation comme :

module.exports = {
  // Export promiseified graceful-fs:
  ...require('./fs'),
  // Export extra methods:
  ...require('./copy-sync'),
  ...require('./copy'),
  ...require('./empty'),
  ...require('./ensure'),
  ...require('./json'),
  ...require('./mkdirs'),
  ...require('./move-sync'),
  ...require('./move'),
  ...require('./output'),
  ...require('./path-exists'),
  ...require('./remove')
}

Ce n'est actuellement pas un cas d'analyse de réexportations que nous détectons, mais il pourrait être possible d'ajouter à cjs-module-lexer si ce serait un cas utile pour gérer la détection d'exportations nommées.

Merci @jkrems & @guybedford ! J'ai ouvert un PR maintenant en utilisant ce module : #10673

La prise en charge exacte de fs-extra décrite dans https://github.com/facebook/jest/issues/9430#issuecomment -713204282 est désormais implémentée dans [email protected] , suivi en amont sur https://github. com/nodejs/node/pull/35745.

_Mise à jour : en testant cette version, elle détecte correctement toutes les fonctions fs-extra, mais malheureusement, elle ne détecte pas les fonctions natives de Node.js car elles ne sont pas analysables statiquement car elles sont remplies par une boucle for._

exploit : prend en charge les exportations nommées de CJS en tant qu'importations nommées ESM #10673

Je pensais que l'ESM natif ne prend en charge que l'importation de exports un module CommonJS en tant que default ?

Bonjour. Il m'est assez difficile d'embrasser rapidement toute l'histoire derrière ESM dans node/jest, donc, probablement, je demande quelque chose d'évident ou de déjà répondu. Ai-je bien compris que le cas suivant n'est pas encore pris en charge ? Ou, j'espère, je fais quelque chose qui n'est pas correct ? Je le vis comme si import x from 'x' fonctionnait, mais pas la import { sub } from 'x' déstructuration.

...
importer { v4 } depuis 'uuid' ;

Les modules ESM ne prennent pas en charge les importations de déstructuration, même si la syntaxe y ressemble. Pour que cela fonctionne, "export v4" est nécessaire. 'export default' ne correspondra pas.

https://kentcdodds.com/blog/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution

@sdwlig uuid fournit des exportations nommées et n'en a pas par défaut. Cela devrait fonctionner, mais le chargement d'esm à partir de packages avec le champ "exports" n'est pas encore pris en charge par jest. Commonjs est chargé à la place, ce qui n'est disponible que via l'exportation par défaut.
https://github.com/uuidjs/uuid/blob/master/src/index.js

Pourrions-nous ajouter la prise en charge de l'auto-référence du package (#10883) à cela ?

Cette page vous a été utile?
0 / 5 - 0 notes