paint-brush
Tại sao bạn không cần PNPM và YARNby@bormando

Tại sao bạn không cần PNPM và YARN

Dmitrii Bormotov9m2024/07/23
Read on Terminal Reader

npm là trình quản lý gói mặc định cho hệ sinh thái **Node.js**. 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** ở đó). Nó ổn định và tốc độ tương đương với các trình quản lý gói khác.
featured image - Tại sao bạn không cần PNPM và YARN
Dmitrii Bormotov HackerNoon profile picture
0-item

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é!

Quy tắc so sánh hiệu suất

Tôi quyết định so sánh npm , sợipnpm về “tốc độ” của chúng…


Bạn sẽ thấy 3 biện pháp dưới đây:


  1. Tạo một tập tin khóa mà không có bất kỳ bộ đệm nào.


  2. 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.


  3. 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:


  1. 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 ).


  2. Đị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.

npm

Đó 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:


  1. Quản lý các phần phụ thuộc (cài đặt, gỡ bỏ, cập nhật)
  2. Xuất bản các gói (riêng tư, công khai)
  3. Gói liên kết cục bộ
  4. Quản lý không gian làm việc.

Quản lý phụ thuộc

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 ):


mục nhập gói-lock.json


Bây giờ, hãy xem nó hoạt động như thế nào về tốc độ cài đặt…

Tạo gói-lock.json mà không cần bất kỳ bộ đệm nào

Tạo gói-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


Phải mất 1 phút để npm tạo package-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

Cài đặt phụ thuộc từ package-lock.json mà không cần bất kỳ bộ đệm nào

Cài đặt các phần phụ thuộc từ package-lock.json mà không cần bất kỳ bộ đệm nào


Phải mất 18 giây để npm cài đặt các phần phụ thuộc từ package-lock.json mà không cần bất kỳ bộ đệm nào.


Lệnh được sử dụng:

 npm ci

Cài đặt phụ thuộc từ package-lock.json với Global Cache

Cài đặt các phần phụ thuộc từ package-lock.json với bộ đệm chung


Phải mất 8 giây để npm cài đặt các phần phụ thuộc từ package-lock.json với bộ đệm chung.


Lệnh được sử dụng:

 npm ci

Quản lý không gian làm việc

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:


  1. Cài đặt các phần phụ thuộc cho tất cả các dự án trong không gian làm việc.
  2. Cài đặt các phần phụ thuộc cho một dự án cụ thể.
  3. Chạy đệ quy một tập lệnh cho tất cả các dự án cùng một lúc.

sợi

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.

Quản lý phụ thuộc

sợi có hai cách tiếp cận để cài đặt các phụ thuộc:


  1. 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 .


  2. 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 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:


Liên kết gói

Đ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.

Tạo tập tin khóa mà không cần bất kỳ bộ đệm nào

Tạo các tệp khóa bằng sợi và cài đặt các phụ thuộc


Phải mất 16,5 giây để sợi tạo tệp yarn.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

Cài đặt 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 bằng phương pháp "Không cài đặt" và không có bất kỳ bộ đệm nào


Phải mất 11 giây để sợi cài đặt các phần phụ thuộc bằng phương pháp "Không cài đặt" và không có bất kỳ bộ nhớ đệm nào.


Lệnh được sử dụng:

 yarn install --frozen-lockfile

Cài đặt phụ thuộc từ các tệp khóa hiện có với bộ đệm chung


Cài đặt các phần phụ thuộc bằng phương pháp "Không cài đặt" và bộ đệm chung


Phải mất 8 giây để sợi cài đặt các phần phụ thuộc bằng phương pháp “Không cài đặt” và bộ nhớ đệm chung.


Lệnh được sử dụng:

 yarn install --frozen-lockfile

Quản lý không gian làm việc

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:


  1. Cài đặt các phần phụ thuộc cho tất cả các dự án trong không gian làm việc.
  2. Cài đặt các phần phụ thuộc cho một dự án cụ thể.
  3. Chạy đệ quy một tập lệnh cho tất cả các dự án cùng một lúc.


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

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.

Quản lý phụ thuộc

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 ab 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 ab . 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.

Tạo pnpm-lock.yaml mà không cần bất kỳ bộ đệm nào

Tạo pnpm-lock.yaml


Phải mất 31 giây để pnpm tạo pnpm-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

Cài đặt phụ thuộc từ pnpm-lock.yaml mà không cần bộ đệm chung

Cài đặt các phần phụ thuộc từ pnpm-lock.yaml mà không cần bộ đệm chung


Phải mất 16 giây để pnpm cài đặt các phần phụ thuộc từ pnpm-lock.yaml mà không cần bộ đệm.


Lệnh được sử dụng:

 pnpm i --frozen-lockfile


Cài đặt phụ thuộc từ tệp khóa hiện có với bộ đệm chung

Cài đặt phụ thuộc từ pnpm-lock-yaml bằng bộ đệm


Phải mất 5 giây để pnpm cài đặt các phần phụ thuộc từ pnpm-lock.yaml với bộ đệm chung.


Lệnh được sử dụng:

 pnpm i --frozen-lockfile

Quản lý không gian làm việc

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:

cài đặt pnpm --filter

Đ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:


  • một ứng dụng web,
  • máy chủ phụ trợ,
  • dự án thử nghiệm (thử nghiệm từ đầu đến cuối).


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.

đệ quy-cài đặt=false

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 .

Shared-workspace-lockfile=false

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ư npmsợ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 đề:


  1. eslinttsc --noEmit gây ra lỗi "JavaScript hết bộ nhớ" trong quy trình Hành động GitHub của tôi.


  2. 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 .

Kết quả so sánh hiệu suất

#

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…

Tạo một tập tin khóa

Đó 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.

Cài đặt phụ thuộc

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.

Phần kết luận

Sự kiện

  • pnpm thực sự là một trình quản lý gói “nhanh và hiệu quả về ổ đĩa” - điều này khá rõ ràng trong bài đánh giá hiện tại!


  • Tính năng không gian làm việc pnpm bị lỗi và một số lỗi vẫn chưa được khắc phục trong nhiều năm.


  • cả pnpmsợi đều yêu cầu thiết lập bổ sung trong đường ống CI, trong khi npm thì không.


  • cả pnpmsợi đều không lưu trữ thông tin đăng ký gói trong tệp khóa của chúng, trong khi npm thì có.

Suy nghĩ của tác giả

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ì:


  • nó ổn định (đặc biệt là không gian làm việc),


  • đi kèm với Node.js và không yêu cầu thiết lập bổ sung trong quy trình CI,


  • lưu trữ các cơ quan đăng ký gói trong 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! 👇 😊