1 คะแนน โดย GN⁺ 5 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • สามารถรวม โปรเจกต์ Deno ที่สร้างด้วยเว็บแอปและโค้ด TypeScript ให้เป็นไบนารีแอปเดสก์ท็อปที่แจกจ่ายซ้ำได้ตามแพลตฟอร์ม
  • เอาต์พุตจะรวมโค้ดแอปพลิเคชัน, Deno runtime, และเอนจินเรนเดอร์เว็บไว้ด้วยกัน โดยฟีเจอร์นี้ถูกรวมเข้ามาใน Deno v2.9.0 แล้ว แต่ยังไม่ใช่รุ่นเสถียร
  • WebView backend เริ่มต้นใช้ webview ที่มีมาในระบบปฏิบัติการเพื่อให้ได้ ไบนารีขนาดเล็ก และหากต้องการความสม่ำเสมอของการเรนเดอร์ก็สามารถเลือก backend แบบ Chromium (CEF) ได้
  • รองรับการตรวจจับโปรเจกต์ Next.js, Astro, Fresh, Remix, Nuxt, SvelteKit, SolidStart, TanStack Start และ Vite SSR แล้วรันเซิร์ฟเวอร์ให้เหมาะกับโหมดรีลีสและโหมดพัฒนา --hmr
  • การสื่อสารระหว่างโค้ด Deno กับ webview ใช้ in-process channel แทน IPC แบบ socket และยังครอบคลุมถึง cross compile กับการอัปเดตอัตโนมัติบนพื้นฐานของ bsdiff

บทบาทและสถานะปัจจุบันของ deno desktop

  • deno desktop ใช้แปลงโปรเจกต์ Deno ให้เป็น แอปเดสก์ท็อปแบบ self-contained
    • อินพุตทำได้ตั้งแต่ไฟล์ TypeScript เดี่ยวไปจนถึงแอป Next.js
    • เอาต์พุตคือไบนารีที่แจกจ่ายซ้ำได้ตามแพลตฟอร์ม
    • ภายในไบนารีมีทั้งโค้ดแอปพลิเคชัน, Deno runtime และเอนจินเรนเดอร์เว็บ
  • ฟีเจอร์นี้รวมอยู่ใน Deno v2.9.0 แล้ว แต่ยังไม่ใช่รุ่นเสถียร
    • หากต้องการลองตอนนี้ ต้องติดตั้งบิลด์ canary ด้วย deno upgrade canary
    • คำสั่ง, คีย์การตั้งค่า และ TypeScript API อาจเปลี่ยนแปลงได้ก่อนจะเสถียร

การเลือก backend และการรันโปรเจกต์เว็บ

  • แนวทางนี้ใช้เทคโนโลยีเว็บเป็น UI toolkit สำหรับเดสก์ท็อป พร้อมลด trade-off ที่มักเจอในเครื่องมือทำแอปเดสก์ท็อปที่อิงเว็บสแตกเดิม
    • เครื่องมืออย่าง Electron, Tauri และ Electrobun อาจมี trade-off เช่น ไบนารีขนาดใหญ่, รองรับแพลตฟอร์มไม่ครบ, ขาด ecosystem ของ JavaScript, ไม่มีระบบอัปเดตในตัว หรือไม่มีการผสานกับเฟรมเวิร์ก
  • WebView backend เริ่มต้นใช้ webview ของระบบปฏิบัติการเพื่อมุ่งไปที่ ไบนารีขนาดเล็ก
    • สามารถใช้ ecosystem ของ npm ได้ผ่านชั้นความเข้ากันได้กับ Node ของ Deno
    • หากต้องการให้การเรนเดอร์เหมือนกันบน macOS, Windows และ Linux ก็สามารถเลือก CEF backend ที่ bundle Chromium มาได้
  • การตรวจจับเฟรมเวิร์กอัตโนมัติเป็นแนวทางให้รันโปรเจกต์เว็บเดิมบนเดสก์ท็อปได้โดยไม่ต้องแก้โค้ด
    • รองรับ Next.js, Astro, Fresh, Remix, Nuxt, SvelteKit, SolidStart, TanStack Start และ Vite SSR เป็นต้น
    • ในโหมดรีลีสจะรัน production server
    • ใน --hmr จะรัน development server ที่มี hot reload

การสื่อสารใน runtime, การ build และการอัปเดต

  • การสื่อสารระหว่าง backend กับ UI ใช้ in-process channel
    • ค่าต่าง ๆ จะถูกเข้ารหัสเมื่อข้ามขอบเขตการเรียก
    • ไม่มีการวิ่งไปกลับข้ามโปรเซสระหว่างโค้ด Deno กับ webview
  • สามารถ cross compile สำหรับ macOS, Windows และ Linux ได้จากเครื่องเดียว
    • backend จะไม่ถูก build แบบ local แต่จะดาวน์โหลดเมื่อจำเป็น
  • ระบบอัปเดตอัตโนมัติเป็นการอัปเดตส่วนต่างของไบนารีในตัว โดยใช้ manifest latest.json และ bsdiff patch
    • runtime จะจัดการการ polling, การนำไปใช้ และการ rollback เมื่อการรันล้มเหลว

ตัวอย่างง่าย ๆ และโครงสร้างเอกสาร

  • แอปเดสก์ท็อปแบบไฟล์เดียวสามารถสร้างได้โดยเขียน main.ts ให้ Deno.serve() ส่งคืน HTML response แล้วรัน deno desktop main.ts
Deno.serve(() =>
  new Response("Hello, desktop

", {
    headers: { "content-type": "text/html" },
  })
);
deno desktop main.ts
  • ไบนารีที่คอมไพล์แล้วจะเปิดหน้าต่างที่ชี้ไปยัง local HTTP server ซึ่ง bind อยู่กับ handler ของ Deno.serve()
    • บน macOS/Linux ให้รันด้วย ./main
    • บน Windows ให้รันด้วย .\\main.exe
  • Deno.serve() จะ bind เข้ากับที่อยู่ที่ webview จะเปิดโดยอัตโนมัติ จึงไม่จำเป็นต้องส่งพอร์ตหรือชื่อโฮสต์
  • เอกสารที่เกี่ยวข้องแบ่งเป็นการตั้งค่า, backend, HTTP serving, framework, การจัดการหน้าต่าง, binding, เมนู, tray และ dock, dialog, การแจ้งเตือน, HMR, DevTools, การอัปเดตอัตโนมัติ, การรายงานข้อผิดพลาด, การ deploy, การเปรียบเทียบ และ CLI reference
    • Deno.BrowserWindow เกี่ยวข้องกับวงจรชีวิตของหน้าต่าง, หลายหน้าต่าง และอีเวนต์
    • Deno.autoUpdate() เกี่ยวข้องกับ manifest, bsdiff และ rollback
    • bindings.() คือวิธี binding สำหรับเรียกโค้ด Deno จาก webview

1 ความคิดเห็น

 
GN⁺ 5 시간 전
ความคิดเห็นบน Hacker News
  • ดูเหมือนว่า Deno Desktop จะเลือกจุดประนีประนอมนี้แบบ ชัดเจนมาก พอสมควร: “ค่าเริ่มต้นให้เล็ก แต่ Node compatibility ให้ครบถ้วน”
    ผมลองรัน Hello World 5 บรรทัดในบทความด้วย deno desktop index.ts แล้วบน Windows 10 ผลลัพธ์ออกมาเป็น 442MB
    นึกว่าจะเล็กกว่า Electron build แต่กลับใหญ่กว่ามากจนน่าตกใจ โดย libcef.dll มีขนาด 247MB และ deno-test.dll ที่ใส่ Hello World มีขนาด 78MB
    เลยสงสัยว่าผมทำอะไรผิดหรือเปล่า

    • เท่าที่จำได้ Hello World ของ Electron ก็อยู่ราว ๆ 100~150MB รวม browser/Chromium runtime แล้ว
      ก็เลยหวังว่าน่าจะมีทางออกแบบใช้ซ้ำพวก OS webview แล้วลดลงมาเหลือ ต่ำกว่า 20MB ได้ แต่พอเกิน 400MB มันก็รู้สึกเหมือนโฆษณาเกินจริงนิดหน่อย
      อาจเป็นเพราะตั้งค่าผิดก็ได้ เลยสงสัยว่านอกจาก deno desktop test.ts แล้วยังต้องทำอะไรเพิ่มอีกไหม
  • ตรงที่บอกว่า “แทนที่แต่ละแอปจะ bundle CEF กันเอง ถ้าจัดการ shared CEF runtime ได้ ก็อาจลดขนาดไบนารีต่อแอปลงเหลือไม่กี่ MB และอยู่ใน roadmap” น่าสนใจดี
    ผมไม่ค่อยรู้เรื่อง CEF เลยสงสัยว่าการจัดการเวอร์ชันจะเป็นยังไง
    ถ้าแต่ละแอปต้องการ CEF คนละเวอร์ชัน สุดท้ายจะย้อนกลับไปเป็นโมเดลแบบ Electron ที่แต่ละแอปต้องแบกเบราว์เซอร์ของตัวเองอยู่ดีไหม หรือแม้ในกรณีนั้นก็ยังมีข้อดีของ shared runtime เหลืออยู่หรือเปล่า
    https://docs.deno.com/runtime/desktop/comparison/

    • CEF คือ Chromium Embedded Framework
      https://github.com/chromiumembedded/cef
    • อ้างอิงเพิ่มเติม CEF เคยถูกใช้ใน Riot และ League of Legends client ด้วย
      ผลลัพธ์ออกมาไม่ได้ดีนัก แต่ผมก็ไม่แน่ใจว่าเป็นปัญหาของตัวเทคโนโลยี CEF เอง หรือเป็นเพราะองค์ประกอบ/โปรเซสอื่น
      https://www.riotgames.com/en/news/architecture-league-client...
    • ผมสงสัยว่าข้อดีจะมากพอไหม
      แอป Electron บนเดสก์ท็อปแทบทั้งหมดในความเป็นจริงก็ใช้ Chromium คนละเวอร์ชัน กันอยู่แล้ว และบางครั้งก็ต้องค้างเวอร์ชันเก่าไว้เพราะกลัวอัปเกรดแล้วพัง
    • นักพัฒนาเว็บคุ้นเคยกับสภาพแวดล้อมเป้าหมายที่อัปเดตเป็นรุ่นใหม่ตลอดเวลาอยู่แล้ว เลยอาจมีทางเลือกว่าจะเข้าร่วมหรือไม่เข้าร่วมโมเดลแบบ “ก็ใช้ตัวล่าสุดที่คุณมีไปเลย”
    • ถ้าจะให้ดี ผมอยากใช้ system webview มากกว่าการต้องดาวน์โหลดและจัดการเบราว์เซอร์ที่ฝังมาเอง
      ถ้าเป็น Windows ก็แนวเดียวกับ WebView2
  • Deno ยังคงน่าประทับใจอยู่เรื่อย ๆ
    ผมไม่ได้เริ่มโปรเจ็กต์ใหม่โดยไม่ใช้ Deno มาพักใหญ่แล้ว และตอนนี้ก็สนับสนุน ecosystem ของ Deno เต็มตัวมากกว่า Node.js ไปแล้ว
    ไม่แน่ใจว่าจะได้ใช้ฟีเจอร์นี้บ่อยแค่ไหน แต่การมีตัวเลือกเพิ่มขึ้นก็ดีมากจริง ๆ

  • งานที่น่าประทับใจ
    น่าจะน่าสนใจมากเวลาทำ desktop app ด้วย vibe coding
    เครื่องมืออย่าง Lovable, Bolt, v0 มักใช้ TypeScript เป็นค่าเริ่มต้นเวลาสร้างเว็บแอป เลยดูเข้ากันได้ดี
    ปกติผมใช้ Go/Wails แทนการ bundle Chromium กับ Node สำหรับเดสก์ท็อปแอปเล็ก ๆ ส่วน Electron ก็ทำหน้าที่ของมันได้ดี แต่ bundle ที่ใหญ่ขนาดนั้นเป็นสิ่งที่ผมรู้สึกต่อต้านอย่างชัดเจน

  • ผมสงสัยว่ามันจะผสานกับ ระบบสิทธิ์ ซึ่งเป็นหนึ่งในจุดแข็งที่สุดของ Deno ยังไง
    โดยเฉพาะเวลาปล่อยให้เอเจนต์ไปวิ่งทำอะไรก็ได้บนเครื่องของผม เรื่องนี้ยิ่งสำคัญ
    ในเอกสารอ้างอิงของ CLI บอกว่า “สิทธิ์ที่ให้ตอนคอมไพล์จะถูกฝังเข้าไปในไบนารีที่คอมไพล์แล้ว”
    ถ้าสามารถแสดงออกมาให้ผู้ใช้รู้และตัดสินใจได้ว่าจะให้สิทธิ์อะไรบ้าง ก็น่าจะดี
    https://docs.deno.com/runtime/reference/cli/desktop/#runtime...

    • นี่คือกรณีที่รันไบนารีที่ได้รับมาจากนักพัฒนา
      ถ้าในจุดนั้นยังแสดง Deno permission prompt ขึ้นมา ผมคิดว่าอาจทำให้เข้าใจผิดมากกว่า เพราะไม่มี หลักประกันความถูกต้องสมบูรณ์ ของสิทธิ์นั้น
    • หนึ่งในสิ่งที่ Deno Desktop ยังไม่มีคือ runtime permissions สำหรับ desktop app
      คือแนวทางนำระบบสิทธิ์ของ Deno มาใช้กับ desktop sandboxing โดยเด้ง permission prompt ทุกครั้งที่เข้าถึง filesystem หรือ network
  • เป็นฟีเจอร์ที่ฉลาดมากสำหรับการเปิดตัว
    เวลาต้องตัดสินใจว่าจะใช้แพลตฟอร์มไหน ผมว่านี่น่าจะเป็นตัวเลือกที่ควรหยิบมาพิจารณาอย่างจริงจัง

    • เห็นด้วย
      ถ้าได้ทั้ง ขนาดติดตั้งเล็ก และ cross-platform ก็ดูเป็นทางเลือกที่ดีแทน Electron หรือ Tauri
  • ผมคิดว่าสำนวนที่ว่า “เว็บเทคโนโลยีคือ UI toolkit ที่เป็นที่รู้จักมากที่สุดในโลก” ไม่ค่อยเหมาะเท่าไร
    เหตุผลที่แอป Electron ถูกวิจารณ์หนักก็เพราะมันแทบจะอยู่คนละขั้วกับการเป็น UI toolkit
    หลายครั้งมันทำตามแพตเทิร์น UI ของ OS โฮสต์ได้ไม่ดีนัก
    เว็บเทคโนโลยีก็เป็นแค่เว็บเทคโนโลยี มันเรนเดอร์ปุ่มได้ก็จริง แต่ไม่มีอะไรรับประกันว่าต่อให้เป็นปุ่มที่ยังไม่ใส่สไตล์จะดูเหมือน native ของ OS และยังต่างกันไปตามแต่ละเบราว์เซอร์

    • นั่นไม่ใช่เหตุผลที่คนใช้ Electron
      เป้าหมายไม่เคยเป็นแค่ “UI toolkit” หรือ “การทำตามแพตเทิร์น UI ของ OS โฮสต์”
      Chromium มีความสามารถมหาศาลอยู่ในนั้น และ Electron ก็ดึงยูทิลิตีเหล่านั้นมาใช้ตรง ๆ ซึ่งเป็นข้อดี
      เช่น ถ้าเคยทำงานวิดีโอมาก่อน จะรู้ว่าการใช้ศักยภาพทั้งหมดของเบราว์เซอร์สมัยใหม่ภายในเดสก์ท็อปแอปนั้นเปลี่ยนเกมมาก
      ไม่ใช่แค่การเล่นวิดีโอ แต่รวมถึงการทรานส์โค้ดที่ทำได้ด้วยเว็บสมัยใหม่และ WebCodecs ซึ่งถ้าจะไปทำเองทั้งหมดนั้นเป็นงานใหญ่มาก และยิ่งเป็นเดสก์ท็อปแอปที่ต้องรันบน Windows/macOS/Linux ก็ยิ่งหนักเข้าไปอีก
      ผมมีแอปตัวหนึ่งที่ทำด้วย Electron ในเวลาไม่กี่สิบชั่วโมง แต่ถ้าใช้วิธีอื่นน่าจะกินเวลาเป็นหลายสิบวัน และต่อให้ใช้ AI ถ้าไม่ใช่ผู้เชี่ยวชาญด้านวิดีโอก็คงยากอยู่ดี
    • ไม่เข้าใจว่าทำไมถึงมองว่าสำนวนนี้แย่
      ก็ไม่ได้เคยอ้างว่าเป็น UI แบบ “native”
      UI แบบ native ของ Linux ดูไม่สวยมาตลอดอยู่แล้ว และผมกลับรู้สึกว่าการใช้ HTML+CSS layout ที่จัดมาดี ๆ ดีกว่ามาก
      จากประสบการณ์ของผม Electron มักโดนด่าว่ากินทรัพยากรและช้าเป็นหลัก ส่วนเรื่องไม่ native เป็นแค่ประเด็นเสริมที่คนชอบหยิบมาเพิ่ม
      ผมอยากทำการผสานกับเบราว์เซอร์โดยตรงมานานแล้ว ใช้ HTML+CSS ทำเลย์เอาต์แต่ไม่ต้องมี JavaScript runtime
      ไม่รู้ว่า Servo เบาแค่ไหน แต่ก็หวังว่าวันหนึ่งไอเดียแบบนั้นจะเกิดขึ้นจริง
    • ทุกครั้งที่ใช้ Zed บน Linux, macOS, Windows ผมทึ่งเสมอว่า GPUI framework เสถียรและเร็วแค่ไหน
      ในฐานะผู้ใช้ผมพอใจมาก แม้ว่าฟีเจอร์พื้นฐานอย่าง accessibility จะยังขาดอยู่บ้าง แต่คิดว่าน่าจะมีเร็ว ๆ นี้
      ในมุมของนักพัฒนา นอกจาก Rust แล้วก็ไม่ค่อยรู้ว่ามีอุปสรรคอะไร และในขณะเดียวกัน Rust เองก็เป็นจุดเด่นด้วย
    • ประเด็นเรื่อง UI ดูเหมือน native หรือไม่ นั้นหมดพลังในการเป็นข้อโต้แย้งไปนานแล้ว
      มันเป็นเรื่องของเมื่อราว 25 ปีก่อน และหลังจากที่แม้แต่ Microsoft ก็เริ่มไม่ใส่ใจแล้ว คนอื่นก็แทบไม่สนกันอีก
    • ดูเหมือนคุณจะมองว่าการไม่ทำตามแพตเทิร์น UI ของ OS โฮสต์เป็นข้อเสีย แต่สำหรับผมมันคือข้อดีหลักอย่างหนึ่งของ Electron
      ผมไม่อยากให้แอปของตัวเองหน้าตาต่างกันไปตามแต่ละ OS
      ผมไม่มีทรัพยากรพอจะทดสอบบนทุกอุปกรณ์ และการที่หน้าจอที่ทดสอบบนระบบหนึ่งดูเหมือนกันเป๊ะบนอีกระบบหนึ่งเป็นข้อดีใหญ่มาก
  • ยินดีที่มีคู่แข่งเกิดขึ้นในพื้นที่นี้
    โดยเฉพาะ Deno ที่ตอนนี้ไม่ได้แค่ลบ type ออกเหมือน Node implementation ปัจจุบัน แต่ รัน TypeScript จริง ๆ ได้โดยตรง ซึ่งดีมาก
    แต่ก็คิดว่าสิ่งนี้น่าจะดึงส่วนแบ่งตลาดของ Tauri ไปได้พอสมควร
    ตอนนี้ยังมีเหตุผลอะไรให้ใช้ Tauri อีก?
    สำหรับการเชื่อมต่ออินเทอร์เน็ตส่วนใหญ่ การเพิ่มขนาด bundle อีก 150MB ต่างกันแค่เวลาโหลด 1-10 วินาที แลกกับการได้ rendering engine ที่เชื่อถือได้

    • เวลา Deno รันโค้ด TypeScript โดยพื้นฐานแล้วก็แค่ ลบ type annotation ออกเท่านั้น
      ถ้าจะตรวจ type ต้องรันด้วย deno run --check หรือใช้คำสั่งย่อย deno check แยกต่างหาก
      ระหว่างพัฒนาปกติ IDE ก็มักจะช่วยตรวจ type และ lint ให้อัตโนมัติอยู่แล้ว เลยไม่ใช่ปัญหาใหญ่
    • Tauri ไม่ได้บังคับให้คุณติดอยู่ใน JavaScript ecosystem ใดระบบหนึ่ง
      จริง ๆ แล้วไม่ใช้ JavaScript เลยก็ได้
      และเราก็เห็นสตาร์ตอัปสาย developer framework อย่าง Astro, Nuxt, UV, Bun, Vite ถูกซื้อกิจการกันมาหลายรายแล้ว
      ถ้าเป็นซอฟต์แวร์ที่ต้องอยู่และได้รับการสนับสนุนต่อเนื่องหลายปี กระแสแบบนั้นไม่ได้สร้างความเชื่อมั่นนัก
    • ผมใช้ Tauri ตอนที่ “backend” ไม่ใช่ JavaScript
    • ผมไม่ค่อยเข้าใจคำว่า “ได้ rendering engine ที่เชื่อถือได้”
      Deno Desktop กับ Tauri ไม่ใช่ว่าทั้งคู่ก็ใช้ system webview เหมือนกันหรอกหรือ?
    • ถ้าตามตรรกะนั้นก็คือกำลังบอกให้ใช้ Electron เหมือนกัน
      แล้วทำไมต้องใช้ตัวนี้แต่ไม่ใช้ Electron?
  • ในเอกสารที่ Deno ปล่อยออกมา ส่วนที่ผมชอบที่สุดคือ หัวข้อเปรียบเทียบ
    บรรทัดสุดท้ายระบุว่าการรองรับ iOS/Android ของ Electron เป็น “no” ส่วน Deno เป็น “not yet” ซึ่งถ้าทำได้จริงจะใหญ่มาก

  • ดูเหมือนจะเหมาะมากสำหรับการแจกจ่ายเว็บเกมเป็น แอปบน Steam หรือแอปสำหรับการซื้อออนไลน์
    ผมน่าจะลองใช้ดู