npm package จริงคอมไพล์ได้แล้ว: axios, zod, express — กับการกวาด conformance
This dated article records the Perry version and measurements available when it was published. Use the current limitations, platform guide, and benchmark artifact for decisions today.
โพสต์ที่แล้วจบลงที่ v0.5.875 ด้วยเรื่อง GC — การปิด gap ที่ benchmark ของ aya_koto เปิดเผยออกมา โพสต์นั้นว่าด้วยการชนะ benchmark ตัวเดียว โพสต์นี้ว่าด้วยงานคนละแบบ: ราว 270 release ระหว่าง v0.5.875 ถึง v0.5.1146 ที่ลงจอดภายในราวสี่สัปดาห์ แทบไม่มีตัวไหนเป็นพาดหัวด้าน benchmark เลย ธีมขยับจาก “วิ่งให้เร็วบน microbenchmark” ไปสู่ “ทำให้ TypeScript ในโลกจริงและ npm package จริงคอมไพล์และรันได้จริง” บวกกับการยกเครื่องด้านภาพของ Windows เต็มรูปแบบและ widget ใหม่อีกกองหนึ่งระหว่างทาง
นี่คือสิ่งที่ปล่อยออกมา จัดกลุ่มตามว่ามันมีไว้เพื่ออะไรจริง ๆ
Real npm packages compile now
เส้นเรื่องเดี่ยวที่ใหญ่ที่สุดตลอดช่วงนี้คือการกวาดเพื่อทำให้ npm package ยอดนิยมคอมไพล์เป็น native binary และผ่านการทดสอบเชิงพฤติกรรม — ไม่ใช่แค่ “link โดยไม่มี error” แต่รันและให้ผลลัพธ์ที่ถูกต้อง รายการที่ตอนนี้ทำงานได้ผ่าน perry.compilePackages รวมถึง axios, jose, zod v4, vitest, express, fastify, @hono/node-server, dayjs, chalk, ms, debug, lodash, ethers, argon2, และ Colyseus
แต่ละตัวล้มด้วยเหตุผลของตัวเอง และการแก้แต่ละครั้งก็เป็นเรื่องราวเล็ก ๆ ของมันเอง:
- zod v4 crash ด้วย
Cannot read properties of undefined (reading 'onattach')ต้นเหตุ (v0.5.1144, #4698):new F()ที่Fเป็นฟังก์ชันที่ import มาจากอีกโมดูลให้ object ว่างเปล่าแบบเงียบ ๆ — body ของ constructor ไม่เคยรัน ดังนั้น check สไตล์$ZodCheckMinLengthทุกตัวกลับมาโดยถูกถอด property_zodออก - axios + jose ต้องการ crypto และ compression ที่ Perry ยังไม่มี:
zlib.createBrotliDecompress,crypto.subtle.wrapKey/unwrapKey,subtle.generateKey/encrypt/decryptสำหรับ AES-GCM และrandomFillSync(v0.5.972–976) - fastify เกิด deadlock บน polling timeout หนึ่งวินาทีใน
wait_for_promiseเราแทนมันด้วยการรอแบบ condvar และทำให้ promise ที่ถูก reject ผุดขึ้นมาเป็นHTTP 500แทนที่จะค้าง (v0.5.912) - @hono/node-server อ่าน POST body ไม่ได้ —
c.req.text()/.json()/.formData()คืนค่าว่างบน POST/PUT จนกระทั่งการแก้ parent-registration ใน v0.5.1142 - chalk, ms, debug, express ชนรูปร่างเดียวกันทั้งหมด: ค่าที่เรียกได้พร้อม property ติดมาด้วย (
chalk.red,express()บวกexpress.Router) รูปแบบนั้นสามแบบถูกแก้ตลอด v0.5.935 และการกวาด npm รอบ ๆ บวกutil.inherits+ โครง stream prototype เพื่อปลดล็อก express (v0.5.990) - dayjs ที่ปล่อยมาเป็น bundle แบบ minified ออกแรงกับ prototype-method dispatch สไตล์ JS-classic (
Class.prototype.m = fn) ที่ Perry lower ผิด (v0.5.924/932)
ใต้ทั้งหมดนั้นคือส่วนที่ทำให้ package ที่ Perry คอมไพล์ native ไม่ได้ ยังรันได้: V8-fallback runtime เป็นจริงเป็นจังขึ้นในช่วงนี้ ModuleLoader ของมันตอนนี้อ่านจาก embedded module map ดังนั้น binary แบบ fallback ก็ยัง self-contained — ไม่มี node_modules กระจัดกระจายตอน runtime (v0.5.994) createServer เชื่อมไปยัง hyper server จริง (v0.5.999) และ global ของ Web Fetch อย่าง Response / Request / Headers มีอยู่ใน path แบบ fallback (v0.5.1006) และ import() แบบ dynamic ที่ compile-time — await import('./foo.ts') แบบ string-literal ที่ resolve ตอน build — ในที่สุดก็ลงจอด (v0.5.905, #100)
A test262 conformance sweep
อีกเส้นเรื่องที่โดดเด่นคือ conformance เรารัน pass แบบโฟกัสเทียบกับ radar ของ subset test262 และขยับเข็มบน built-in ที่ code จริงพิงหนักที่สุด:
built-ins/String 60.2% → 79.3% (v0.5.1128)
built-ins/Array 61.5% → 72.5% (v0.5.1127)
language/.../destructuring 41.6% → 53.9% (v0.5.1143)การกระโดดของ String มาจากการให้ทุกเมธอด String.prototype มี dispatch แบบ generic-this และแก้ index coercion ของ slice/substring การกระโดดของ Array คือ thisArg บน callback ของ dense-array (forEach/map/filter/…), ToLength แบบ array-like, การจัดลำดับ spec operation และการ validate กรณีไม่มี argument Destructuring เก็บ parameter-destructuring ข้ามทั้ง plain, generator, async-generator, static และ private class method
ควบคู่กับตัวเลขพาดหัว ความถูกต้องหางยาวก็ลงจอด: JSON.parse ตอนนี้โยน SyntaxError จริง (ไม่ใช่ TypeError) และปฏิเสธ token ที่ตามท้าย reviver ของมันเดินผ่านอัลกอริทึม InternalizeJSONProperty ตาม spec Object.prototype.toString brand ได้ถูกต้องสำหรับ typed array, Symbol, BigInt, Map/Set/WeakMap/WeakSet/Promise/RegExp RegExp.prototype.toString คืน /source/flags async generator ได้ semantics ของ yield-awaits-operand ถูกต้อง เหล่านี้เป็น subset radar ไม่ใช่ suite เต็ม — Perry ยังไต่อยู่ — แต่การไต่ของเดือนนี้ชันมาก
Windows goes Fluent
Windows ได้รับการยกเครื่องด้านภาพ (ชุด #4681) หน้าต่าง Perry ตอนนี้เลือกใช้ DWM chrome สมัยใหม่โดย default — Mica backdrop, มุมโค้งมน และ title bar ที่รับรู้ธีม — และ common control เรนเดอร์ผ่าน comctl32 v6 แทน default ยุค Windows 95 window proc ตอนนี้จัดการ WM_DPICHANGED ดังนั้นหน้าต่างยังคมเมื่อคุณลากมันระหว่างจอที่มี scaling ผสมกัน แทนที่จะถูกยืด bitmap
ที่สำคัญ ไม่มีอะไรในนี้นำ regression #1542 เก่า “พื้นที่ดำหลัง resize” กลับมาอีก: client area ยังถูกวาดทึบแสง และ blur-through แบบ Mica/Acrylic เต็มเฟรมยังเป็น opt-in app.setVibrancy(...) แบบชัดเจน ยังมี backend scaffold --target windows-winui ตัวใหม่ (WinUI 3) สำหรับแอปที่อยากได้ stack สมัยใหม่เต็มตัว และการแก้เล็ก ๆ แต่เป็นเรื่องจริงที่ทำให้ perry compile main.ts -o main ผลิต main.exe บน Windows เพื่อให้ PowerShell launch มันได้จริง (v0.5.1146)
New widgets, every platform
widget สองตัวลงจอดในวันสุดท้ายพอดี และทั้งคู่ครอบทุกแพลตฟอร์ม UI ที่ Perry target:
- DatePicker (#4772) — date control แบบ field กะทัดรัด:
NSDatePickerบน macOS,UIDatePicker(.compact) บน iOS/visionOS,SysDateTimePick32บน Windows,android.widget.DatePickerบน Android, GTK4 บน Linux ผิว TS เดียวข้ามทั้งหมด - Drag & drop (#4773) — widget ใด ๆ เป็น drop destination และ drag source สำหรับ text/files/URLs ได้ แมปไปยัง
NSDraggingDestination(AppKit),UIDropInteraction(UIKit), และView.setOnDragListener(Android)
import { DatePicker } from "@perry/ui";
DatePicker(2026, 6, (iso) => {
// iso is a POSIX-locale "yyyy-MM-dd" string
console.log("picked", iso);
});ก่อนหน้านี้ในช่วงเดียวกัน ชั้นวาง widget ก็เต็มขึ้นทั้งบน desktop และ mobile ด้วย — Combobox, TreeView, Calendar, Chart, CommandPalette, RichTextEditor, MapView, PdfView, BottomNavigation, และ ImageGallery แบบ swipe ได้ — แต่ละตัวหนุนด้วย native control จริงบนทุกแพลตฟอร์ม HarmonyOS (ArkTS) ได้ Chart และ TreeView (v0.5.893) สอง widget สุดท้ายที่มันต้องการเพื่อให้เทียบเท่ากับตัวอื่น
GC, internals, and stability
release 270 ตัวนั้นส่วนใหญ่ไม่ใช่พาดหัว — มันคือ bug fix และ internals และนั่นคือประเด็นของเฟสนี้ มีบางอย่างที่ควรกล่าวถึง:
- GC เดินหน้าต่อ งาน conditional free-list จากโพสต์ GC ยังคงค่อย ๆ ลงตัว และ bug คลาสคม ๆ หนึ่งก็ถูกปิด: Promise ที่เชื่อม native ตอนนี้ ถูกปักหมุดไว้ขณะ in flight บน tokio worker เพื่อให้ GC ไม่สามารถ sweep มันก่อนที่การ resolve จะลงจอด (v0.5.923) ถ้าคุณรัน async fetch ภายใต้โหลดแล้วเห็นการ collect แบบผีหลอก นั่นคือเรื่องนี้
- memory model มีเอกสารแล้ว ตอนนี้มี deep-dive
internals/memory-model.md— NaN-boxing, generational GC, shadow stack และ write barrier — ต่อเข้ากับ docs site (v0.5.933) - คลื่นการแก้ความเสถียรของ codegen ที่การกวาด npm ทำให้ผุดขึ้นมา: arrow ที่เป็น
constระดับโมดูลที่เรียกข้างใน async step ที่ resume แล้วไม่ SIGSEGV อีก (v0.5.953),try { await rejected } catch { return X }ไม่ค้างชั่วนิรันดร์อีก (v0.5.870), และ crash แบบjs_is_truthy/ raw-pointer-range อีกหยิบมือที่ bundle จริงสะดุด
Apple housekeeping
เล็กกว่าแต่เป็นเรื่องจริง: perry setup ios --development ตอนนี้ provision สำหรับ development build (v0.5.1023) และ path build/link ของ Apple cross-library ถูก dedup และทำให้ portable ด้านความกว้างของ pointer (v0.5.1121/1125) — ซึ่งเป็นสิ่งที่ปลดล็อก matrix การ publish npm / Homebrew / APT / winget ที่เคยติดขัดอยู่
Where this leaves things
เดิมพันเบื้องหลัง Perry มาตลอดคือ “native TypeScript” จะมีความหมายก็ต่อเมื่อ TypeScript จริง รันได้ — ไม่ใช่ subset ของเล่น แต่คือ package จริงที่คน npm install เดือนนี้ส่วนใหญ่คืองานนั้น: ไม่ใช่ตัวเลขเดียวไว้คุยโม้ แต่เป็นการดันอันยืดยาวไร้ความหรูหราเพื่อปิด gap ระหว่าง “คอมไพล์ได้” กับ “ทำงานได้” radar ของ conformance และ test ความเทียบเท่าของ npm คือ scoreboard ที่เราจับตาอยู่ตอนนี้ และเราจะโพสต์ตัวเลขต่อไป — ทั้งส่วนที่ดีและส่วนที่ยังไม่สมบูรณ์
Source: github.com/PerryTS/perry — Issues: github.com/PerryTS/perry/issues
— Ralph
ชอบโพสต์นี้ใช่ไหม? รับโพสต์ถัดไป
บันทึกสั้น ๆ เกี่ยวกับการอัปเดตของ Perry และสิ่งที่เรากำลังสร้างต่อไป
Your email is sent to Resend for the Perry newsletter. You can request unsubscribe or deletion at any time. Privacy notice