Aller au contenu

Packages populaires

La conformité à la spécification ne garantit pas le bon fonctionnement des bibliothèques réelles. Les moteurs JS qui réussissent 99 % des tests test262 échouent encore régulièrement avec le code de production, car les bibliothèques dépendent d’une longue liste de cas limites de la spécification : ordre précis des pièges Proxy, forme de Function.prototype.toString, comportement des expressions régulières avec des entrées délicates et interactions exactes entre l’ordre de Object.keys et les noms de propriétés calculés.

Phasis vérifie l’égalité octet par octet de 204 bibliothèques largement utilisées par rapport à Node.js (V8). Elles se trouvent dans tests/Popular/ du dépôt, et la CI les exécute à chaque modification du code source du moteur ou de la suite.

Couverture par catégorie

Catégorie Bibliothèques
Analyseurs / AST acorn 8.16.0, chevrotain 11.0.3, parse5 7.2.1, parsimmon 1.18.1, jsep 1.4.0, postcss-value-parser 4.2.0, acorn-walk 8.3.4, estraverse 5.3.0, escodegen 2.1.0, css-tree 3.0.4, sax 1.4.1, nearley 2.20.1
Templating / Markdown / HTML mustache 4.2.0, handlebars 4.7.9, marked 18.0.3, markdown-it 14.1.0 (+ markdown-it-emoji), markdown-table 3.0.4, showdown 2.1.0, cheerio 1.1.2, htmlparser2 11.0.0
Utilitaires / fonctionnel lodash 4.18.1, ramda 0.31.3, remeda 2.17.4, es-toolkit 1.27.0, immutable 5.1.3, immer 10.1.1, redux 5.0.1, deepmerge 4.3.1, dot-object 2.1.5, lodash.merge 4.6.2, lodash.clonedeep 4.5.0, extend 3.0.2, extend-shallow 3.0.2, mixin-deep 2.0.1, merge-options 3.0.4
Accès aux objets dequal 2.0.3, clsx 2.1.1, classnames 2.5.1, get-value 4.0.1, set-value 4.1.0, object.omit 3.0.0, object.pick 1.3.0, is-plain-obj 4.1.0, kind-of 6.0.3
Validation / schéma zod 4.4.3, yup 1.4.0, valibot 1.1.0, superstruct 2.0.2, validator 13.12.0, email-validator 2.0.4, ajv 8.17.1, @sinclair/typebox 0.34.42, runtypes 6.7.0, typanion 3.14.0, ow 2.0.0
Date / heure dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2
Mathématiques / nombres bignumber.js 11.1.1, decimal.js 10.6.0, numeral 2.0.6, jsbi 4.3.0, big.js 6.2.2, fraction.js 4.3.7, complex.js 2.4.2, simple-statistics 7.8.8
Hachage / cryptographie blueimp-md5 2.19.0, crypto-js 4.2.0, fnv-plus 1.3.1, murmurhash3js 3.0.1, hash-sum 2.0.0, jwt-decode 4.0.0, @noble/hashes 2.2.0, tweetnacl 1.0.3, aes-js 3.1.2, bcryptjs 3.0.2, xxhashjs 0.2.2, object-hash 3.0.0
Recherche / diff fuse.js 7.3.0, minisearch 7.1.1, diff 8.0.2, diff-match-patch 1.0.5, fast-deep-equal 3.1.3, fast-equals 5.2.2, fastest-levenshtein 1.0.16, lunr 2.3.9
JSON / formats de données json5 2.2.3, js-yaml 4.1.0, yaml 2.6.1, toml 3.0.0, smol-toml 1.3.1, fast-json-patch 3.1.1, jmespath 0.16.0, jsonata 2.0.6, jsonpath-plus 10.3.0, mingo 6.7.0, sift 17.1.3, fast-json-stable-stringify 2.1.0, safe-stable-stringify 2.5.0, json-stringify-safe 5.0.1, canonicalize 2.1.0, papaparse 5.5.4
Chaînes / linguistique he 1.2.0, slugify 1.6.9, camelcase 8.0.0, entities 6.0.1, pluralize 8.0.0, inflection 3.0.2, wcwidth 1.0.1, emoji-regex 10.4.0, unraw 3.0.0, jsesc 3.1.0, lower-case 2.0.2, upper-case 2.0.2, dot-case 3.0.4, pascal-case 3.1.2, snake-case 3.0.4, title-case 3.0.3, xregexp 5.1.1, escape-string-regexp 5.0.0, ansi-regex 6.1.0, strip-ansi 7.1.2, string-width 8.1.0
URL / web url-parse 1.5.10, qs 6.13.1, query-string 9.1.1, tldts 6.1.69, punycode 2.3.1, linkifyjs 4.3.1, ipaddr.js 2.2.0, uri-js 4.4.1, url-template 3.1.1, bowser 2.11.0
Compression / encodage / archives pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1
Couleur color-string 2.1.1, d3-color 3.1.0, chroma-js 3.1.2, color-name 2.0.0, tinycolor2 1.6.0, color 5.0.3
Clonage / égalité rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2
Format / affichage ms 2.1.3, bytes 3.1.2
ID / UUID uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3
Détection de type / glob type-detect 4.1.0, picomatch 4.0.2, minimatch 10.1.1, wildcard-match 5.1.4, glob-to-regexp 0.4.1, to-regex 4.0.4, array-uniq 3.0.0, array-unique 0.3.2
Semver / configuration semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0
Caches / performances lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0
Asynchrone / événements eventemitter3 5.0.1, eventemitter2 6.4.10, mitt 3.0.1, p-limit 7.1.1, p-queue 9.0.2, p-defer 5.0.0, p-retry 7.1.0, throttle-debounce 5.0.2, async 3.2.6
État réactif mobx 6.13.7, xstate 5.23.0, valtio 2.1.5, nanostores 1.0.1, jotai 2.16.1, redux-saga 1.3.0, redux 5.0.1
CSS / styles postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4
Build / AST / compilateurs magic-string 0.30.20, escodegen 2.1.0, acorn-walk 8.3.4, estraverse 5.3.0, @babel/parser 7.28.5, terser 5.46.0, prettier 3.3.3, svelte 5.55.7 (compilateur), typescript 6.0.3
MQTT / protocole mqtt-packet 9.0.4
GraphQL graphql-js 16.11.0
Coloration syntaxique highlight.js 11.11.1
Tests / assertions chai 6.2.1

Total : 204 bibliothèques reproduisent exactement la sortie de Node. Toutes sont épinglées sur la dernière version amont à la date de la dernière mise à jour.

Fonctionnement

Chaque scénario est un répertoire tests/Popular/<lib>/ contenant trois fichiers :

Text
tests/Popular/lodash/
├── lodash.js     ← vendored upstream library (untouched, UMD bundle)
├── runner.js     ← Phasis-side script that exercises the library
└── oracle.txt    ← Node.js output of running runner.js (committed)

tests/Popular/PopularPackagesTest.php est un test de fournisseur de données PHPUnit qui :

  1. Charge lodash.js + runner.js dans un new Phasis\Engine() vierge.
  2. Capture la sortie console.log dans un tampon.
  3. Vérifie que le tampon capturé est identique octet par octet à oracle.txt.

Régénérez un oracle avec :

Shell
node tests/Popular/gen-oracle.js tests/Popular/<lib>

(Utilisé lors de la mise à jour de la bibliothèque vendue avec le projet : relance le runner sous Node réel et remplace oracle.txt.)

Étape de validation CI

Workflow : .github/workflows/popular.yml.

Se lance lors des pushs et des pull requests vers main qui modifient src/, tests/Popular/, phpunit.xml.dist, les fichiers Composer ou le workflow lui-même, ainsi que lors d'un lancement manuel. Deux étapes :

  1. Côté Phasis — exécute la suite de tests PHPUnit popular, qui lance chaque bibliothèque via Phasis et compare le résultat à l'oracle validé dans le dépôt. Échec à la moindre différence d'un octet.
  2. Nouvelle vérification avec Node — exécute node tests/Popular/gen-oracle.js … sur chaque bibliothèque et vérifie que l'oracle fraîchement régénéré correspond à celui du dépôt. Détecte toute dérive lorsqu'une bibliothèque vendue avec le projet est mise à jour sans actualiser l'oracle.

Les deux étapes doivent réussir avant la fusion de la PR. Une réussite de test262 qui casse lodash n'est pas acceptable ; pas plus qu'une réussite de lodash qui casse test262.

Pourquoi ces bibliothèques

  • acorn — l'analyse est la partie la plus fragile de tout moteur JS. Elle met à l'épreuve chaque cas syntaxique particulier ajouté par le JS moderne. Si Phasis peut analyser du code moderne quelconque avec acorn, le runtime est fiable.
  • mustache.js — le templating fait partie des usages d'intégration explicitement visés par Phasis (le premier exemple concret de README est « les moteurs de templating »). Mustache met à l'épreuve l'itération, la résolution de portée et les transformations de chaînes dans le même ordre que les vrais modèles.
  • lodash — la bibliothèque utilitaire JS la plus utilisée au monde. Ses plus de 300 fonctions font appel indirectement à chaque méthode de la bibliothèque standard. Si lodash fonctionne, la transformation générique de données JS fonctionne.
  • marked — rendu Markdown. Mise à l'épreuve concrète des expressions régulières (en grand nombre) et de la manipulation de chaînes avec état interligne. Révèle les écarts entre le moteur d'expressions régulières PCRE2 (solution de repli de Phasis) et Irregexp de V8.
  • dayjs — les calculs de date et d'heure sont une source classique d'erreurs de décalage d'un jour qu'aucun cas test262 ne détecte. dayjs teste les variantes du constructeur, les calculs autour de limites mensuelles équivalentes au passage à l'heure d'été et le développement des jetons de format, dans les mêmes parties du code que celles utilisées par chaque bibliothèque de dates JS.
  • bignumber.js — l'arithmétique de précision arbitraire sans TypedArrays met à l'épreuve l'analyse des nombres sous forme de chaînes, les boucles de multiplication et division de grands entiers et le choix du mode d'arrondi — le tout en JS pur, l'environnement devant donc prendre en charge tous les coûts. Révèle toute anomalie subtile de conversion entre Number et String.
  • json5 — l'analyse souple de JSON repose fortement sur les expressions régulières à classes de caractères et la tokenisation avec état. Un bon indicateur de la justesse des expressions régulières et des limites de l'itération sur les chaînes.
  • fuse.js — un module UMD transpilé par Babel qui met à l'épreuve _classCallCheck (le modèle this instanceof Ctor utilisé par toutes les classes transpilées avant ES6) et l'algorithme complet de recherche floue bitap. Une structure commune aux bibliothèques transpilées par Babel : tout ce qui casse Fuse casse la moitié de l'écosystème npm.
  • handlebars — templating complet avec compilation puis rendu. Met à l'épreuve le chemin d'exécution sans eval via une seule énorme entrée compile(), le parcours de l'AST, la répartition des helpers via une table de recherche dynamique et la vérification de marqueurs SafeString qui utilise instanceof entre différents realms. Un point de comparaison avec le parcours de modèles plus simple de mustache.js.
  • zod — validation de schémas à l'exécution. Hiérarchies de classes complexes (ZodString, ZodObject, ZodArray, ZodUnion, …) avec chaînage de méthodes renvoyant des sous-classes affinées, mise en forme structurée des erreurs où la structure du tableau .issues côté JS doit correspondre octet par octet à celle de Node, et modèles de discriminateurs et de balises littérales. Met à l'épreuve le code de validation riche en objets utilisé dans la moitié des applications TypeScript modernes.
  • typescript — le véritable compilateur TypeScript exécuté sur le moteur intégré. Un compilateur minifié de 9 MB qui réanalyse du code TS arbitraire, parcourt l'AST et produit JS — le contenu JS pur le plus lourd qui soit. Si Phasis peut transcompiler les génériques, async/await, les enums et les hiérarchies de classes avec une sortie identique octet par octet à tsc, la sémantique du langage est fiable.
  • prettier — formateur JS au style affirmé. Formater JS avec JS fait passer chaque particularité de la spécification du moteur par le même flux de contrôle que celui qui formate le code : une charge de travail particulièrement exigeante.
  • svelte/compiler — compilateur autonome de Svelte. Analyse du code source .svelte, parcours de l'AST et production de JS pour les cibles client et SSR.
  • terser / @babel/parser / postcss — minificateur JS, analyseur JS, post-processeur CSS. Des dizaines de milliers de lignes de code minifié qui réanalysent des entrées arbitraires — un terrain propice à l'apparition de structures AST rares.
  • ajv — validateur de schémas JSON qui compile à la volée chaque schéma en une fonction de validation personnalisée via new Function(...). Met à l'épreuve le chemin du constructeur Function utilisé par la plupart des bibliothèques de schémas et de templating.
  • mobx — état réactif fondé sur Proxy. Chaque lecture d'une valeur observable passe par un piège Proxy get qui enregistre une dépendance ; chaque écriture déclenche des réactions. Mise à l'épreuve de l'infrastructure Proxy, des Maps, tableaux et objets imbriqués observables, ainsi que de l'ordonnanceur autorun.
  • cheerio / htmlparser2 — jQuery côté serveur reposant sur un analyseur HTML rapide. Analyse par moteur de sélecteurs, parcours de type DOM, manipulation d'attributs et sérialisation HTML dans un seul paquet.
  • graphql-js / jsonata — implémentation de référence GraphQL et langage de requête JSON. Les deux s'appuient fortement sur les schémas, la validation et les évaluateurs récursifs — typiques du code de « couche de données dans le navigateur ».
  • JSZip — générateur asynchrone d'archives ZIP. Planifie le travail via un ordonnancement fondé sur setImmediate et produit une véritable sortie binaire, mettant à l'épreuve la surface des temporisateurs et les chemins riches en Uint8Array.
  • moment / luxon — calculs de date et d'heure. moment est un UMD mutable, optimisé manuellement ; luxon en est la réécriture moderne immuable. Ensemble, ils couvrent toute la surface du formatage, de l'analyse et des calculs de mois et d'années équivalents entre fuseaux horaires.
  • mqtt-packet — codec MQTT 3.1.1 / 5.0 entièrement en JS. Empaquetage et décodage octet par octet, ainsi que les classes de caractères d'expressions régulières pour les caractères hors alphabet Base64, qui mettent à l'épreuve les limites de la grammaire Annex B.
  • xstate / valtio / nanostores / jotai / redux-saga — panorama de la gestion d'état moderne. Machines à états, état Proxy, stockage par atomes, atomes dérivés et exécuteurs d'effets fondés sur des générateurs : chaque bibliothèque met à l'épreuve une forme différente de réactivité.
  • escodegen / acorn-walk / estraverse / magic-string — outils AST. Génération de code, parcours et modification non destructive du code source : les briques de base de tout transformateur JS sur JS (outils de build, codemods, linters).
  • papaparse / lunr / yaml / sax / css-tree — analyseurs et tokeniseurs purs. CSV, index de recherche en texte intégral, YAML 1.2, XML en flux de type SAX et AST CSS. Des grammaires différentes, toutes de bons indicateurs de la lecture au niveau des caractères et du comportement des expressions régulières.

En ajouter d'autres

Ajoutez un nouveau répertoire sous tests/Popular/<name>/ avec la structure en trois fichiers, puis :

Shell
node tests/Popular/gen-oracle.js tests/Popular/<name>   # one-time, generates oracle.txt
git add tests/Popular/<name>

La suite PHPUnit le détecte automatiquement au prochain lancement, et la CI le prend en compte puisque la modification touche tests/Popular/.

Bons candidats à ajouter : chevrotain (combinateur d'analyseurs, met à l'épreuve les fermetures et les expressions régulières), nanoid (limites de la cryptographie et de l'aléatoire), date-fns (gestion des fuseaux horaires au-delà de dayjs).