Populära paket
Att följa specifikationen garanterar inte att verkliga bibliotek fungerar. JS-motorer som klarar 99 % av test262 går ändå ofta sönder med produktionskod eftersom biblioteken är beroende av många mindre uppenbara specifikationsdetaljer — Proxy-fällor i en viss ordning, formen på Function.prototype.toString, regexbeteende för knepiga indata och exakt hur ordningen på Object.keys samspelar med beräknade egenskapsnamn.
Phasis verifierar 204 vanliga bibliotek byte för byte mot Node.js (V8). De finns i tests/Popular/ i kodarkivet, och CI kör dem varje gång motorkällkoden eller sviten ändras.
Täckning per kategori
| Kategori | Bibliotek |
|---|---|
| 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 |
| Mall / 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 |
| Verktyg / funktioner | 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 |
| Objektåtkomst | 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 |
| Validering / 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 / tid | dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2 |
| Matematik / tal | 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 |
| Hashning / kryptografi | 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 |
| Sökning / 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 / dataformat | 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 |
| Strängar / språk | 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 / webb | 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 |
| Komprimering / kodning / arkiv | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| Färg | 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 |
| Kloning / likhet | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| Format / visning | ms 2.1.3, bytes 3.1.2 |
| ID:n / UUID:er | uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3 |
| Typidentifiering / 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 |
| Cache / prestanda | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| Asynkronitet / händelser | 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 |
| Reaktivt tillstånd | 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 |
| Bygge / AST / kompilatorer | 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 (kompilator), typescript 6.0.3 |
| MQTT / protokoll | mqtt-packet 9.0.4 |
| GraphQL | graphql-js 16.11.0 |
| Syntaxmarkering | highlight.js 11.11.1 |
| Test / assertioner | chai 6.2.1 |
Totalt: 204 bibliotek återger alla exakt samma utdata som Node. Alla är låsta till den senaste uppströmsversionen vid den senaste uppdateringen.
Så fungerar det
Varje scenario är en katalog tests/Popular/<lib>/ med tre filer:
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 är ett data-provider-test PHPUnit som:
- Läser in
lodash.js+runner.jsi en nynew Phasis\Engine(). - Fångar utdata från
console.logi en buffert. - Kontrollerar att den fångade bufferten är byte för byte identisk med
oracle.txt.
Återskapa en referens med:
node tests/Popular/gen-oracle.js tests/Popular/<lib>
(Används när du uppdaterar det inbäddade biblioteket — kör programmet igen under riktig Node och skriver över oracle.txt.)
CI-kontroll
Arbetsflöde: .github/workflows/popular.yml.
Körs vid pushar och pull-förfrågningar till main som ändrar src/, tests/Popular/, phpunit.xml.dist, filerna Composer eller själva arbetsflödet, samt vid manuell start. Två steg:
- Sidan Phasis — kör PHPUnit
popular-testsviten, som kör varje bibliotek genom Phasis och jämför med den incheckade referensen. Misslyckas om en enda byte skiljer sig. - Ny kontroll med Node — kör
node tests/Popular/gen-oracle.js …mot varje bibliotek och verifierar att den nygenererade referensen stämmer med den incheckade. Upptäcker avvikelser där ”det inbäddade biblioteket har uppdaterats utan att referensen uppdaterats”.
Båda måste godkännas innan PR:en kan slås ihop. En förbättring i test262 som får lodash att sluta fungera är oacceptabel; en förbättring i lodash som får test262 att sluta fungera är inte heller acceptabel.
Varför dessa bibliotek
-
acorn — parsning är den känsligaste delen av varje JS-motor. Biblioteket prövar alla syntaktiska specialfall som modern JS tillför. Om Phasis kan tolka godtycklig modern kod med acorn är körmiljön stabil.
-
mustache.js — mallrendering är ett av de inbäddningsfall som Phasis uttryckligen riktar sig till (det första konkreta exemplet i README är "mallmotorer"). Mustache prövar iteration, uppslagning av variabelomfång och strängomvandlingar i samma ordning som verkliga mallar.
-
lodash — världens mest använda verktygsbibliotek för JS. Dess över 300 funktioner berör indirekt varje metod i standardbiblioteket. Om lodash fungerar, fungerar generell dataomvandling i JS.
-
marked — rendering av markdown. Ett praktiskt arbetsflöde som prövar mängder av regex samt stränghantering med tillstånd över radgränser. Det synliggör skillnader mellan PCRE2 (reservmotorn i Phasis) och Irregexp i V8.
-
dayjs — datum- och tidsaritmetik är en klassisk källa till fel på en enhet som inget test262-fall fångar. dayjs prövar konstruktorvarianter, aritmetik över månadsgränser motsvarande sommartidsgränser och expansion av formateringstoken i ungefär samma kodvägar som alla JS-bibliotek för Date använder.
-
bignumber.js — aritmetik med godtycklig precision utan TypedArrays prövar strängbaserad talparsning, loopar för multiplikation och division av stora heltal samt val av avrundningsläge — allt i ren JS så att motorn står för hela kostnaden. Det synliggör subtila fel i konverteringen Number ↔ String.
-
json5 — tillåtande JSON-parsning bygger i hög grad på regex med teckenklasser och tillståndsbaserad tokenisering. Ett bra varningstest för både regex-korrekthet och specialfall i strängiteration.
-
fuse.js — ett Babel-transpilerat UMD-bibliotek som prövar
_classCallCheck(mönstretthis instanceof Ctorsom varje transpilerad klass från före ES6 använder) samt hela bitap-algoritmen för ungefärlig matchning. Samma struktur återkommer i alla Babel-transpilerade bibliotek, så ett fel som slår ut Fuse slår ut halva npm-ekosystemet. -
handlebars — en komplett mallmotor med kompilering följd av rendering. Den prövar körvägen utan
evalvia en enda stor ingång,compile(), AST-traversering, anrop av hjälpfunktioner via en dynamisk uppslagstabell och typkontroll avSafeStringmedinstanceofmellan körkontexter. Ett komplement till den enklare mallvandringen i mustache.js. -
zod — schemavalidering vid körning. Omfattande klasshierarkier (
ZodString,ZodObject,ZodArray,ZodUnion, …) med kedjade metodanrop som returnerar förfinade underklasser, strukturerad felformatering där formen på JS-sidans.issues-array måste matcha Node byte för byte samt mönster med diskriminatorer och litterala taggar. Prövar den typ av objektorienterad valideringskod som omger hälften av moderna TypeScript-appar. -
typescript — den verkliga TypeScript-kompilatorn som körs på den inbäddade motorn. 9 MB minifierad kompilator som tolkar om godtycklig TS, traverserar AST och genererar JS — den tyngsta tänkbara arbetslasten i ren JS. Om Phasis kan transpilera generiska typer, async/await, uppräkningar och klasshierarkier till byteidentiska resultat jämfört med
tsc, är språksemantiken korrekt. -
prettier — en JS-formaterare med bestämda formateringsregler. Att formatera JS med JS innebär att varje specialfall i specifikationen som motorn har prövas av samma kontrollflöde som formaterar din kod — en ovanligt krävande arbetslast.
-
svelte/compiler — den fristående kompilatorn för Svelte. Tolkar
.svelte-källkod, traverserar AST och genererar JS för både klient- och SSR-mål. -
terser / @babel/parser / postcss — minifierare för JS, parser för JS, efterbehandlare för CSS. Tiotusentals rader minifierad kod som parsar om godtyckliga indata — ytan där ovanliga AST-strukturer dyker upp.
-
ajv — JSON-schemavaliderare som JIT-kompilerar varje schema till en anpassad validatorfunktion via
new Function(...). Testar vägen via Function-konstruktorn som de flesta schema- och mallbibliotek använder. -
mobx — reaktivt tillstånd baserat på proxyer. Varje läsning av ett observerbart värde går genom en Proxy-
get-fälla som registrerar ett beroende; varje skrivning utlöser reaktioner. Ett stresstest av Proxy-infrastrukturen, observerbara Map-objekt, arrayer och nästlade objekt samt schemaläggaren för autorun. -
cheerio / htmlparser2 — jQuery på serversidan ovanpå en snabb HTML-parser. Parsning med selektormotor, DOM-liknande traversering, attributmanipulering och HTML-serialisering i ett paket.
-
graphql-js / jsonata — GraphQL-referensimplementation och ett JSON-frågespråk. Båda är inriktade på scheman, validering och rekursiva utvärderare — typisk kod för ”datalager i webbläsaren”.
-
JSZip — asynkron ZIP-arkivbyggare. Styr arbetet genom
setImmediate-driven schemaläggning och skapar verklig binär utdata, vilket testar både timergränssnittet och vägar med mycketUint8Array. -
moment / luxon — datum- och tidsberäkningar. moment är en föränderlig, handoptimerad UMD; luxon är den moderna oföränderliga omskrivningen. Tillsammans täcker de hela området för formatering, parsning och tidszonsmässigt likvärdig månads- och årsaritmetik.
-
mqtt-packet — ren JS MQTT-3.1.1-codec för version 5.0. Packning och avkodning på bytenivå samt regexar med teckenklasser som omfattar icke-alfabetiska Base64-tecken, vilket testar grammatikens kanter i Annex B.
-
xstate / valtio / nanostores / jotai / redux-saga — bredden inom modern tillståndshantering. Tillståndsmaskiner, proxytillstånd, atomlager, härledda atomer och generatorbaserade effektkörningar — varje bibliotek träffar en annan form av reaktivitet.
-
escodegen / acorn-walk / estraverse / magic-string — AST-verktyg. Kodgenerering, traversering och icke-destruktiv källkodsredigering — byggstenarna för alla JS-på-JS-transformerare (byggverktyg, codemods, linters).
-
papaparse / lunr / yaml / sax / css-tree — rena parsrar och tokeniserare. CSV, fulltextsökindex, YAML 1.2, SAX-liknande strömmande XML och CSS-AST. Olika grammatiker, alla bra lackmustest för teckenskanning och regexbeteende.
Lägga till fler
Lägg till en ny katalog under tests/Popular/<name>/ med strukturen för de tre filerna och kör sedan:
node tests/Popular/gen-oracle.js tests/Popular/<name> # one-time, generates oracle.txt
git add tests/Popular/<name>
Testsviten PHPUnit hittar den automatiskt vid nästa körning, och CI tar med den eftersom ändringen berör tests/Popular/.
Bra kandidater att lägga till: chevrotain (parserkombinator, testar closures och reguljära uttryck), nanoid (gränssnittet för kryptografi och slumpmässighet), date-fns (tidszonsfunktioner utöver dayjs).