Lỗi Glob Loader trong Astro 5 khi dùng Monorepo
Bản build Astro của bạn đã thành công. Không có lỗi. Không có cảnh báo. Nhưng nội dung của bạn lại bị thiếu.
Gần đây tôi đã gặp vấn đề này trong một pnpm monorepo. Tôi đang sử dụng content collections của Astro 5 để thêm các nhận định biên tập (editorial takes) vào các trang của mình. Ở môi trường local, mọi thứ hoạt động hoàn hảo. Nhưng trong pipeline CI, các trang lại được render với nội dung trống.
Vấn đề nằm ở cách glob loader phân giải (resolve) các đường dẫn.
Vấn đề
Astro glob loader phân giải các đường dẫn tương đối (relative base paths) từ process.cwd(). Nó không sử dụng vị trí của tệp cấu hình của bạn.
Trong một monorepo, CI của bạn thường chạy bản build từ thư mục gốc của workspace (workspace root). Ở local, có lẽ bạn chạy bản build từ thư mục ứng dụng (app directory).
- Local: cwd là
apps/oss-alternatives. Đường dẫn./contenthoạt động bình thường. - CI: cwd là thư mục gốc của repository. Đường dẫn
./contentkhông tồn tại.
Astro không báo lỗi khi không tìm thấy tệp nào. Nó chỉ đơn giản trả về một collection trống. Bạn sẽ xuất bản một trang web bị thiếu dữ liệu mà không hề hay biết.
Cách khắc phục
Đừng sử dụng các chuỗi tương đối cho đường dẫn nữa. Hãy sử dụng import.meta.url để neo (anchor) các đường dẫn của bạn vào tệp cấu hình thay vì thư mục làm việc (working directory).
Sử dụng mẫu này:
import { fileURLToPath } from "node:url";
const TAKES_DIR = fileURLToPath(
new URL("./content/per-alternative-takes", import.meta.url)
);
Điều này đảm bảo đường dẫn luôn chính xác, bất kể bạn chạy bản build từ đâu.
Tránh xung đột ID
Theo mặc định, glob loader sử dụng trường slug trong frontmatter làm ID. Nếu người dùng thêm một trường slug, nó có thể làm hỏng việc truy vấn dữ liệu của bạn. Hãy sử dụng generateId để ép tên tệp trở thành ID chính thức.
Bài học cho các nhà phát triển Monorepo
- Chạy smoke test từ workspace root ở local. Nếu bạn chỉ test từ thư mục app, bạn sẽ bỏ lỡ các lỗi về đường dẫn.
- Thêm các bước kiểm tra sức khỏe (health checks) cho collection. Trong môi trường dev, hãy ném ra một lỗi nếu một collection quan trọng trả về kết quả trống (zero items).
- Sử dụng phân giải đường dẫn tuyệt đối (absolute path resolution) cho mọi tham chiếu tệp trong các tệp cấu hình của bạn.
- Thêm bước kiểm tra sau khi deploy (post-deploy check) để xác minh rằng các nội dung quan trọng có tồn tại trong HTML thực tế.
Đừng bao giờ tin vào sự im lặng. Một bản build thành công không phải lúc nào cũng đồng nghĩa với một đợt triển khai (deployment) thành công.
