Zum Inhalt springen

Beliebte Pakete

Die Einhaltung der Spezifikation garantiert nicht, dass echte Bibliotheken funktionieren. JS-Engines, die 99 % von test262 bestehen, scheitern in Produktionscode noch regelmäßig an langen Listen von „Spezialfällen der Spezifikation“ – etwa Proxy-Traps in bestimmter Reihenfolge, Function.prototype.toString-Formen, Regex-Verhalten bei kniffligen Eingaben oder der genauen Wechselwirkung zwischen der Reihenfolge von Object.keys und berechneten Eigenschaftsnamen.

Phasis prüft 204 weit verbreitete Bibliotheken bytegenau gegen Node.js (V8). Sie befinden sich im Repo unter tests/Popular/; CI führt sie bei jeder Änderung am Engine-Quellcode oder an der Suite aus.

Abdeckung nach Kategorie

Kategorie Bibliotheken
Parser / 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
Hilfsfunktionen / funktional 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
Objektzugriff 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
Validierung / Schema 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
Datum / Uhrzeit dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2
Mathematik / Zahlen 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
Hashing / Kryptografie 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
Suche / Unterschiede 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 / Datenformate 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
Zeichenfolgen / Linguistik 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
Komprimierung / Kodierung / Archive pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1
Farben 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
Klonen / Gleichheit rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2
Format / Anzeige ms 2.1.3, bytes 3.1.2
IDs / UUIDs uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3
Typ-Erkennung / 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 / Konfiguration semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0
Caches / Leistung lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0
Asynchronität / Ereignisse 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
Reaktiver Zustand 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 / Styling postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4
Build / AST / Compiler 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 (compiler), typescript 6.0.3
MQTT / Protokoll mqtt-packet 9.0.4
GraphQL graphql-js 16.11.0
Syntaxhervorhebung highlight.js 11.11.1
Tests / Assertions chai 6.2.1

Insgesamt: 204 Bibliotheken geben exakt dieselbe Ausgabe wie Node aus. Alle sind auf die neueste Upstream-Version beim letzten Aktualisieren festgelegt.

So funktioniert es

Jedes Szenario ist ein tests/Popular/<lib>/-Verzeichnis mit drei Dateien:

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 ist ein PHPUnit-Test mit Datenprovider, der:

  1. lodash.js + runner.js in ein frisches new Phasis\Engine() lädt.
  2. Die Ausgabe von console.log in einem Puffer erfasst.
  3. Prüft, ob der erfasste Puffer bytegenau oracle.txt entspricht.

Eine Referenz neu erzeugen mit:

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

(Wird verwendet, wenn du die mitgelieferte Bibliothek aktualisierst – führt den Runner erneut unter echtem Node aus und überschreibt oracle.txt.)

CI-Prüfschranke

Workflow: .github/workflows/popular.yml.

Wird bei Pushes und Pull Requests an main ausgeführt, die src/, tests/Popular/, phpunit.xml.dist, Composer-Dateien oder den Workflow selbst ändern, sowie bei manueller Ausführung. Zwei Schritte:

  1. Phasis-Seite – führt die PHPUnit-Testsuite popular aus. Sie führt jede Bibliothek über Phasis aus und vergleicht die Ausgabe mit der eingecheckten Referenz. Schon ein abweichendes Byte lässt den Schritt fehlschlagen.
  2. Erneute Node-Prüfung – führt node tests/Popular/gen-oracle.js … für jede Bibliothek aus und prüft, ob die neu erzeugte Referenz mit der eingecheckten übereinstimmt. Erkennt Abweichungen, wenn eine mitgelieferte Bibliothek aktualisiert wurde, ohne die Referenz zu aktualisieren.

Beide Schritte müssen erfolgreich sein, bevor der PR zusammengeführt wird. Ein Erfolg bei test262, der lodash beeinträchtigt, ist nicht akzeptabel; ebenso wenig ein Erfolg bei lodash, der test262 beeinträchtigt.

Warum diese Bibliotheken

  • acorn — Das Parsen ist die anfälligste Stelle jeder JS-Engine. Es prüft jeden syntaktischen Sonderfall, den modernes JS mitbringt. Wenn Phasis beliebigen modernen Code mit acorn parsen kann, ist die Laufzeitumgebung solide.
  • mustache.js — Templating zählt zu den Einbettungsfällen, auf die Phasis ausdrücklich ausgelegt ist (das erste konkrete Beispiel in der README sind „templating engines“). Mustache prüft Iteration, Bereichsauflösung und String-Transformationen in der Reihenfolge echter Templates.
  • lodash — die meistgenutzte JS-Hilfsbibliothek weltweit. Ihre über 300 Funktionen greifen indirekt auf jede Methode der Standardbibliothek zu. Wenn lodash funktioniert, funktioniert auch generisches JS zur Datentransformation.
  • marked — Markdown-Rendering. Praxisnah und prüft reguläre Ausdrücke (sehr viele) sowie String-Manipulation mit zeilenübergreifendem Zustand. Macht Abweichungen zwischen der Regex-Engine PCRE2 (Fallback von Phasis) und V8s Irregexp sichtbar.
  • dayjs — Datums- und Zeitberechnungen sind eine klassische Quelle für Fehler um einen Tag, die kein test262-Fall abfängt. dayjs prüft Konstruktionsvarianten, Berechnungen über DST-äquivalente Monatsgrenzen und die Erweiterung von Format-Tokens über ungefähr dieselben Codepfade wie jede JS-Datumsbibliothek.
  • bignumber.js — Arithmetik mit beliebiger Genauigkeit ohne TypedArrays prüft stringbasiertes Zahlenparsing, Schleifen für Multiplikation und Division großer Ganzzahlen sowie die Auswahl des Rundungsmodus — alles in reinem JS, sodass die Engine die gesamte Arbeit übernimmt. Macht subtile Fehler bei der Umwandlung zwischen Number und String sichtbar.
  • json5 — Das tolerante JSON-Parsing stützt sich stark auf Zeichenklassen in regulären Ausdrücken und zustandsbehaftete Tokenisierung. Ein guter Frühindikator für korrekte reguläre Ausdrücke und die Grenzfälle der String-Iteration.
  • fuse.js — ein mit Babel transpiliertes UMD, das _classCallCheck prüft (das this instanceof Ctor-Muster, das jede vor ES6 transpilierten Klasse verwendet) sowie den vollständigen Bitap-Algorithmus für unscharfe Treffer. Diese Form teilen alle mit Babel transpilierten Bibliotheken; alles, was Fuse kaputt macht, betrifft also die halbe npm-Landschaft.
  • handlebars — leistungsfähiges Templating mit Kompilieren vor dem Rendern. Prüft den Laufzeitpfad ohne eval über einen einzigen riesigen compile()-Eintrag, AST-Traversierung, Helper-Aufrufe über eine dynamische Nachschlagetabelle und SafeString-Markenprüfung mit instanceof über verschiedene Realms hinweg. Ein Gegenstück zum einfacheren Template-Walker von mustache.js.
  • zod — Schema-Validierung zur Laufzeit. Tiefe Klassenhierarchien (ZodString, ZodObject, ZodArray, ZodUnion, …) mit Methodenverkettung, die verfeinerte Unterklassen zurückgibt, strukturierte Fehlerformatierung, bei der die Form des JS-seitigen .issues-Arrays bytegenau mit Node übereinstimmen muss, sowie Discriminator- und Literal-Tag-Muster. Prüft den objektorientierten Validierungscode, der die Hälfte moderner TypeScript-Apps umhüllt.
  • typescript — der echte TypeScript-Compiler auf der eingebetteten Engine. Ein 9 MB großer minimierter Compiler, der beliebiges TS erneut parst, den AST durchläuft und JS ausgibt — die schwerste vorstellbare reine JS-Ladung. Wenn Phasis Generics, async/await, Enums und Klassenhierarchien bytegenau wie tsc transpiliert, stimmt die Sprachsemantik.
  • prettier — ein meinungsstarker JS-Formatter. JS mit JS zu formatieren bedeutet, dass dieselben Kontrollflüsse, die deinen Code formatieren, jede Spezifikationsecke der Engine berühren — eine besonders anspruchsvolle Belastung.
  • svelte/compiler — der eigenständige Compiler von Svelte. Er parst .svelte-Quellcode, durchläuft den AST und gibt JS sowohl für Client- als auch SSR-Ziele aus.
  • terser / @babel/parser / postcss — JS-Minifizierer, JS-Parser und CSS-Nachbearbeitung. Zehntausende Zeilen minimierten Codes, die beliebige Eingaben erneut parsen — hier zeigen sich seltene AST-Formen.
  • ajv — JSON-Schema-Validator, der jedes Schema über new Function(...) JIT in eine eigene Validatorfunktion kompiliert. Prüft den Function-Konstruktorpfad, auf den sich die meisten Schema- und Templating-Bibliotheken stützen.
  • mobx — reaktiver Zustand auf Proxy-Basis. Jeder Lesezugriff auf ein Observable läuft durch einen Proxy-get-Trap, der eine Abhängigkeit registriert; jeder Schreibzugriff löst Reaktionen aus. Ein Stresstest für die Proxy-Infrastruktur, Observable Maps, Arrays und verschachtelte Objekte sowie den autorun-Scheduler.
  • cheerio / htmlparser2 — jQuery auf der Serverseite, auf Basis eines schnellen HTML-Parsers. Parser der Selektor-Engine, DOM-artige Traversierung, Attributmanipulation und HTML-Serialisierung in einem Paket.
  • graphql-js / jsonata — Referenzimplementierung von GraphQL und Abfragesprache JSON. Beide setzen stark auf Schemas, Validierung und rekursive Auswerter — typische „Datenschicht im Browser“-Programme.
  • JSZip — asynchroner ZIP-Archiversteller. Steuert die Arbeit über setImmediate-gestützte Planung und erzeugt echte Binärausgabe; damit werden sowohl die Timer-Schnittstelle als auch Pfade mit vielen Uint8Array geprüft.
  • moment / luxon — Datums- und Zeitberechnungen. moment ist ein veränderliches, handoptimiertes UMD; luxon die moderne unveränderliche Neufassung. Zusammen decken sie Formatierung, Parsing und Monats- und Jahresberechnungen über äquivalente Zeitzonen hinweg ab.
  • mqtt-packet — reiner JS-Codec für MQTT 3.1.1 / 5.0. Packen und Dekodieren auf Byte-Ebene sowie Zeichenklassen für reguläre Ausdrücke, die nicht zum Base64-Alphabet gehörende Zeichen erkennen und Randfälle der Annex-B-Grammatik prüfen.
  • xstate / valtio / nanostores / jotai / redux-saga — die moderne Bandbreite der Zustandsverwaltung. Zustandsmaschinen, Proxy-Zustand, Atom-Stores, abgeleitete Atome und Generator-basierte Effekt-Runner — jede Bibliothek prüft eine andere Form von Reaktivität.
  • escodegen / acorn-walk / estraverse / magic-string — AST-Werkzeuge. Codegenerierung, Traversierung und nichtdestruktive Quelltextbearbeitung — die Bausteine für alle JS-zu-JS-Transformatoren (Build-Tools, Codemods, Linter).
  • papaparse / lunr / yaml / sax / css-tree — reine Parser und Tokenizer. CSV, Volltext-Suchindex, YAML 1.2, Streaming-XML im SAX-Stil und CSS-AST. Unterschiedliche Grammatiken, alle gute Frühindikatoren für zeichenweises Scannen und das Verhalten regulärer Ausdrücke.

Weitere hinzufügen

Lege unter tests/Popular/<name>/ ein neues Verzeichnis mit der Struktur aus drei Dateien an und führe dann Folgendes aus:

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

Die PHPUnit-Testsuite erkennt es beim nächsten Lauf automatisch, und CI nimmt es auf, weil die Änderung tests/Popular/ betrifft.

Gute Kandidaten für Ergänzungen: chevrotain (Parser-Kombinator, prüft Closures und reguläre Ausdrücke), nanoid (Grenzbereich von Kryptografie und Zufallszahlen), date-fns (Zeitzonenfunktionen über dayjs hinaus).