7 điểm bởi GN⁺ 2025-10-07 | 2 bình luận | Chia sẻ qua WhatsApp
  • mise vừa công bố tính năng tác vụ monorepo mới
  • Cung cấp một không gian tên tác vụ hợp nhất để dễ dàng quản lý môi trường, công cụ và tác vụ của từng dự án trong kho chứa nhiều dự án
  • Bao gồm nhiều tính năng như mẫu wildcard mạnh mẽ, kế thừa môi trường/công cụ và ngữ cảnh thực thi nhất quán
  • Mang lại sự đơn giản và linh hoạt cho các monorepo dùng nhiều ngôn ngữ hoặc có môi trường phức tạp
  • So với Bazel, Turborepo và các công cụ hiện có, điểm mạnh là không phụ thuộc ngôn ngữ, dễ cấu hình và quản lý hợp nhất

Giới thiệu: Công bố tính năng tác vụ monorepo

  • mise đã giới thiệu một tính năng mới tên là Monorepo Tasks
  • Cung cấp hỗ trợ monorepo cấp cao để có thể duy trì độc lập và quản lý hiệu quả công cụ, biến môi trường và tác vụ theo từng dự án trong một kho chứa bao gồm nhiều dự án

Các tính năng chính

  • Không gian tên tác vụ hợp nhất: Tự động phát hiện mọi tác vụ trong monorepo và gắn tiền tố theo vị trí để phân biệt rõ ràng
    Ví dụ:
    mise //projects/frontend:build
    mise //services/api:deploy
  • Kế thừa công cụ và môi trường thông minh: Định nghĩa công cụ dùng chung ở root và có thể ghi đè tại các dự án con khi cần
    • Ví dụ: thiết lập node=20, python=3.12 trong mise.toml ở root sẽ tự động được kế thừa bởi mọi dự án con
    • Có thể override thành node=14 trong một dự án cụ thể (mise.toml), trong khi thiết lập python từ cấp trên vẫn tiếp tục được kế thừa
  • Mẫu wildcard mạnh mẽ:
    • Chạy test cho mọi dự án: mise //...:test
    • Chạy mọi bản build dưới services/: mise //services/...:build
    • Chạy mọi tác vụ trong frontend: mise '//projects/frontend:*'
    • Có thể chạy theo nhóm dựa trên tên tác vụ
  • Thực thi nhất quán ở mọi nơi: Dù chạy tác vụ ở đâu, nó vẫn sẽ được thực thi với đúng môi trường và công cụ được định nghĩa tại config_root của tác vụ đó
  • Tự động lan truyền độ tin cậy: Chỉ cần đánh dấu trust cho root monorepo là các cấu hình con sẽ tự động được trust

Hướng dẫn bắt đầu nhanh

  1. Trong mise.toml ở root, đặt experimental_monorepo_root=true
  2. Bật cờ thử nghiệm (MISE_EXPERIMENTAL=1)
  3. Thêm tasks vào mise.toml của từng dự án
    • Ví dụ:
      [tasks.build]
      run = "npm run build"
  4. Chạy tác vụ mong muốn từ root hoặc bất kỳ đường dẫn nào
    • mise //projects/frontend:build
    • mise //...:test

Ví dụ cấu trúc monorepo

  • myproject/
    ├── mise.toml (experimental_monorepo_root = true)
    ├── services/
    │ ├── api/mise.toml
    │ ├── worker/mise.toml
    │ └── scheduler/mise.toml
    └── apps/
    ├── web/mise.toml
    └── mobile/mise.toml
  • Chạy build cho mọi service: mise //services/...:build
  • Chạy test cho mọi app: mise //apps/...:test
  • Toàn bộ tác vụ: mise '//...:*'

Bối cảnh ra đời và hiệu quả

  • Bắt nguồn từ bài toán độ phức tạp trong quản lý monorepo và các script lặp đi lặp lại
  • Định nghĩa một lần, chạy ở mọi nơi để giảm thiểu trùng lặp
  • Tự động áp dụng chính xác công cụ/môi trường cho từng dự án
  • Đơn giản hóa pipeline CI/CD nhờ wildcard mạnh mẽ
  • Không gian tên tác vụ giúp việc khám phá và hiểu hệ thống tốt hơn

So sánh với các công cụ phổ biến hiện có

  • Simple Task Runners (Taskfile, Just, v.v.)

    • Tối ưu cho tự động hóa trong một dự án đơn lẻ; trong monorepo không hỗ trợ không gian tên hợp nhất, kế thừa hay wildcard
    • mise cung cấp tự động phát hiện tác vụ và hỗ trợ mẫu mạnh mẽ
  • Công cụ tập trung vào JavaScript (Nx, Turborepo, Lerna)

    • Mạnh trong monorepo JS/TS (dependency graph, codegen, cache, v.v.)
    • mise không phụ thuộc ngôn ngữ, hỗ trợ nhiều ngôn ngữ/stack và quản lý hợp nhất công cụ/biến môi trường
  • Hệ thống build quy mô lớn (Bazel, Buck2)

    • Cung cấp distributed cache, remote execution, v.v. nhưng độ phức tạp và đường cong học tập cao, kèm nhiều ràng buộc về cấu trúc
    • mise theo hướng tiếp cận non-hermetic, cho phép cấu hình linh hoạt và triển khai dễ dàng
  • Khác (Rush, Moon, v.v.)

    • Rush: orchestration build dành riêng cho JS
    • Moon: dựa trên Rust, hướng tới hỗ trợ đa ngôn ngữ

Điểm đặc biệt của mise Monorepo Tasks

Tính năng Simple Runners Chuyên JS Build Systems mise
Hỗ trợ đa ngôn ngữ
Dễ học ⚠️
Phát hiện tác vụ hợp nhất
Mẫu wildcard ⚠️
Quản lý phiên bản công cụ ⚠️
Kế thừa môi trường ⚠️
Cấu hình tối thiểu ⚠️
Caching tác vụ
  • Khi nào nên chọn Mise?
    • Monorepo đa ngôn ngữ
    • Quản lý hợp nhất công cụ và tác vụ
    • Khi ưu tiên sự gọn nhẹ
    • Phù hợp với người đã có kinh nghiệm dùng mise
  • Khi nào nên cân nhắc công cụ khác
    • Chỉ tập trung vào JS/TS → Nx, Turborepo
    • Enterprise cực lớn (Google/Meta, v.v.) → Bazel, Buck2
    • Cần caching tác vụ nâng cao → Nx, Turborepo, Bazel

Kết luận

  • Tính năng tác vụ monorepo của mise được thiết kế để giúp quản lý các monorepo phức tạp trong nhiều môi trường ngôn ngữ một cách dễ dàng và nhất quán, không bị giới hạn trong một ngôn ngữ duy nhất
  • Với cấu hình tối thiểu và các mẫu tác vụ mạnh mẽ, tính năng này cải thiện cả năng suất lẫn trải nghiệm của lập trình viên
  • So với các giải pháp enterprise phức tạp, nó đơn giản và linh hoạt hơn nhiều

2 bình luận

 
GN⁺ 2025-10-07
Ý kiến trên Hacker News
  • Trước đây khi chủ yếu dùng Python, tôi không thực sự cảm nhận được sức hút của Mise, vì nghĩ chỉ cần uv là đủ
    Nhưng khi cần khớp phiên bản theo từng thư mục như Node, và cần các điểm vào chung như mise build hay mise test bất kể ngôn ngữ hay loại dự án, tôi mới thấy rõ giá trị thực sự của Mise
    Tôi cũng rất thích Just như một task runner, nhờ đó có thể rời xa Make
    Make rất mạnh, nhưng về trải nghiệm phát triển thì vẫn có chỗ đáng tiếc
    Just có thể mạnh hơn Mise về mặt tính năng task, nhưng với tôi, Mise là sự kết hợp tốt nhất nhờ có tính năng task khá ổn cùng khả năng quản lý công cụ xuất sắc

    • Là một người thích Makefile đơn giản, tôi tò mò không biết có những lợi ích gì khi chuyển từ Make sang Just rồi đến Mise

    • Tôi từng thực sự rất thích just, nhưng việc thiết lập đúng môi trường cho just task khá phiền, và cả việc nạp virtual environment cũng rất bất tiện
      Vì những lý do tương tự nên tôi đã chuyển sang mise

  • Tôi đặt kỳ vọng rất lớn vào mise
    Nó đã nhanh chóng trở thành công cụ không thể thiếu mỗi khi bắt đầu một dự án mới
    Việc có thể quản lý nhiều công cụ như node, python, rust, go cùng lúc và thay thế makefile bằng một cấu hình duy nhất rất tiện lợi
    Tôi thường thiết lập hook postinstall, nên khi ai đó nhận dự án của tôi chỉ cần chạy mise install là toàn bộ phiên bản công cụ phù hợp và cả các gói phụ thuộc đều được cài tự động, rất dễ dàng
    Trong khi tôi thấy rào cản tiếp cận của nix khá cao, mise thực tế hơn nhiều

    • Nếu cách tiếp cận của Nix khiến bạn thấy nặng nề, các công cụ như devenv.sh có thể giúp việc tiếp cận dễ dàng hơn nhiều
      Ví dụ, bạn có thể thiết lập ngay môi trường phát triển rust bằng languages.rust.enable = true
      Ngoài ra còn có thể thêm script, task và package

    • Không biết bạn có thể chia sẻ cấu hình ví dụ không
      Nghe khá thú vị
      Tôi đã dùng just và docker(-compose) trong các dự án monorepo, còn trải nghiệm thử moon & proto thì ngắn và hơi thất vọng
      Tôi thích sự đơn giản của just, nhưng khi onboarding thành viên mới trên nhiều nền tảng khác nhau thì vẫn khá phiền

    • Tôi cũng đã thử setup dự án mới bằng mise
      Người mới vào có thể bắt đầu dễ dàng hơn rất nhiều mà không cần các bước thủ công, thực sự tuyệt vời

    • Tôi thấy cách dùng hook postinstall trong mise khá thú vị
      Không biết bạn thường đưa những gì vào đó

  • Việc không hỗ trợ task cache là một thiếu sót khá lớn
    Khi có dependency trong đồ thị công việc, các task đã hoàn thành nên được xử lý qua cache thay vì chạy lại, điều này rất quan trọng để tối ưu các lần chạy lặp, nhất là trong monorepo cỡ vừa
    Tôi đã tìm xem có kế hoạch cho tính năng này không, nhưng issue trong kho lưu trữ Mise đã bị tắt và README cũng không nhắc gì, nên tôi không thấy yên tâm lắm
    Nếu bạn dùng npm monorepo một ngôn ngữ, tôi khuyên dùng Wireit
    Wireit bổ sung dependency cùng cache cục bộ/GitHub Actions cho npm script, và còn có task kiểu service chạy lâu dài
    Wireit GitHub

    • Mise cũng hỗ trợ cache cục bộ cho các task kiểu Make
      Có thể làm được nếu chỉ định sources và outputs, xem tại hướng dẫn cấu hình task của mise
      Chỉ cần chỉ định sources là cũng sẽ tự động theo dõi thay đổi của source
      Tôi đã yêu cầu tính năng này từ lâu để tăng tốc build Docker, và đang dùng rất hiệu quả

    • Ngược lại, việc mise ít quan tâm hơn đến mã nguồn dự án hay dependency thư viện lại là sức hút của sự đơn giản
      Thường nó chỉ cung cấp tính năng đến đúng ranh giới đó

    • Task caching không phải là hướng đi của mise
      Xem tài liệu anti-goals chính thức
      turbopack, moonrepo và các công cụ khác đã tập trung vào bài toán này
      Mise nhiều khả năng sẽ tiếp tục là một task runner nhẹ, tập trung đơn thuần vào việc chạy script

    • Tôi cũng không rõ vì sao issue trong kho lưu trữ Mise bị tắt
      Trước đây từng có một issue kiểu “maintainer thích discussion hơn issues”, nhưng giờ đã biến mất
      Tôi đã mở cuộc thảo luận này về chủ đề đó
      Từ góc nhìn của người đã dùng vài năm như tôi, tôi khá tin tưởng dự án này và cũng hay giới thiệu cho người khác
      Tôi khuyên bạn nên tham khảo discussions và trải nghiệm sử dụng thực tế

    • Điều này hơi giống như đòi hỏi mise phải có các tính năng của một build system kiểu bazel
      Có thể nói nó đã phần nào đảm nhiệm vai trò đó rồi
      Tính năng cache thì hữu ích thật, nhưng thêm vào có thể làm độ phức tạp tăng mạnh nên cần cẩn trọng
      Cũng đáng để nghĩ đến cách tích hợp với các build system hiện có

  • mise có vẻ khá ổn
    Chỉ là từ góc nhìn của người dùng asdf hiện tại, tôi hơi lưỡng lự vì mise có vẻ muốn quản lý quá nhiều thứ khác nhau (như thao tác với PATH)
    Việc nhiều công cụ mỗi cái lại động vào PATH theo cách riêng thực sự rất phiền, nên tôi đã tự cố định PATH trong .zprofile và bỏ hết các script khởi tạo linh tinh
    Sẽ rất tốt nếu mise có thể quản lý cả ngôn ngữ lập trình lẫn các ứng dụng CLI được cài qua ngôn ngữ đó (cargo, go, uv, v.v.) cùng một lúc, nhưng phần này có vẻ sẽ hơi phiền khi chuyển đổi

    • Bạn nói việc nhiều công cụ thao tác theo thứ tự ưu tiên PATH rất bất tiện, nhưng mise không làm vậy
      Nếu muốn thì bạn vẫn có thể dùng shim
      Nó hỗ trợ cả quản lý công cụ theo từng ngôn ngữ lẫn quản lý chính bản thân ngôn ngữ đó

    • Tôi không thực sự nhớ rõ vì sao trước đây đã chuyển từ asdf sang mise, nhưng sau vài năm dùng thì hoàn toàn không gặp vấn đề gì

  • Tôi thực sự xem mise là lựa chọn hàng đầu
    Nó rất phù hợp với những ai nghiêm túc về tự động hóa, thiết lập môi trường đồng nhất, và bootstrap nhanh cho dự án mới
    Đặc biệt trong môi trường Ruby/Python/Node, nó giúp giải quyết đơn giản các vấn đề như mỗi người một kiểu setup hay việc phải tái tạo môi trường lặp đi lặp lại mà không cần tới Docker hay thứ tương tự
    Với các nhóm nhỏ hoặc dự án cá nhân, bạn có thể dễ dàng tạo ra môi trường chạy lặp lại mà không cần CI hay build system (Bazel, Gradle, v.v.)
    Tôi cũng đang kết hợp nó với chezmoi để quản lý các công cụ hệ thống cục bộ rất tốt

  • Gần đây tôi đã chuyển từ just sang mise
    just cũng rất xuất sắc, nhưng nó chỉ cung cấp chức năng command runner đơn thuần, còn tôi cần thêm các tính năng mà mise có
    Tôi thấy quyết định chuyển đổi là đúng đắn
    Tuy vậy, sẽ tốt hơn nếu có tài liệu giải thích rõ ràng hơn về use case, lịch sử, so sánh với các công cụ khác (nix, docker, v.v.) và cấu trúc tổng thể để người mới dễ hiểu
    Tôi muốn tài liệu làm rõ hơn bằng các ví dụ về những khác biệt nhỏ trong thực tế để giải thích “vì sao” cần mise, và nó khác biệt ra sao so với các công cụ khác đã tồn tại

  • Tôi thực sự rất hào hứng với tin này
    Nó cho cảm giác như đang kết hợp hợp lý giữa ưu điểm của các task runner đơn giản như just/taskfile và sức mạnh của bazel/buck2
    Tôi tò mò muốn xem người khác sẽ tận dụng nó ra sao, và rất mong chờ những thử nghiệm mới

    • Tôi cũng dùng mise là chính và nhìn chung gần như hài lòng hoàn toàn
      Quy trình quản lý môi trường đã được đơn giản hóa rất nhiều
      Nhưng tôi không thực sự cần chức năng task runner
      Make hay just đã làm rất tốt vai trò đó rồi
      Dù chưa dùng trong monorepo thực tế, tôi nghĩ cả hai công cụ đều hỗ trợ import và mở rộng file task/recipe nên có thể thiết lập theo nhu cầu
      Trải nghiệm UX có thể không mượt như công cụ chuyên biệt, nhưng tôi thích mỗi công cụ tập trung vào một vai trò duy nhất
      Mise vốn đã bao gồm khá nhiều tính năng với vai trò environment manager rồi, nên tôi muốn nó tập trung vào phần đó hơn
      Nhân tiện, hình như bạn là tác giả của mise, xin cảm ơn
  • Nếu bạn muốn quản lý task của kho lưu trữ qua một điểm vào duy nhất, có thể cân nhắc dela do tôi tạo ra
    Nó quét các định nghĩa task file khác nhau như pyproject.toml, package.json, makefile, v.v. rồi cho phép chạy trực tiếp từ CLI bằng tên task
    Tôi thấy nó rất tiện vì có thể dùng ngay trên nhiều repo mà không cần chỉnh sửa gì, và cũng không cần thay đổi cấu trúc repo
    Nó chưa hỗ trợ task của mise, nhưng nếu có nhu cầu thì tôi sẵn sàng thêm ngay
    Theo thống kê gần đây, mise đang được dùng trong 94 trên 100.000 repo GitHub có nhiều sao
    Xem thêm dữ liệu chi tiết tại 2025 task runners census

    • Trông rất hay, không biết có hỗ trợ xem toàn bộ danh sách task không
      Mỗi khi vào một repo dự án Node, việc đầu tiên tôi làm luôn là chạy npm run để xem danh sách script
      Nếu có Makefile thì tôi sẽ mở ra xem, nhưng nếu target hay dependency đều được viết bằng biến thì tôi thường thoát luôn
  • Đúng lúc tôi đang nghĩ giá mà mise cũng có tính năng như thế này thì giờ nó lại vừa ra mắt, thật vui
    Điều tôi thích nhất khi dùng mise là khả năng cài các công cụ toàn cục ở backend bằng npm, go, cargo, v.v.
    Ví dụ có thể cài rất dễ chỉ với lệnh đơn giản như mise use -g npm:prettier
    Trước đây khi dùng nvm, tôi luôn phải nhớ gói global đã được cài vào phiên bản node nào, còn với mise thì mọi thứ tiện hơn rất nhiều
    Tuy vậy, gần đây khi tôi thử cài phiên bản Node mới nhất thì có một lỗi nhỏ là nó lại cài phiên bản mới thứ hai

  • Nếu bạn có thể dùng pure Nix-shell thì sức hấp dẫn của mise có thể giảm đi đôi chút
    Dù vậy, vì đường cong học tập thấp hơn Nix nên có lẽ nó sẽ được phổ biến rộng hơn

    • Mise thực sự nổi bật nếu nhìn từ góc độ giúp nhiều người khác nhau — chứ không chỉ bản thân bạn hay chiếc PC của bạn — có thể bootstrap dự án một cách dễ dàng
      Cấu hình dựa trên toml cũng rất đơn giản để mọi người hiểu
      Những chuyện trước đây như phải lục README rồi tự chỉnh môi trường thủ công, hay mỗi ngôn ngữ lại có cách cài khác nhau, đều không còn là vấn đề với mise
      Nó đặc biệt có lợi khi quản lý môi trường Node/Ruby/Python

    • Tôi đã dùng nix-darwin suốt 1 năm rồi cuối cùng chuyển sang mise
      mise đáp ứng được 90% nhu cầu cần thiết chỉ với 1% mức độ phiền phức
      Tôi vẫn thấy các khái niệm của nix rất hay, và tin rằng cách xây dựng phần mềm trong tương lai chắc chắn sẽ đi theo hướng này
      Chỉ là hiện tại, tôi không nghĩ nix nhất thiết sẽ là bên dẫn dắt xu hướng đó