2 điểm bởi GN⁺ 2025-04-09 | 1 bình luận | Chia sẻ qua WhatsApp
  • Lux là trình quản lý gói mới gói gọn việc tạo, bảo trì và phân phối mã Lua vào một CLI đơn giản, nhằm mang luồng phát triển quen thuộc như cargo vào hệ sinh thái Lua
  • Sau hơn một năm phát triển, Lux đã đạt trạng thái rất khả dụng cho công việc hằng ngày, nhưng hỗ trợ MSVC, thông báo lỗi và xử lý các trường hợp biên vẫn là việc cần hoàn thiện trước bản phát hành 1.0
  • Tích hợp trong một luồng duy nhất: mô hình dự án dựa trên lux.toml, tự động tạo rockspec, lockfile, build song song, cài đặt header Lua, định dạng, lint và chạy test
  • Vừa duy trì khả năng tương thích với hệ sinh thái Luarocks, vừa tập trung giảm gánh nặng tương thích cũ, tính khó dự đoán theo từng hệ thống và trải nghiệm cài đặt/đồng bộ chậm
  • Phân phối plugin Neovim và tích hợp Nix là các trường hợp sử dụng chính; bước tiếp theo bao gồm viết lại rocks.nvim dựa trên Lux thay vì Luarocks

Luồng quản lý gói Lua mà Lux cung cấp

  • Lux là trình quản lý gói mới cho việc tạo, bảo trì và phân phối mã Lua
  • CLI lấy cảm hứng từ các trình quản lý gói quen thuộc như cargo của Rust
  • Hiện đã đạt mức “rất khả dụng cho công việc hằng ngày”
    • Hỗ trợ MSVC, thông báo lỗi và xử lý các trường hợp biên vẫn còn cần làm
    • Các chỉnh sửa đó nằm trong kế hoạch cho bản phát hành 1.0

Mô hình dự án và tích hợp công cụ phát triển

  • Hỗ trợ tính di động giữa các hệ thống, có thể build và cài đặt song song
  • Lux xử lý việc cài đặt header Lua
    • Các mục tiêu được hỗ trợ là Lua 5.1, 5.2, 5.3, 5.4 và luajit
    • Tác giả gói chỉ cần chỉ định các phiên bản Lua tương thích
  • Crate lux-lib có thể nhúng hoàn toàn, và cũng có thể được build để expose Lua API
  • Cung cấp khái niệm dự án xoay quanh tệp lux.toml
    • Tự động tạo rockspec từ lux.toml
    • Giảm gánh nặng phải trực tiếp quản lý nhiều tệp rockspec trong repository
  • Lockfile hướng tới các bản build và môi trường phát triển có thể tái lập
    • Lưu hash của source và hash của rockspec
    • Các hash này có thể được dùng để giúp tích hợp Lux với Nix dễ hơn
  • Định dạng mã và lint cũng được đưa vào CLI
  • Hỗ trợ mặc định việc chạy test dựa trên busted
    • Có thể dùng Neovim làm trình thông dịch Lua
    • Thiết lập một môi trường sạch

Khác biệt so với Luarocks

  • Luarocks có phạm vi rộng, nhưng gặp vấn đề là khó thích nghi với phát triển Lua hiện đại do gánh nặng tương thích trong khoảng 20 năm
  • Lux hướng tới một khởi đầu mới và dùng TOML làm định dạng manifest chính
    • Có thể thêm, xóa, cố định và cập nhật dependency bằng CLI
    • Trong thư mục dự án có lux.toml, các lệnh như build sẽ build dự án và cài vào cây cục bộ của dự án
    • Trong quá trình build, tạo lockfile cho dependency của dự án để có thể tái lập cùng dependency trên các hệ thống tương thích
  • Cách khuyến khích dùng SemVer cũng khác
    • Luarocks cho phép phiên bản tùy ý sau patch version
    • Ví dụ 1.0.1.0.0.0.2 hợp lệ trong Luarocks, nhưng được xem là không có ý nghĩa hữu ích
    • Lux cũng parse dạng này, nhưng coi các giá trị sau patch version là phiên bản prerelease
  • Build song song lấy cảm hứng từ Nix store
    • Lux hash thư mục cài đặt để ngăn xung đột gói và cho phép build song song mà không có nguy cơ làm hỏng hệ thống tệp
    • Chi tiết liên quan có trong hướng dẫn về xung đột gói của Lux

Sử dụng trong hệ sinh thái Neovim

  • Sau hỗ trợ Luarocks của rocks.nvimlazy.nvim, Luarocks đang trở nên phổ biến như một cách phân phối plugin Neovim
  • Tuy nhiên, việc dùng Luarocks hiện tại còn hạn chế do thiếu tính di động hoàn toàn và kết quả khó dự đoán trên từng hệ thống
  • Vì Luarocks được viết bằng Lua, việc cài đặt nhiều gói và đồng bộ plugin rocks.nvim rất chậm
  • Việc dùng Lux là không phá vỡ hiện trạng và không cản trở cách phân phối plugin Neovim dựa trên Git hiện nay
  • Khi dùng cờ --nvim, gói sẽ được cài vào cấu trúc cây tương thích với :h packages của Neovim

Lockfile cho tích hợp Nix

  • Nếu plugin Neovim tồn tại dưới dạng gói Luarocks, nixpkgs sẽ dùng nó làm source chuẩn
    • Vì trong một trình quản lý gói phù hợp, trách nhiệm khai báo dependency thuộc về tác giả gói
  • Hỗ trợ lockfile của Luarocks còn cơ bản và không bao gồm source hash
  • Cả Luarocks và Lux đều hỗ trợ các dependency xung đột thông qua luarocks.loader
  • nixpkgs khó bổ sung hợp lý nhiều phiên bản của cùng một dependency vào package set
  • lux.lock của Lux lưu source hash và rockspec hash của từng dependency
    • Nếu source URL là Git repository, Lux lưu NAR hash
    • lux.lock có thể được dùng để tạo fixed-output derivation bao gồm tất cả dependency, giống như Cargo.lock

Các bước tiếp theo và tài liệu

  • Ưu tiên hiện tại là sửa lỗi và cải thiện thông báo lỗi
  • rocks.nvim dự kiến sẽ được viết lại để dùng Lux bên trong thay cho Luarocks
    • Việc viết lại này nhằm đưa tốc độ của rocks.nvim lên ngang tầm các trình quản lý plugin khác
    • Nếu thành công, đây sẽ là ví dụ cho thấy Lux cũng có thể được nhúng ở nơi khác
    • lazy.nvim, từng được nhắc đến vì có vấn đề liên quan đến Luarocks trước đây, được nêu làm ví dụ
  • Người dùng ban đầu có thể xem tutorial và hướng dẫn trên trang tài liệu
  • Câu hỏi hoặc issue có thể được gửi qua GitHub discussions hoặc issue tracker
  • Lux dùng giấy phép LGPLv3.0+, còn logo Lux được cấp phép CC BY-NC-SA 4.0 của © 2025 Kai Jakobi

1 bình luận

 
GN⁺ 2025-04-09
Ý kiến trên Hacker News
  • Gót chân Achilles của các ngôn ngữ kịch bản là môi trường thực thi. Cá nhân tôi không dùng Neovim, nhưng tôi từng nghĩ việc Neovim được chấp nhận rộng rãi sẽ thúc đẩy sự phát triển của mảng này bên phía Lua
    Bryan Cantrill từng gọi JavaScript là “LISP mặc đồ C”, và ở một khía cạnh nào đó Lua lại cho tôi cảm giác như điều ngược lại, nên tôi thích nó. Dù vậy, tôi chưa từng phải dùng nó trong công việc

    • Tôi không hiểu cơ sở nào để nói JavaScript là Lisp mặc đồ C. Tôi cũng không thấy Lua liên quan gì đến Lisp, và hoàn toàn không có cú pháp Lisp
  • Tôi biết có những dự án như Koreader[1] dùng Lua làm ngôn ngữ ứng dụng chính. Nếu có thể thuyết phục một dự án như vậy chuyển sang, điều đó có lẽ sẽ tạo thêm niềm tin nhất định về mức độ trưởng thành và độ phổ biến của ý tưởng này
    [1]: https://github.com/koreader/koreader

    • Gợi ý hay đấy. Lux sẽ cần thêm thời gian để trưởng thành, nhưng việc build một dự án đa nền tảng lớn như koreader chắc chắn có thể là một mục tiêu tốt
  • Trông thực sự rất ổn. Tôi dùng Lua khá nhiều, nhưng luarocks quá nặng tính định hướng nên hầu như vô dụng với những gì tôi cần
    Chỉ cần hơi lệch khỏi kiểu “cài thư viện để chạy trực tiếp trên hệ thống cục bộ” là đã bế tắc ngay từ đầu. Nếu bạn có một môi trường scripting nhúng dùng các gói Lua và muốn đóng gói script cùng các dependency để phát hành, thì coi như bó tay
    Tôi không biết công cụ này có làm tốt hơn cho mục đích đó không, nhưng dù không thì luarocks, nói nhẹ nhất, vẫn khá thô và khó chịu khi dùng

    • Cộng đồng Lua phụ thuộc cực kỳ nhiều vào thư viện C, và gần như mọi gói luarocks đều cố build thư viện, nên trên Windows về cơ bản nó trở nên vô dụng
  • Dự án thú vị đấy. Tôi muốn cùng làm để xây dựng hỗ trợ Lua tốt hơn trong Pixi thông qua hệ sinh thái conda-forge
    Chúng tôi đã đóng gói lua và một vài phần mở rộng C rồi. Phần mở rộng C là lĩnh vực cốt lõi của Pixi, nên tôi nghĩ có thể rất hợp
    Tài liệu pixi.sh và gói lua trong registry: https://prefix.dev/channels/conda-forge/packages/lua

    • Nghe như một ý hay. Tôi đã mở an issue trong kho lưu trữ, cứ ping ở đó là được
  • Tôi hỏi vì không thấy điều này ở đây hay trên các trang liên quan: nó có tích hợp gốc với package.pathpackage.cpath không, có phát hiện các bản cài đặt không chuẩn nhưng phổ biến như brew(1) không, và có thể cài theo kiểu GitHub :user/:repository không
    Dự án trông rất ngầu và được làm khá tốt

    • Các lệnh lx runlx lua sẽ thiết lập PATH, LUA_PATH, LUA_CPATH. Ngoài ra còn có lệnh lx path để thiết lập các biến môi trường đó
      Việc phát hiện cài đặt Lua về cơ bản dùng pkg-config, và nếu không tìm thấy thì sẽ thử cài Lua bằng các crate lua_srcluajit_src. Về sau có thể thêm hỗ trợ cho các công cụ khác như vcpkg
      Việc cài theo kiểu GitHub :user/:repository thì chưa có. Có kế hoạch thêm vào lux.toml/đặc tả dependency, nhưng có lẽ sẽ không cho phép đăng rockspec theo kiểu đó lên luarocks.org. Vì tôi không muốn trở thành nguyên nhân khiến mọi người tải lên các gói mà luarocks không thể build
  • Một trình quản lý gói cho một ngôn ngữ được thiết kế để nhúng vào C và phụ thuộc nhiều vào thư viện C lại được viết bằng Rust, trong khi bản thân Lua được tạo ra làm ngôn ngữ cấu hình cho chương trình C, còn cấu hình lại dùng TOML à
    Tôi xin kiếu. Luarocks có giới hạn và có lẽ cần viết lại, nhưng nên dùng ngôn ngữ phù hợp với hệ sinh thái và đi theo văn hóa của hệ sinh thái Lua. Rust và Cargo gần như ở phía đối lập hoàn toàn với Lua

    • Lua đã phát triển và hiện được dùng ở nhiều nơi hơn rất nhiều so với mục đích ban đầu khi nó được tạo ra
  • Cá nhân tôi đã quá ngán mấy kiểu trình quản lý gói theo từng ngôn ngữ như thế này. Nó không có vẻ là hướng đi đúng, và cách tiếp cận như nix trông tốt hơn nhiều

    • Một trong những động lực của Lux là cải thiện hệ sinh thái Lua và Neovim trong nixpkgs
  • Trình quản lý gói cho Lua mà lại phụ thuộc vào Rust cơ à

    • Có vẻ chẳng sao cả. Phần lớn trình quản lý gói đều hỗ trợ cài các gói chỉ có binary
    • Có thể bạn sẽ ngạc nhiên vì nó chạy tốt hơn bạn nghĩ đấy
    • Còn dùng cả TOML nữa
  • Tôi thích đấy. Tôi đã muốn có một cách cài gói Lua có thể tái lập trên nhiều máy từ khá lâu rồi

    • Tôi cũng đã tạo được trạng thái cài gói Lua có thể tái lập trên nhiều máy, nhưng Lua chủ yếu được dùng theo hai kiểu
      Một là dùng kiểu “thô”, liên kết vào VM nội bộ và quản lý codebase .lua như một phần của quy trình build dự án; hai là dùng như công cụ hệ thống, kết hợp luarocks --local, các công cụ như luaenv, đưa vào Makefile/CMakeLists.txt, rồi trộn thêm một chút luastatic vào các bản bundle để phát hành
      Thành thật mà nói, chuyện này không khác Python hay các ngôn ngữ kịch bản khác có thể được đóng gói kèm bao nhiêu. Chỉ là lúc nào cũng phải phân biệt giữa /bin/script_language do hệ thống cung cấp và ngôn ngữ được dùng như công cụ dev/script engine bên trong một dự án lớn hơn hoặc như công cụ cho môi trường làm việc cục bộ
      Một trong những lý do tôi thực sự thích Lua là việc đóng gói thư viện, liên kết bytecode, bọc bundle lại và cung cấp cho người dùng hệ điều hành đích dưới dạng cài đặt một cú nhấp khá dễ và thú vị. Tất nhiên, vẫn phải tự xắn tay làm một chút
  • Tuyệt thì có tuyệt, nhưng cảm giác là nó đang đi ngược mạnh với định hướng thiết kế của Lua. Lua được thiết kế như một ngôn ngữ để nhúng đơn giản, và ở đây “quản lý gói” gần như chỉ là tải vài file zip về rồi giải nén, còn “quản lý phiên bản” thì gần với việc chọn dùng tương thích 5.1 hay tương thích 5.4 hơn