Xin chào tất cả mọi người!
Tôi chắc rằng bạn đã thấy các dự án Node.js sử dụng các trình quản lý gói khác nhau, ví dụ:
Bản thân tôi đã nhìn thấy điều đó và làm việc với tất cả những điều trên, nhưng tôi luôn có một câu hỏi trong đầu - điều gì thúc đẩy mọi người/nhóm sử dụng sợi hoặc pnpm thay vì npm ? Ưu điểm là gì? Có bất kỳ khuyết điểm nào không?
Chà… Hãy cùng tìm hiểu nhé!
Tôi quyết định so sánh npm , sợi và pnpm về “tốc độ” của chúng…
Bạn sẽ thấy 3 biện pháp dưới đây:
Tạo một tập tin khóa mà không có bất kỳ bộ đệm nào.
Cài đặt các phần phụ thuộc từ các tệp khóa hiện có mà không cần bất kỳ bộ đệm nào.
Cài đặt các phần phụ thuộc từ các tệp khóa hiện có bằng bộ đệm chung.
Có hai loại bộ đệm:
Toàn cầu.
Thường được lưu trữ trong thư mục chính của người dùng (fe, ~/.yarn/berry/cache
).
Địa phương.
Được lưu trữ trong thư mục dự án (fe, <project-dir>/.yarn
).
Mặc dù #2 & #3 là những trường hợp sử dụng phổ biến nhất theo kinh nghiệm của tôi, nhưng tôi cũng lấy #1 để đề phòng (mặc dù đó là một trường hợp rất hiếm gặp).
Tôi đã sử dụng một dự án mẫu từ ứng dụng tạo phản ứng làm ví dụ cho điểm chuẩn.
Đó là trình quản lý gói mặc định cho hệ sinh thái Node.js - còn gì để nói nữa? Nó đi kèm với gói cài đặt, vì vậy về cơ bản nó sẵn sàng để sử dụng khi bạn cài đặt Node.js trên máy của mình (hoặc trong bất kỳ nhà cung cấp CI nào nếu bạn thiết lập Node.js ở đó).
Trong tâm trí tôi, đó là một tính năng “pro” rất lớn - bạn không cần phải cài đặt riêng!
Không có gì nổi bật ở đó - nó chỉ… hoạt động! Và tôi chưa thấy bất kỳ lỗi lớn nào trong nhiều năm - nó có vẻ khá ổn định và hoàn thành công việc.
Các tính năng của npm tôi đã sử dụng cho đến nay:
npm lưu trữ các phần phụ thuộc trong thư mục node_modules
của thư mục gốc dự án của bạn. Khá đơn giản.
ℹ️ package-lock.json
lưu trữ thông tin về cơ quan đăng ký cho các gói được liệt kê - nó RẤT hữu ích nếu bạn có các gói từ một phạm vi duy nhất, tức là @example-company
trong các cơ quan đăng ký khác nhau (ví dụ - Gói npm & GitHub ):
Bây giờ, hãy xem nó hoạt động như thế nào về tốc độ cài đặt…
Phải mấtpackage-lock.json
và cài đặt các phần phụ thuộc mà không cần bất kỳ bộ đệm nào.
Lệnh được sử dụng:
npm i
Phải mấtpackage-lock.json
mà không cần bất kỳ bộ đệm nào.
Lệnh được sử dụng:
npm ci
Phải mấtpackage-lock.json
với bộ đệm chung.
Lệnh được sử dụng:
npm ci
Tôi có thể tạo một không gian làm việc và quản lý các phần phụ thuộc cho toàn bộ không gian làm việc cùng một lúc và cho các dự án cụ thể một cách riêng biệt.
Nói cách khác - nó hoàn thành công việc mà không có bất kỳ lỗi/vấn đề nào và tài liệu chính thức khá đơn giản.
Các tính năng của không gian làm việc mà tôi đã sử dụng cho đến nay:
Thành thật mà nói, tôi chưa thử nhiều tính năng của sợi . Ý tôi là, tôi đã sử dụng nó rất nhiều với mục đích “cài đặt các phần phụ thuộc” khi làm việc trên một số dự án, và chỉ vậy thôi.
sợi không đi kèm với trình cài đặt Node.js , vì vậy bạn phải cài đặt riêng. Điều đó có nghĩa là sẽ có một bước bổ sung trong quy trình CI của bạn - bạn phải thiết lập sợi trước khi cài đặt các phần phụ thuộc dự án của mình.
sợi có hai cách tiếp cận để cài đặt các phụ thuộc:
“ Zero Installs ” (mặc định) - tạo thư mục .yarn
và liệt kê các gói trong tệp yarn.lock
& .pnp.cjs
.
Một cái thông thường - tương tự như npm , lưu trữ các phần phụ thuộc vào node_modules
và liệt kê chúng trong tệp yarn.lock
.
ℹ️ Tệp khóa sợi CHỈ lưu trữ thông tin về các cơ quan đăng ký cho tất cả các gói được liệt kê nếu bạn sử dụng phương pháp cài đặt cũ (thông thường).
⚠️ Hãy nhớ rằng “ Zero Installs ” dường như đang lưu trữ các gói trong bộ đệm cục bộ và cung cấp liên kết đến các tệp khóa của bạn:
Điều này có thể quan trọng đối với bạn nếu bạn có đường dẫn Dockerfile hoặc CI nơi bạn cài đặt các phần phụ thuộc trong một môi trường sạch và sau đó muốn chuyển nó sang môi trường khác (bạn sẽ phải sao chép cả thư mục .yarn
và bộ đệm cục bộ).
Vì phương pháp mặc định cho sợi hiện nay là “ Không cài đặt ” và có hiệu suất tốt hơn phương pháp cũ - chúng tôi sẽ chỉ ghi lại điểm chuẩn bằng phương pháp này.
Phải mấtyarn.lock
và cài đặt các phần phụ thuộc mà không cần bộ nhớ đệm.
Lệnh được sử dụng:
yarn install
Phải mất
Lệnh được sử dụng:
yarn install --frozen-lockfile
Phải mất
Lệnh được sử dụng:
yarn install --frozen-lockfile
Tôi có thể tạo một không gian làm việc và quản lý các phần phụ thuộc cho tất cả các dự án cùng một lúc và cho các dự án cụ thể một cách riêng biệt.
Các tính năng của không gian làm việc mà tôi đã sử dụng cho đến nay:
Tài liệu này ổn, nhưng tên lệnh và cờ hơi khó hiểu.
Ví dụ: tôi phải thực thi điều này để chạy tập lệnh test
trong dự án root ( . ) và lồng nhau b2b
:
yarn workspaces foreach -A --include '{.,b2b}' run test
So sánh với npm :
npm run test --workspace=b2b --include-workspace-root
pnpm hiện đang được quảng cáo rầm rộ - rất nhiều công ty và dự án nguồn mở sử dụng nó .
Giống như sợi - pnpm không đi kèm với trình cài đặt Node.js , vì vậy bạn phải cài đặt riêng. Điều đó có nghĩa là sẽ có một bước bổ sung trong quy trình CI của bạn - bạn sẽ phải thiết lập pnpm trước khi cài đặt các phần phụ thuộc dự án của mình.
pnpm được coi là “ Trình quản lý gói nhanh, hiệu quả về dung lượng ổ đĩa ” …
Thật vậy, tôi đồng ý với tuyên bố “hiệu quả về dung lượng ổ đĩa” về mặt quản lý các phần phụ thuộc cục bộ.
Theo mặc định, pnpm loại bỏ các phần phụ thuộc được chia sẻ trùng lặp. pnpm tạo liên kết tượng trưng cho các gói được sử dụng trong nhiều phần phụ thuộc. tức là, nếu gói a
và b
sử dụng gói c
làm phụ thuộc - pnpm sẽ lưu gói c
dưới dạng một bản sao duy nhất và tạo liên kết tượng trưng cho gói a
và b
. Bằng cách đó, trình quản lý gói không tạo bản sao cứng và tiết kiệm bộ nhớ trên ổ SSD/HDD của bạn.
ℹ️ pnpm-lock.yaml
không lưu trữ thông tin về việc đăng ký các gói được liệt kê.
⚠️ Hãy nhớ rằng pnpm đôi khi lưu trữ các phần phụ thuộc trong bộ đệm chung, thay vì giữ nó như một dự án.
Phải mấtpnpm-lock.yaml
và cài đặt các phần phụ thuộc mà không cần bất kỳ bộ đệm nào.
Lệnh được sử dụng:
pnpm install
Phải mấtpnpm-lock.yaml
mà không cần bộ đệm.
Lệnh được sử dụng:
pnpm i --frozen-lockfile
Phải mấtpnpm-lock.yaml
với bộ đệm chung.
Lệnh được sử dụng:
pnpm i --frozen-lockfile
Bây giờ, đó là lúc mọi thứ trở nên thực sự thú vị…
pnpm có rất nhiều tùy chọn cấu hình, nhưng một số chức năng cốt lõi không hoạt động!
Hãy xem lại một số lỗi mà tôi gặp phải:
Điều quan trọng là chỉ có thể cài đặt các phần phụ thuộc cho các dự án cụ thể -- điều này khá hữu ích cho monorepos khi bạn tạo các quy trình liên quan đến các dự án cụ thể trong không gian làm việc.
tức là, hãy tưởng tượng bạn có trong không gian làm việc của mình:
Tất cả đều là các dự án npm riêng biệt, nhưng chúng là một phần của cùng một repo ☝️
Bây giờ, bạn muốn một quy trình chỉ chạy thử nghiệm từ đầu đến cuối. Vì vậy, bạn chỉ cần kiểm tra phụ thuộc end-to-end, phải không?
Chà, bạn sẽ không thể làm điều đó - pnpm đang buộc bạn phải cài đặt các phần phụ thuộc cho toàn bộ không gian làm việc!
pnpm install --filter <project-name>
lẽ ra chỉ cài đặt các phần phụ thuộc cho các dự án đã chọn, nhưng nó không hoạt động.
Có một lỗi đã xảy ra một năm và gần đây nó đã được đóng lại bằng một bản sửa lỗi không hoạt động.
theo mặc định, pnpm cài đặt các phần phụ thuộc cho toàn bộ không gian làm việc (tất cả các dự án) khi bạn chạy pnpm install
Bạn có thể thay thế hành vi này nếu bạn đặt recursive-install=false
trong .npmrc
trong thư mục gốc của không gian làm việc.
NHƯNG nó lại giới thiệu một lỗi khác đã gần 2 năm rồi .
pnpm theo mặc định lưu trữ danh sách phụ thuộc trong một tệp khóa duy nhất (giống như npm và sợi ).
Bạn cũng có thể thay thế hành vi này nếu bạn đặt shared-workspace-lockfile=false
trong .npmrc
trong thư mục gốc của không gian làm việc của mình.
Điều đó sẽ cho phép chúng tôi giữ lại tính năng không gian làm việc và sử dụng cờ --ignore-workspace
để cài đặt các phần phụ thuộc cho một dự án cụ thể.
Dù sao, cài đặt này có thêm một số vấn đề:
eslint
và tsc --noEmit
gây ra lỗi "JavaScript hết bộ nhớ" trong quy trình Hành động GitHub của tôi.
Một số phần phụ thuộc được lưu trữ trong bộ đệm chung và được liên kết tượng trưng trong node_modules/.pnpm
.
# | npm | sợi | pnpm |
---|---|---|---|
Tạo một tập tin khóa | 60 giây | 16,5 giây | 31 giây |
Cài đặt phụ thuộc mà không cần bất kỳ bộ đệm nào | 18 giây | 11 giây | 8 giây |
Cài đặt phụ thuộc với bộ đệm chung | 8 giây | 8 giây | 5 giây |
Theo điểm chuẩn ở trên, npm là trình quản lý gói chậm nhất ☝️
Dù sao đi nữa, hãy giải thích những kết quả này…
Đó là một trường hợp hiếm hoi. Thông thường, một tệp khóa được tạo khi khởi tạo dự án và sau đó mở rộng khi bạn cài đặt/cập nhật gói.
Với ý nghĩ đó - có vẻ như đây không phải là điều quá quan trọng để bạn dựa vào khi chọn trình quản lý gói.
Trong hầu hết các trường hợp, dự án của bạn giữ một danh sách phụ thuộc cụ thể và bạn hiếm khi thêm/xóa thứ gì đó.
Rất có thể, đôi khi bạn sẽ thay đổi các phiên bản gói của mình - những thay đổi này rất nhỏ và bạn sẽ sử dụng lại các gói còn lại từ bộ đệm.
Nói cách khác, trường hợp sử dụng phổ biến là -- tìm nạp các gói mới từ sổ đăng ký gói và lấy phần còn lại từ bộ đệm.
pnpm (5-8 giây) nhanh gần gấp đôi so với npm (8-18 giây) với sợi (8-11 giây) ở giữa.
Tôi nghĩ pnpm thực hiện công việc tốt nhất nếu yêu cầu của bạn đối với trình quản lý gói chỉ đơn giản như “chỉ cài đặt phần phụ thuộc”.
Mặc dù pnpm không đi kèm với trình cài đặt Node.js sẵn có, nhưng bạn vẫn có thể dễ dàng thiết lập trong quy trình CI bằng corepack hoặc hành động hiện có .
Tôi thích npm hơn, bởi vì:
package-lock.json
để bạn có thể cài đặt các phần phụ thuộc với một phạm vi duy nhất từ các cơ quan đăng ký khác nhau.
Những ưu điểm này vượt xa số giây về tốc độ và dung lượng ổ đĩa mà tôi tiết kiệm được bằng sợi hoặc pnpm .
Tiêu chí của bạn để chọn một người quản lý gói là gì? Đừng ngại ngùng và hãy cho tôi biết suy nghĩ của bạn trong phần bình luận bên dưới! 👇 😊