Đây là một ví dụ cụ thể hơn.
Tôi đang làm việc trong một dự án với 60 tệp. Chúng tôi có 2 chế độ khác nhau để chạy nó.
Tải một phiên bản nối, 1 tệp lớn. (Sản xuất)
Tải tất cả 60 tệp (phát triển)
Chúng tôi đang sử dụng trình tải để chúng tôi có một tập lệnh trong trang web
<script src="loader.js"></script>
Mặc định đó là chế độ # 1 (tải một tệp được nối lớn). Để chạy ở chế độ # 2 (các tệp riêng biệt), chúng tôi đặt một số cờ. Nó có thể là bất cứ điều gì. Một khóa trong chuỗi truy vấn. Trong ví dụ này, chúng tôi chỉ làm điều này
<script>useDebugVersion = true;</script>
<script src="loader.js"></script>
loader.js trông giống như thế này
if (useDebugVersion) {
injectScript("app.js");
injectScript("somelib.js");
injectScript("someotherlib.js");
injectScript("anotherlib.js");
... repeat for 60 files ...
} else {
injectScript("large-concatinated.js");
}
Tập lệnh xây dựng chỉ là một tệp .sh trông như thế này
cat > large-concantinated.js app.js somelib.js someotherlib.js anotherlib.js
Vân vân...
Nếu một tệp mới được thêm vào, chúng tôi có thể sẽ sử dụng chế độ # 2 vì chúng tôi đang phát triển, chúng tôi phải thêm một injectScript("somenewfile.js")
dòng vào loader.js
Sau đó, để sản xuất, chúng tôi cũng phải thêm somenewfile.js vào tập lệnh xây dựng của chúng tôi. Một bước chúng ta thường quên và sau đó nhận được thông báo lỗi.
Bằng cách chuyển sang AMD, chúng tôi không phải chỉnh sửa 2 tệp. Vấn đề giữ loader.js và tập lệnh xây dựng đồng bộ biến mất. Sử dụng r.js
hoặcwebpack
nó chỉ có thể đọc mã để xây dựnglarge-concantinated.js
Nó cũng có thể xử lý các phụ thuộc, ví dụ: chúng tôi có 2 tệp lib1.js và lib2.js được tải như thế này
injectScript("lib1.js");
injectScript("lib2.js");
lib2 cần lib1. Nó có mã bên trong mà làm một cái gì đó như
lib1Api.installPlugin(...);
Nhưng vì các tập lệnh được chèn được tải không đồng bộ, không có gì đảm bảo chúng sẽ tải theo đúng thứ tự. 2 tập lệnh này không phải là tập lệnh AMD nhưng sử dụng các tệp.j.j chúng ta có thể nói với nó các phụ thuộc của chúng
require.config({
paths: {
lib1: './path/to/lib1',
lib2: './path/to/lib2',
},
shim: {
lib1: {
"exports": 'lib1Api',
},
lib2: {
"deps": ["lib1"],
},
}
});
Tôi mô-đun của chúng tôi sử dụng lib1 chúng tôi làm điều này
define(['lib1'], function(lib1Api) {
lib1Api.doSomething(...);
});
Bây giờ allow.js sẽ tiêm các tập lệnh cho chúng tôi và nó sẽ không tiêm lib2 cho đến khi lib1 được tải vì chúng tôi đã nói với nó lib2 phụ thuộc vào lib1. Nó cũng sẽ không khởi động mô-đun của chúng tôi sử dụng lib1 cho đến khi cả lib2 và lib1 được tải.
Điều này làm cho sự phát triển trở nên tốt đẹp (không có bước xây dựng, không phải lo lắng về việc tải đơn hàng) và nó làm cho việc sản xuất trở nên tốt đẹp (không cần cập nhật tập lệnh xây dựng cho mỗi tập lệnh được thêm vào).
Là một phần thưởng bổ sung, chúng tôi có thể sử dụng plugin babel của webpack để chạy babel qua mã cho các trình duyệt cũ hơn và một lần nữa chúng tôi không phải duy trì tập lệnh xây dựng đó.
Lưu ý rằng nếu Chrome (trình duyệt lựa chọn của chúng tôi) bắt đầu hỗ trợ import
thực sự thì có lẽ chúng tôi sẽ chuyển sang phát triển nhưng điều đó sẽ không thực sự thay đổi bất cứ điều gì. Chúng tôi vẫn có thể sử dụng gói web để tạo một tệp được nối và chúng tôi có thể sử dụng nó để chạy babel qua mã cho tất cả các trình duyệt.
Tất cả điều này có được bằng cách không sử dụng thẻ script và sử dụng AMD