Debug Python thì có pdb. Nhưng giao diện Odoo phần lớn là JavaScript và CSS chạy trên trình duyệt — và ở chế độ thường, chúng bị gộp lại thành một khối nén khổng lồ. Mở DevTools thấy lỗi "ở dòng 1 của file 1MB" thì chịu. Bài này giải quyết đúng vấn đề đó: chế độ assets dev và source map.

Vì sao khó debug: assets bị gộp

Ở chế độ production, Odoo gộp hàng trăm file JS/CSS của mọi module thành vài bundle, rồi nén (minify) và gắn hash nội dung vào URL. Đây là URL bundle thật lấy từ trang login Odoo 19 của loạt bài:

Sơ đồ assets Odoo 19 từ nhiều file rời thành một bundle gộp và nén kèm hash: ở chế độ production trang web tải đúng ba bundle đã gộp hàng trăm file, ví dụ đường dẫn web assets 1 gạch chéo 859b7c1 gạch chéo web.assets_frontend.min.css nặng 1.014.053 byte và web.assets_frontend_lazy.min.js, trong đó đoạn 859b7c1 là hash nội dung nên đổi CSS hoặc JS thì hash đổi khiến trình duyệt tải bản mới; ở chế độ dev bật bằng cờ dev bằng assets thì mỗi file js và css nạp riêng giữ nguyên tên và số dòng nên DevTools chỉ đúng dòng lỗi và đặt breakpoint được, ví dụ file quan_ca_phe static src js the_widget.js hiện đúng file gốc; source map là cầu nối giữa bản nén và mã gốc qua dòng sourceMappingURL ở cuối file min.js giúp DevTools hiện lỗi ở file gốc dù đang chạy bản nén

Hình 1: Chế độ production gộp mọi file thành bundle như web.assets_frontend.min.css (1.014.053 byte thật — hơn 1MB). Đoạn 859b7c1 trong URL là hash nội dung: sửa CSS/JS thì hash đổi, trình duyệt tự tải bản mới (cache-busting). Tuyệt cho tốc độ, nhưng thảm hoạ để debug vì mọi thứ dồn vào một dòng.

Giải pháp: --dev=assets

Bật tính năng assets của cờ dev thì Odoo ngừng gộp và ngừng nén — mỗi file JS/CSS nạp riêng, giữ nguyên tên và số dòng:

odoo --dev=assets -d blog19
# hoặc trong giao diện: Cài đặt → Kích hoạt "Chế độ nhà phát triển (có tài nguyên)"

Khi đó mở DevTools (F12), tab Sources, bạn thấy đúng cây file gốc như quan_ca_phe/static/src/js/the_widget.js — đặt breakpoint, xem biến, bước từng dòng y như debug code thường. Đây chính là lý do menu Odoo có hai mục dev tách biệt: "Chế độ dev" và "Chế độ dev có assets".

Đây là giao diện web thật

Toàn bộ trang này (login, menu, footer) được dựng từ các bundle asset nói trên. Ảnh chụp thật từ Odoo 19 của loạt bài:

Ảnh chụp thật trang đăng nhập website Odoo 19 giao diện tiếng Việt: thanh trên cùng có logo Your Logo, menu Trang chủ, biểu tượng giỏ hàng và tìm kiếm, số điện thoại, nút chọn ngôn ngữ Tiếng Việt, nút Đăng nhập và Liên hệ; giữa trang là biểu mẫu đăng nhập với ô Email nhập email, ô Mật khẩu nhập mật khẩu kèm link Đặt lại mật khẩu, nút Đăng nhập màu tím, dòng Bạn chưa có tài khoản, và nút Sử dụng khoá truy cập; chân trang có ba cột Liên kết hữu ích, Về chúng tôi với đoạn giới thiệu, và Kết nối với chúng tôi kèm email và số điện thoại cùng các biểu tượng mạng xã hội

Hình 2: Giao diện web Odoo 19 thật (đã dịch tiếng Việt). Mọi thành phần — nút, form, footer — đều do CSS/JS trong các bundle web.assets_frontend vẽ ra. Khi một nút không hoạt động hay bố cục vỡ, --dev=assets là thứ giúp bạn lần ra file gốc gây lỗi.

Source map: cầu nối bản nén ↔ mã gốc

Ngay cả khi chạy bản nén, trình duyệt vẫn có thể chỉ đúng lỗi về mã gốc nhờ source map — một file .map ánh xạ từng ký tự bản nén về vị trí gốc. Cuối file .min.js thường có dòng:

//# sourceMappingURL=web.assets_frontend.min.js.map

DevTools đọc dòng này, tải file .map, và hiện stack trace ở file + dòng gốc thay vì "dòng 1 của bundle". Bật source map trong DevTools (Settings → Enable JavaScript source maps) là bạn debug được cả bản đã nén.

Quy trình debug frontend thực tế

  1. Bật --dev=assets (hoặc chế độ dev có assets trong Cài đặt).
  2. F12 → tab Console xem lỗi, tab Sources để đặt breakpoint.
  3. Sửa file JS/CSS → nhờ reload assets của chế độ dev, F5 là thấy ngay, không cần -u.
  4. Xong việc thì tắt dev — production phải chạy bundle gộp để nhanh.

Lưu ý hiệu năng

Đừng bao giờ để --dev=assets trên production: tải hàng trăm file rời thay vì 3 bundle làm trang chậm hẳn và tăng tải máy chủ. Chế độ dev chỉ để debug.

Nhớ ba ý

  1. Production gộp + nén + hash mọi JS/CSS thành vài bundle (thật: web.assets_frontend.min.css hơn 1MB) — nhanh nhưng khó debug.
  2. --dev=assets tách bundle ra thành file gốc riêng lẻ, giữ tên và số dòng — DevTools chỉ đúng chỗ, đặt breakpoint được.
  3. Source map (sourceMappingURL) trỏ lỗi của bản nén về mã gốc; bật nó trong DevTools để debug ngay cả bản production.

Debug được cả hai phía rồi, ta chuyển sang vận hành. Phần sau bàn cách một máy chủ Odoo phục vụ nhiều database và dùng --db-filter để chọn đúng database theo tên miền.