2 คะแนน โดย GN⁺ 2025-04-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Lux เป็นตัวจัดการแพ็กเกจใหม่ที่รวมการสร้าง การดูแลรักษา และการเผยแพร่โค้ด Lua ไว้ใน CLI ที่เรียบง่าย เป็นเครื่องมือที่ต้องการนำเวิร์กโฟลว์การพัฒนาที่คุ้นเคยแบบ cargo มาสู่ระบบนิเวศ Lua
  • หลังพัฒนามานานกว่าหนึ่งปีเล็กน้อย ตอนนี้อยู่ในสถานะที่ ใช้งานประจำวันได้ดีมาก แล้ว แต่การรองรับ MSVC, ข้อความแสดงข้อผิดพลาด และการจัดการ edge case ยังเป็นงานที่ต้องทำก่อนรีลีส 1.0
  • ผสานโมเดลโปรเจกต์ที่ใช้ lux.toml, การสร้าง rockspec อัตโนมัติ, lockfile, การบิลด์แบบขนาน, การติดตั้ง Lua header และการรัน formatting, linting, testing ไว้ในโฟลว์เดียว
  • เน้นลดภาระความเข้ากันได้แบบเก่า ความคาดเดาไม่ได้ในแต่ละระบบ และประสบการณ์ติดตั้ง/ซิงก์ที่ช้า ขณะยังคงความเข้ากันได้กับระบบนิเวศ Luarocks
  • การเผยแพร่ปลั๊กอิน Neovim และ การผสานกับ Nix เป็นการใช้งานหลัก โดยขั้นถัดไปรวมถึงการเขียน rocks.nvim ใหม่ให้ใช้ Lux แทน Luarocks

โฟลว์การจัดการแพ็กเกจ Lua ที่ Lux มอบให้

  • Lux เป็นตัวจัดการแพ็กเกจใหม่สำหรับ การสร้าง การดูแลรักษา และการเผยแพร่ โค้ด Lua
  • CLI ได้แรงบันดาลใจจากตัวจัดการแพ็กเกจที่รู้จักกันดีอย่าง cargo ของ Rust
  • ปัจจุบันมาถึงระดับที่ “ใช้งานประจำวันได้ดีมาก” แล้ว
    • การรองรับ MSVC, ข้อความแสดงข้อผิดพลาด และการจัดการ edge case ยังเหลืออยู่
    • การแก้ไขเหล่านี้รวมอยู่ในแผน รีลีส 1.0

โมเดลโปรเจกต์และการผสานเครื่องมือพัฒนา

  • รองรับ ความสามารถในการพกพาข้ามระบบ และสามารถบิลด์กับติดตั้งแบบขนานได้
  • Lux จัดการการติดตั้ง Lua header ให้
    • รองรับ Lua 5.1, 5.2, 5.3, 5.4 และ luajit
    • ผู้เขียนแพ็กเกจเพียงระบุเวอร์ชัน Lua ที่เข้ากันได้ก็พอ
  • crate lux-lib สามารถฝังเข้าไปได้อย่างสมบูรณ์ และยังสามารถบิลด์ให้เปิดเผย Lua API ได้ด้วย
  • มี แนวคิดแบบโปรเจกต์ ที่มีไฟล์ lux.toml เป็นศูนย์กลาง
    • สร้าง rockspec จาก lux.toml โดยอัตโนมัติ
    • ลดภาระการจัดการไฟล์ rockspec หลายไฟล์โดยตรงใน repository
  • lockfile มีเป้าหมายเพื่อให้บิลด์และสภาพแวดล้อมพัฒนาทำซ้ำได้
    • เก็บ source hash และ rockspec hash
    • hash เหล่านี้สามารถใช้เพื่อทำให้การผสาน Lux กับ Nix ง่ายขึ้น
  • รวม code formatting และ linting ไว้ใน CLI ด้วย
  • รองรับการรันเทสต์ที่ใช้ busted เป็นพื้นฐานโดยค่าเริ่มต้น
    • สามารถใช้ Neovim เป็น Lua interpreter ได้
    • สร้างสภาพแวดล้อมที่สะอาด

ความแตกต่างจาก Luarocks

  • Luarocks มีขอบเขตกว้าง แต่มีปัญหาว่าปรับให้เข้ากับการพัฒนา Lua สมัยใหม่ได้ยาก เพราะมี ภาระด้านความเข้ากันได้ ราว 20 ปี
  • Lux ตั้งเป้าเริ่มต้นใหม่ และใช้ TOML เป็นรูปแบบ manifest หลัก
    • สามารถเพิ่ม ลบ pin และอัปเดต dependency ผ่าน CLI ได้
    • คำสั่งอย่าง build ในไดเรกทอรีโปรเจกต์ที่มี lux.toml จะบิลด์โปรเจกต์และติดตั้งลงใน tree ภายในโปรเจกต์
    • ระหว่างกระบวนการบิลด์จะสร้าง lockfile ของ dependency ของโปรเจกต์ เพื่อให้ทำซ้ำ dependency เดิมบนระบบที่เข้ากันได้
  • แนวทางส่งเสริมการใช้ SemVer ก็แตกต่างกัน
    • Luarocks อนุญาตเวอร์ชันแบบกำหนดเองหลัง patch version
    • ตัวอย่างเช่น 1.0.1.0.0.0.2 ถือว่าใช้ได้ใน Luarocks แต่ถูกมองว่าไม่มีความหมายที่เป็นประโยชน์
    • Lux ก็ parse ได้เช่นกัน แต่ค่าหลัง patch version จะถูกถือเป็น prerelease version
  • การบิลด์แบบขนานได้แรงบันดาลใจจาก Nix store
    • Lux hash ไดเรกทอรีติดตั้งเพื่อป้องกันการชนกันของแพ็กเกจ และทำให้บิลด์แบบขนานได้โดยไม่มีความเสี่ยงที่ระบบไฟล์จะเสียหาย
    • รายละเอียดที่เกี่ยวข้องอยู่ใน คู่มือ package conflict ของ Lux

การใช้งานในระบบนิเวศ Neovim

  • หลังจาก rocks.nvim และ lazy.nvim รองรับ Luarocks แล้ว Luarocks ก็กำลังได้รับความนิยมในฐานะวิธีเผยแพร่ปลั๊กอิน Neovim
  • อย่างไรก็ตาม การใช้งาน Luarocks แบบเดิมมีข้อจำกัดเรื่องความสามารถในการพกพาที่ไม่สมบูรณ์ และผลลัพธ์ที่คาดเดาได้ยากในแต่ละระบบ
  • เนื่องจาก Luarocks เขียนด้วย Lua การติดตั้งแพ็กเกจจำนวนมากและการซิงก์ปลั๊กอิน rocks.nvim จึงช้ามาก
  • การใช้ Lux เป็นแบบไม่ทำลายของเดิม และปัจจุบันไม่รบกวนวิธีเผยแพร่ปลั๊กอิน Neovim ผ่าน Git
  • เมื่อใช้ flag --nvim จะติดตั้งแพ็กเกจลงในโครงสร้าง tree ที่เข้ากันได้กับ :h packages ของ Neovim

lockfile สำหรับการผสานกับ Nix

  • หากปลั๊กอิน Neovim อยู่ในรูปแบบแพ็กเกจ Luarocks nixpkgs จะใช้สิ่งนั้นเป็นแหล่งอ้างอิง
    • เพราะในตัวจัดการแพ็กเกจที่เหมาะสม ความรับผิดชอบในการประกาศ dependency อยู่ที่ผู้เขียนแพ็กเกจ
  • การรองรับ lockfile ของ Luarocks เป็นแบบพื้นฐานและไม่รวม source hash
  • ทั้ง Luarocks และ Lux รองรับ dependency ที่ชนกันผ่าน luarocks.loader
  • nixpkgs เพิ่ม dependency หลายเวอร์ชันของ dependency เดียวกันเข้าใน package set อย่างสมเหตุสมผลได้ยาก
  • lux.lock ของ Lux เก็บ source hash และ rockspec hash ของแต่ละ dependency
    • หาก source URL เป็น Git repository Lux จะเก็บ NAR hash
    • lux.lock สามารถใช้สร้าง fixed-output derivation ที่รวม dependency ทั้งหมดได้ เหมือนกับ Cargo.lock

ขั้นต่อไปและเอกสาร

  • ลำดับความสำคัญปัจจุบันคือ การแก้บั๊ก และปรับปรุงข้อความแสดงข้อผิดพลาด
  • rocks.nvim มีกำหนดจะถูกเขียนใหม่ให้ใช้ Lux ภายในแทน Luarocks
    • การเขียนใหม่นี้มีเป้าหมายยกระดับความเร็วของ rocks.nvim ให้เทียบเท่าตัวจัดการปลั๊กอินอื่น
    • หากสำเร็จ จะเป็นตัวอย่างที่แสดงว่า Lux สามารถฝังไปใช้ที่อื่นได้ด้วย
    • มีการกล่าวถึง lazy.nvim เป็นตัวอย่างที่เคยมีปัญหาเกี่ยวกับ Luarocks ในอดีต
  • ผู้ใช้ช่วงแรกสามารถดู tutorial และ guide ได้ที่ เว็บไซต์เอกสาร
  • คำถามหรือ issue สามารถส่งได้ที่ GitHub discussions หรือ issue tracker
  • Lux ใช้ไลเซนส์ LGPLv3.0+ และโลโก้ Lux ใช้ไลเซนส์ CC BY-NC-SA 4.0 ของ © 2025 Kai Jakobi

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

 
GN⁺ 2025-04-09
ความคิดเห็นจาก Hacker News
  • จุดอ่อนแบบ Achilles' heel ของภาษาสคริปต์คือ สภาพแวดล้อมการรัน โดยส่วนตัวไม่ได้ใช้ Neovim แต่เคยคิดว่าการที่ Neovim นำ Lua มาใช้ น่าจะช่วยผลักดันความก้าวหน้าในด้านนี้ของฝั่ง Lua ได้
    Bryan Cantrill เคยเรียก JavaScript ว่า “LISP ที่สวมเสื้อผ้า C” ซึ่งในบางแง่ Lua ให้ความรู้สึกเหมือนตรงกันข้าม และนั่นเป็นเหตุผลที่ชอบ แต่ไม่เคยมีโอกาสต้องใช้ในการทำงาน

    • ไม่แน่ใจว่ามีเหตุผลอะไรที่บอกว่า JavaScript คือ Lisp ที่สวมเสื้อผ้า C และก็ไม่รู้ว่า Lua เกี่ยวข้องกับ Lisp ตรงไหนด้วย ไวยากรณ์แบบ Lisp ไม่มีเลย
  • เข้าใจว่าโปรเจกต์อย่าง Koreader[1] ใช้ Lua เป็น ภาษาหลักของแอปพลิเคชัน ถ้าสามารถโน้มน้าวให้โปรเจกต์ลักษณะนี้สักโปรเจกต์ย้ายมาใช้ได้ ก็น่าจะช่วยสร้างความมั่นใจได้ระดับหนึ่งทั้งในแง่ความสุกงอมของไอเดียและความนิยม
    [1]: https://github.com/koreader/koreader

    • เป็นข้อเสนอที่ดี Lux คงต้องใช้เวลาอีกหน่อยกว่าจะสุกงอม แต่การ build โปรเจกต์มัลติแพลตฟอร์มขนาดใหญ่แบบ koreader ได้ ก็เป็นเป้าหมายที่ดีอย่างแน่นอน
  • ดูดีจริง ๆ ใช้ Lua ค่อนข้างเยอะ แต่ luarocks มีแนวทางที่ตายตัวเกินไป จนแทบไม่มีประโยชน์กับสิ่งที่ต้องการทำ
    แค่ขยับออกจากกรอบ “ติดตั้งไลบรารีเพื่อรันโดยตรงบนระบบ local” ไปนิดเดียว ก็เจอทางตันตั้งแต่แรกแล้ว ถ้ามี สภาพแวดล้อมสคริปต์แบบฝังตัว ที่ใช้แพ็กเกจ Lua และอยาก bundle สคริปต์พร้อม dependency เพื่อแจกจ่าย ก็แทบต้องยอมแพ้
    ไม่รู้ว่าเครื่องมือนี้จะดีกว่าสำหรับ use case นั้นไหม แต่ถึงไม่ใช่ luarocks ก็ดูหยาบและน่าหงุดหงิดในการใช้งานอย่างมากแม้มองในแง่ดีก็ตาม

    • คอมมูนิตี้ Lua พึ่งพา ไลบรารี C สูงมาก และแพ็กเกจ luarocks แทบทุกตัวพยายาม build ไลบรารี ทำให้บน Windows แทบใช้การไม่ได้
  • เป็นโปรเจกต์ที่น่าสนใจ อยากร่วมงานกันเพื่อสร้าง การรองรับ Lua ที่ดีกว่าผ่าน ecosystem ของ conda-forge ใน Pixi
    ตอนนี้แพ็กเกจ lua และ C extension บางตัวไว้อยู่แล้ว ส่วน C extension เป็นพื้นที่หลักของ Pixi จึงน่าจะเข้ากันได้ดี
    เอกสาร pixi.sh และแพ็กเกจ lua ใน registry: https://prefix.dev/channels/conda-forge/packages/lua

    • น่าจะเป็นไอเดียที่ดี เปิด an issue ไว้ใน repository แล้ว ไป ping ได้ตามสะดวกเลย
  • ขอถามเพราะไม่เห็นกล่าวถึงที่นี่หรือในไซต์ที่เกี่ยวข้อง: อยากรู้ว่ามีการ integrate กับ package.path และ package.cpath แบบ native หรือไม่, ตรวจพบการติดตั้งที่ไม่ใช่มาตรฐานแต่ใช้กันแพร่หลายอย่าง brew(1) หรือไม่, และติดตั้งด้วยรูปแบบ GitHub :user/:repository ได้หรือไม่
    โปรเจกต์ดูเจ๋งและทำออกมาดี

    • คำสั่ง lx run และ lx lua จะตั้งค่า PATH, LUA_PATH, LUA_CPATH และยังมีคำสั่ง lx path สำหรับตั้งค่า environment variable เหล่านั้นด้วย
      การตรวจพบการติดตั้ง Lua โดยค่าเริ่มต้นใช้ pkg-config และถ้าหาไม่เจอจะพยายามติดตั้ง Lua ด้วย crate lua_src และ luajit_src ต่อไปอาจเพิ่มการรองรับเครื่องมืออื่นอย่าง vcpkg ได้
      การติดตั้ง GitHub แบบ :user/:repository ยังทำไม่ได้ มีแผนจะเพิ่มใน lux.toml/ข้อกำหนด dependency แต่คงไม่อนุญาตให้เผยแพร่ rockspec แบบนั้นบน luarocks.org เพราะไม่อยากเป็นต้นเหตุให้คนอัปโหลดแพ็กเกจที่ build ด้วย luarocks ไม่ได้
  • แปลว่าตัวจัดการแพ็กเกจสำหรับภาษาที่ถูกออกแบบมาให้ฝังใน C และพึ่งพาไลบรารี C อย่างมาก จะถูก เขียนด้วย Rust และทั้งที่ Lua เองถูกสร้างมาเป็นภาษาสำหรับตั้งค่าโปรแกรม C แต่การตั้งค่ากลับใช้ TOML งั้นหรือ
    ขอผ่าน Luarocks มีข้อจำกัดและอาจควรเขียนใหม่จริง แต่ควรใช้ภาษาที่เข้ากับ ecosystem และเดินตามวัฒนธรรมของ ecosystem Lua Rust กับ Cargo อยู่คนละขั้วกับ Lua พอดี

    • Lua พัฒนามาไกลแล้ว และถูกใช้ในที่ต่าง ๆ มากกว่าวัตถุประสงค์เดิมตอนที่มันถูกสร้างขึ้นมาก
  • โดยส่วนตัวเบื่อ ตัวจัดการแพ็กเกจเฉพาะภาษา แบบนี้มาก มันไม่รู้สึกว่าเป็นทิศทางที่ถูกต้อง และแนวทางอย่าง nix ดูดีกว่ามาก

    • หนึ่งในแรงจูงใจของ Lux คือการปรับปรุง ecosystem ของ Lua และ Neovim ใน nixpkgs
  • ตัวจัดการแพ็กเกจสำหรับ Lua ที่ต้องพึ่ง Rust เนี่ยนะ

    • ดูไม่ได้มีปัญหาอะไร ตัวจัดการแพ็กเกจส่วนใหญ่รองรับ การติดตั้งแพ็กเกจแบบ binary-only อยู่แล้ว
    • อาจจะแปลกใจว่ามันทำงานได้ดีกว่าที่คิด
    • แถมยังใช้ TOML ด้วย
  • ชอบนะ อยากมีวิธี ติดตั้งแพ็กเกจ Lua แบบทำซ้ำได้เหมือนเดิม บนหลายเครื่องมานานแล้ว

    • เคยทำให้สถานะการติดตั้งแพ็กเกจ Lua ทำซ้ำได้เหมือนเดิมบนหลายเครื่องแล้ว แต่ส่วนใหญ่ใช้ Lua อยู่สองแบบ
      แบบหนึ่งคือใช้แบบ “ดิบ ๆ” โดย link เข้ากับ VM ภายใน และจัดการ codebase .lua เป็นส่วนหนึ่งของการ build โปรเจกต์ อีกแบบคือใช้เป็นเครื่องมือระบบ โดยใช้เครื่องมืออย่าง luarocks --local, luaenv ให้เหมาะสม แล้วใส่ไว้ใน Makefile/CMakeLists.txt และผสม luastatic นิดหน่อยสำหรับ bundle เพื่อแจกจ่าย
      พูดตรง ๆ นี่ไม่ได้ต่างจาก Python หรือภาษาสคริปต์อื่นที่อาจถูก bundle มาด้วยมากนัก เพียงแต่ต้องแยกเสมอระหว่าง /bin/script_language ที่ระบบจัดให้ กับภาษาที่ใช้เป็นเครื่องมือพัฒนา/สคริปต์เอนจินภายในโปรเจกต์ที่ใหญ่กว่า หรือเป็นเครื่องมือบน workbench แบบ local
      หนึ่งในเหตุผลที่ชอบ Lua มากคือการแพ็กเกจไลบรารี, link bytecode, และห่อ bundle เพื่อส่งให้ผู้ใช้ระบบปฏิบัติการเป้าหมายในรูปแบบ ติดตั้งคลิกเดียว นั้นค่อนข้างง่ายและสนุก แน่นอนว่าก็ต้องลงแรงอยู่บ้าง
  • ยอดเยี่ยมก็จริง แต่รู้สึกแรงว่ามันเดินสวนทางกับแนวทางการออกแบบของ Lua Lua ถูกออกแบบมาเป็น ภาษาแบบฝังตัว ที่เรียบง่าย และในบริบทนี้ “การจัดการแพ็กเกจ” ก็ใกล้เคียงกับการดาวน์โหลด zip สองสามไฟล์มาแตก ส่วน “การจัดการเวอร์ชัน” ก็ประมาณเลือกว่าจะใช้แบบเข้ากันได้กับ 5.1 หรือ 5.4 เท่านั้น