Populaire pakketten
Conformiteit met de specificatie garandeert niet dat echte bibliotheken werken. JS-engines die voor 99 % van test262 slagen, lopen in productie toch vaak vast omdat bibliotheken afhankelijk zijn van een lange reeks 'randgevallen in de specificatie' — Proxy-traps in een specifieke volgorde, de vorm van Function.prototype.toString, regexgedrag bij lastige invoer en de precieze manier waarop de volgorde van Object.keys samenwerkt met berekende propertynamen.
Phasis controleert 204 veelgebruikte bibliotheken byte voor byte tegen Node.js (V8). Ze staan in de repository onder tests/Popular/ en CI voert ze uit telkens wanneer de enginebroncode of de suite verandert.
Dekking per categorie
| Categorie | Bibliotheken |
|---|---|
| Parsers / 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 |
| Sjablonen / 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 |
| Hulpmiddelen / functioneel | 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 |
| Objecttoegang | 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 |
| Validatie / 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 / tijd | dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2 |
| Wiskunde / getallen | 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 / crypto | 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 |
| Zoeken / verschillen | 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 / gegevensindelingen | 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 |
| Strings / taalkunde | 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 |
| Compressie / codering / archief | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| Kleur | 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 / gelijkheid | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| Opmaak / weergave | ms 2.1.3, bytes 3.1.2 |
| ID's / UUID's | uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3 |
| Typeherkenning / 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 / configuratie | semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0 |
| Caches / prestaties | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| Asynchroon / gebeurtenissen | 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 |
| Reactieve status | 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 / compilers | 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 / protocol | mqtt-packet 9.0.4 |
| GraphQL | graphql-js 16.11.0 |
| Syntaxaccentuering | highlight.js 11.11.1 |
| Testen / assertions | chai 6.2.1 |
Totaal: 204 bibliotheken reproduceren exact dezelfde uitvoer als Node. Alle bibliotheken zijn vastgezet op de nieuwste upstreamversie van de laatste update.
Werking
Elk scenario is een tests/Popular/<lib>/-map met drie bestanden:
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 is een test met gegevensprovider in PHPUnit die:
lodash.js+runner.jslaadt in een nieuwenew Phasis\Engine().- De uitvoer van
console.logopvangt in een buffer. - Controleert of de opgevangen buffer byte voor byte gelijk is aan
oracle.txt.
Een oracle opnieuw genereren:
node tests/Popular/gen-oracle.js tests/Popular/<lib>
(Wordt gebruikt wanneer u de meegeleverde bibliotheek bijwerkt — voert de runner opnieuw uit onder echte Node en overschrijft oracle.txt.)
CI-controle
Workflow: .github/workflows/popular.yml.
Wordt uitgevoerd bij pushes en pull requests naar main die src/, tests/Popular/, phpunit.xml.dist, de bestanden in Composer of de workflow zelf wijzigen, en bij handmatige uitvoering. Twee stappen:
- Kant van Phasis — voert de PHPUnit-
popular-testsuite uit, die elke bibliotheek via Phasis uitvoert en vergelijkt met de vastgelegde oracle. Mislukt als ook maar één byte verschilt. - Opnieuw verifiëren met Node — voert
node tests/Popular/gen-oracle.js …uit voor elke bibliotheek en controleert of de nieuw gegenereerde oracle overeenkomt met de ingecheckte versie. Spoort afwijkingen op wanneer 'een meegeleverde bibliotheek is bijgewerkt zonder de oracle bij te werken'.
Beide controles moeten slagen voordat de PR wordt samengevoegd. Een verbetering van test262 die lodash breekt, is onaanvaardbaar; een verbetering van lodash die test262 breekt, evenmin.
Waarom deze bibliotheken
- acorn — parsen is het kwetsbaarste onderdeel van elke JS-engine. Het test alle syntactische randgevallen die moderne JS toevoegt. Als Phasis willekeurige moderne code met acorn kan parsen, is de runtime solide.
- mustache.js — sjablonen verwerken is een van de toepassingen waarvoor Phasis expliciet bedoeld is (het eerste concrete voorbeeld van README is 'sjabloonengines'). Mustache test iteratie, scope-resolutie en tekenreeksbewerkingen in de volgorde waarin echte sjablonen die uitvoeren.
- lodash — de meestgebruikte JS-hulpmiddelenbibliotheek ter wereld. De meer dan 300 functies raken indirect elke methode van de standaardbibliotheek. Als lodash werkt, werken algemene JS-gegevensbewerkingen ook.
- marked — Markdown weergeven. Praktisch en test regex (veel regex) plus tekenreeksbewerkingen met status over meerdere regels. Brengt verschillen tussen regex-engines aan het licht: PCRE2 (de fallback van Phasis) en Irregexp van V8.
- dayjs — datum- en tijdsberekeningen zijn een klassieke bron van fouten van één dag die geen enkele test van test262 opspoort. dayjs test varianten van constructors, berekeningen over maandgrenzen die overeenkomen door zomertijd en de uitbreiding van formaattokens in ongeveer dezelfde codepaden die elke datum-bibliotheek van JS gebruikt.
- bignumber.js — rekenen met willekeurige precisie zonder TypedArrays test getalparsing op basis van tekenreeksen, vermenigvuldigings- en delingslussen voor grote gehele getallen en afhandeling van afrondingsmodi — allemaal in zuivere JS, zodat de engine alle kosten draagt. Brengt subtiele fouten aan het licht bij de conversie tussen getallen en tekenreeksen.
- json5 — het parsen van soepele JSON-syntax steunt sterk op regexen met tekenklassen en tokenisatie met status. Een goede graadmeter voor de juistheid van regex en de omgang met randgevallen bij iteratie over tekenreeksen.
- fuse.js — een met Babel getranspilde UMD die
_classCallChecktest (hetthis instanceof Ctor-patroon dat elke klasse gebruikt die vóór ES6 is getranspild), plus het volledige bitap-algoritme voor fuzzy matching. Dit is een vorm die elke met Babel getranspilde bibliotheek deelt; alles wat Fuse breekt, breekt dus de helft van het npm-ecosysteem. - handlebars — uitgebreide sjablonenverwerking met eerst compileren en daarna weergeven. Test het runtimepad zonder
evalvia één grootcompile()-item, AST-traversal, dispatch van helpers via een dynamische opzoektabel enSafeString-typecontrole dieinstanceofover verschillende realms gebruikt. Een tegenhanger van de eenvoudigere sjabloonverwerker van mustache.js. - zod — schemavalidatie tijdens runtime. Uitgebreide klassehiërarchieën (
ZodString,ZodObject,ZodArray,ZodUnion, …) met methodenketens die verfijnde subklassen teruggeven, gestructureerde foutopmaak waarbij de vorm van de array JS-zijde-.issuesbyte voor byte moet overeenkomen met Node, en patronen met discriminators en letterlijke tags. Test het soort validatiecode met veel objectgeoriënteerde code dat de helft van moderne TypeScript-apps omhult. - typescript — de echte TypeScript-compiler die op de ingebedde engine draait. Een compiler van 9 MB met minificatie die willekeurige TS opnieuw parseert, de AST doorloopt en JS produceert — de zwaarste denkbare payload in zuivere JS. Als Phasis generics, async/await, enums en klassehiërarchieën byte voor byte gelijk aan
tsckan transpilen, zijn de taalregels solide. - prettier — een eigenzinnige JS-formatter. JS opmaken met JS raakt elk randgeval van de specificatie in de engine via dezelfde besturingsstroom die uw code opmaakt — een bijzonder veeleisende werklast.
- svelte/compiler — de zelfstandige compiler van Svelte. Parseert
.svelte-broncode, doorloopt de AST en produceert JS voor zowel client- als SSR-doelen. - terser / @babel/parser / postcss — JS-minifier, JS-parser, CSS-nabewerker. Tienduizenden regels geminificeerde code die willekeurige invoer opnieuw parsen: het oppervlak waar zeldzame AST-vormen opduiken.
- ajv — JSON-schemavalidator die elk schema JIT compileert tot een aangepaste validatorfunctie via
new Function(...). Dit test het Function-constructorpad waar de meeste schema- en templatingbibliotheken op steunen. - mobx — proxygebaseerde reactieve status. Elke uitlezing van een observable loopt via een Proxy
get-trap die een afhankelijkheid registreert; elke schrijfoperatie activeert reacties. Een stresstest voor de Proxy-infrastructuur, observable Maps / arrays / geneste objecten en de autorun-planner. - cheerio / htmlparser2 — jQuery aan de serverzijde boven op een snelle HTML-parser. Selector-engine-parsing, DOM-achtige traversering, attribuutmanipulatie en HTML-serialisatie in één pakket.
- graphql-js / jsonata — GraphQL-referentie-implementatie en een JSON-querytaal. Beide maken intensief gebruik van schema's, validatie en recursieve evaluatoren: typische code voor een 'datalaag in de browser'.
- JSZip — asynchrone ZIP-archiefbouwer. Routeert werk via
setImmediate-gestuurde planning en produceert echte binaire uitvoer, waarmee zowel het timeroppervlak alsUint8Array-intensieve paden worden getest. - moment / luxon — datum- en tijdrekenkunde. moment is mutable en met de hand geoptimaliseerde UMD; luxon is de moderne immutable herschrijving. Samen bestrijken ze het volledige oppervlak van formattering, parsing en tijdzone-equivalente maand- en jaarberekeningen.
- mqtt-packet — pure-JS MQTT 3.1.1 / 5.0-codec. Inpakken en decoderen op byteniveau, plus regex-tekenklassen voor tekens buiten het base64-alfabet die grammaticale randgevallen van Annex B testen.
- xstate / valtio / nanostores / jotai / redux-saga — het moderne aanbod voor statusbeheer. Statusmachines, proxystatus, atomstores, afgeleide atomen en generatorgebaseerde effectuitvoerders: elke bibliotheek raakt een andere vorm van reactiviteit.
- escodegen / acorn-walk / estraverse / magic-string — AST-tools. Codegeneratie, traversering en niet-destructieve bronbewerking: de bouwstenen voor elke JS-op-JS-transformator (buildtools, codemods, linters).
- papaparse / lunr / yaml / sax / css-tree — pure parsers en tokenizers. CSV, full-textzoekindex, YAML 1.2, streaming SAX-achtige XML en CSS-AST. Verschillende grammatica's, allemaal goede kanaries voor scannen op tekenniveau en regexgedrag.
Meer toevoegen
Voeg een nieuwe map met de structuur van drie bestanden toe onder tests/Popular/<name>/ en voer daarna het volgende uit:
node tests/Popular/gen-oracle.js tests/Popular/<name> # one-time, generates oracle.txt
git add tests/Popular/<name>
De PHPUnit-suite ontdekt deze automatisch bij de volgende uitvoering, en CI neemt deze mee omdat de wijziging tests/Popular/ raakt.
Goede kandidaten om toe te voegen: chevrotain (parsercombinator, test closures + regex), nanoid (grensgebied van cryptografie en willekeurigheid), date-fns (tijdzonefunctionaliteit buiten dayjs).