Một vài lưu ý với package.json và package-lock.json để sử dụng npm hiệu quả hơn

  • 0

  • 0

  • 0

Một vài lưu ý với package.json và package-lock.json để sử dụng npm hiệu quả hơn

Một vài lưu ý với package.json và package-lock.json để sử dụng npm hiệu quả hơn

Vấn đề

npm là một kho quản lý package khổng lồ dành cho tất cả lập trình viên. Thông qua npm để chia sẻ, tải về và sử dụng các thư viện trong chính dự án của mình. Thậm là chí "mượn" npm để tạo các kho lưu trữ riêng tư lưu hành trong nội bộ.

Nhưng khi một dự án sử dụng quá nhiều phụ thuộc thì nó lại trở thành một cơn "ác mộng phụ thuộc". Bạn không chủ động quản lý được gói của người khác trên npm. Một ngày nào đó gói bạn đang sử dụng bị lỗi, bị xóa, bị hack… gây ra những mối nguy hiểm tiềm tàng cho dự án của chính bản thân.

Thực tế, tôi gặp nhiều vấn đề liên quan đến phiên bản của các gói phụ thuộc. Một trong những lý do thường thấy là mặc dù môi trường development và production sử dụng các gói giống nhau, nhưng vì một lý do nào đó mà một trong hai có vẻ không hoạt động giống nhau.

Nói thì có vẻ thâm sâu, nhưng việc đồng ý sử dụng package cũng có nghĩa là bạn chấp nhận một phần rủi ro. Những rủi ro đó hoàn toàn có thể hạn chế được phần nào nếu bạn đọc tiếp bài viết dưới đây.

Semver

Trước tiên, có thể nói bạn sẽ biết cách làm việc hiệu quả hơn với các package nếu biết đến semver. npm khuyến khích các package tuân thủ theo semver, nếu tuân thủ hoặc tuân thủ chặt chẽ nhiều phiền muộn sẽ tan biến.

Về cơ bản, semver đưa ra một cấu trúc phiên bản MAJOR.MINOR.PATCH, nó được gia tăng theo những quy tắc sau:

  • Số phiên bản MAJOR: khi bạn có những thay đổi API lớn, không tương thích với phiên bản trước.
  • Số phiên bản MINOR: khi bạn thêm chức năng tương thích ngược với phiên bản trước.
  • Số phiên bản PATCH: khi bạn làm một bản vá lỗi tương thích ngược với phiên bản trước.

Ví dụ một phiên bản semver hợp lệ là 1.0.0, 1.0.0-0…

npm tuân thủ semver đến mức nó có thể tự động nâng cấp phiên bản đến MINOR mỗi khi bạn dùng lệnh npm install. Bởi vì những bản nâng cấp ở mức PATCH hoặc MINOR có khả năng tương thích ngược. Chưa biết thay đổi là gì nhưng npm "nghĩ" rằng phiên bản mới "chắc chắn" đáng giá hơn bản cũ.

Đó là trên lý thuyết, thực tế đội ngũ nhà phát triển mới là người quyết định việc tuân thủ hay không. Dù vô tình hay cố ý không tuân thủ semver, package đó có thể phá hủy dự án của bạn. Tưởng tượng sẽ ra sao nếu họ phát hành một phiên bản PATCH nhưng lại xóa hoặc thay đổi một hàm không tương thích ngược trước đó.

package.json và package-lock.json

package.json là một file quan trọng trong dự án. Nó cung cấp nhiều thông tin cũng như chỉ dẫn dự án hoạt động. Một trong số đó là nó quản lý các gói phụ thuộc cùng phiên bản của chúng.

{
  "dependencies": {
    "dayjs": "^1.11.7"
  }
}

Tồn tại song song cùng package.jsonpackage-lock.json. Nếu không chịu khó tìm hiểu, nhiều người không biết mục đích thực sự của nó là gì. package-lock.json được sinh ra mỗi khi chạy npm install, nó lưu vết lại tất cả thông tin gói phụ thuộc tại thời điểm chạy install. Về mục đích tại sao phải sinh ra file lock, tôi xin phép trình bày trong mục npm ci phía dưới.

Một vài lưu ý sử dụng npm hiệu quả hơn

package version

Mỗi khi cần cài đặt một package, npm install <package> giúp bạn làm điều đó. Ngay cả khi muốn cài đặt lại tất cả gói phụ thuộc trong dự án, theo quán tính chúng ta dùng npm install.

Nhưng bạn có để ý hoặc thắc mắc tại sao mỗi lần chạy npm install thì package.json, package-lock.json bị thay đổi? Đó là vì npm install tự động nâng cấp phiên bản của package.

{
  "dependencies": {
    "dayjs": "^1.11.7"
  }
}

Mỗi khi bạn cài đặt package bằng npm install, nó xuất hiện dấu ^ trước phiên bản với ý nghĩa "được phép cập nhật" phiên bản của gói.

Ví dụ: ^1.2.3 được cập nhật lên phiên bản dưới 2.0.0-0, ^0.2.3 được cập nhật lên phiên bản dưới 0.3.0-0

Một dấu thường thấy nữa là ~, nó cũng cho phép npm cập nhật phiên bản.

Ví dụ: ~1.2.3 được cập nhật lên phiên bản dưới 1.3.0-0, ~0.2.3 được cập nhật lên phiên bản dưới 0.3.0-0

Có rất nhiều quy tắc, bạn đọc tìm hiểu thêm tại Advanced Range Syntax.

Nếu chấp nhận những thay đổi phiên bản khi install, có thể bạn không cần bận tâm điều gì. Còn nếu không, hãy xóa các dấu trước phiên bản để npm cài đặt chính xác từng phiên bản đó. Hoặc cài đặt gói cùng với cờ --save-exact:

$ npm install --save-exact dayjs

npm install --production

npm install cài đặt tất cả gói phụ thuộc có trong dependencies và cả devDependencies. Trong devDependencies chứa các gói chỉ cần thiết để phát triển và thử nghiệm cục bộ, ví dụ như các công cụ unittest hoặc linting. Những gói đó không nhất thiết phải được cài đặt trong môi trường production, vì thế bạn có thể loại bỏ chúng bằng cách chỉ cài đặt các gói có trong dependencies bằng cờ --production.

$ npm install --production

npm ci

npm ci tương tự như npm install, nó cũng cài đặt tất cả các gói phụ thuộc, nhưng là trong package-lock.json hoặc npm-shrinkwrap.json. Có vài lưu ý khi làm việc với package-lock.json, bạn đọc tìm hiểu thêm tại npm-ci Description. Một vài lưu ý đặc biệt là:

  • Nếu các gói phụ thuộc trong package-lock.json không khớp với các gói phụ thuộc trong package.json, npm ci sẽ báo lỗi.
  • Nó không bao giờ thay đổi package.json hoặc package-lock.json.

npm ci được khuyến khích dùng trong các môi trường tự động như nền tảng thử nghiệm, tích hợp liên tục và triển khai -- hoặc bất kỳ tình huống nào mà bạn muốn đảm bảo rằng bạn đang thực hiện cài đặt sạch các phụ thuộc của mình.

Kể cả trong production, bạn vẫn nên sử dụng npm ci để cài đặt chính xác phiên bản của các gói. Tránh trường hợp chạy trên development thì được nhưng lúc chạy trên production thì bị lỗi. Tương tự như npm install, sử dụng cờ --production để cài các gói trong dependencies.

$ npm ci --production

npm outdated

Nếu "fix cứng" phiên bản của các gói, làm cách nào để tôi biết gói nào có cập nhật? Đó chính là lúc npm outdated giúp bạn. Mỗi khi cần kiểm tra các bản cập nhật thì chạy nó. Câu lệnh cung cấp thông tin về phiên bản hiện tại, phiên bản MINOR tương thích ngược hoặc phiên bản nâng cấp MAJOR toàn diện.

npm outdated

Hãy thận trọng với các phiên bản MAJOR bởi vì nó thường mang những thay đổi rất lớn đến mức làm hỏng dự án hiện tại của bạn. Các bản cập nhật MINOR hoặc PATCH thường an toàn hơn. Tuy nhiên, tránh nâng cấp toàn bộ phiên bản của các gói cùng một lúc. Thay vào đó hãy nâng cấp từng gói một mà bạn cho là an toàn trước tiên, nếu có lỗi xảy ra thì dễ truy vết lại gói nào không tương thích để kịp thời hoàn tác.

npm audit

Quá nhiều package, mỗi package lại mang trong mình nhiều gói phụ thuộc khác, từ đó cơn "ác mộng phụ thuộc" ra đời. Một vấn đề liên quan đến nó chính là bảo mật. Sẽ ra sao nếu một package được rất nhiều package khác sử dụng dính lỗ hổng bảo mật? npm sớm quan tâm đến việc này, chính vì thế công cụ cung cấp một tính năng "quét" các lỗ hổng trong package và trong cả các dependencies của chúng.

$ npm audit

npm audit

Khi chạy npm audit, npm liệt kê ra tất cả các gói cùng dependencies của nó mà đang dính lỗi bảo mật. Thông tin in ra khá là rõ ràng, gồm có "Mức độ" nguy hiểm của mỗi, thông tin chi tiết (More info), cùng cách giải quyết (# Run … ) và một số thông tin khác.

Để khắc phục tất cả lỗ hổng, chúng ta chạy lệnh fix.

$ npm audit fix

Về cơ bản, npm audit fix chạy lệnh npm install <package> bên dưới. Nó giống như là câu lệnh trong # Run. Do đó, có những package phải thay đổi cả phiên bản MAJOR thì mới sửa được lỗi. Khi đó, npm audit fix không tùy tiện cập nhật phiên bản MAJOR gây nguy cơ hỏng cả dự án. Tuy nhiên, nếu biết bạn đang làm gì và bỏ qua cảnh báo thì bạn có thể sử dụng thêm cờ --force để chấp nhận bản sửa lỗi.

$ npm audit fix --force

Tổng kết

npm khuyến khích nhà phát triển đặt phiên bản cho các gói theo quy tắc semver. Có thể nói nhiều phiền muộn khi sử dụng npm cũng như các gói có trên đó bắt nguồn từ các phiên bản, "địa ngục phụ thuộc" cũng góp phần tạo nên sự phiền muộn đó. Hy vọng qua bài viết này cung cấp cho bạn đọc một góc nhìn về phiên bản gói cùng một vài phương pháp sử dụng npm để giải quyết phần nào vấn đề nêu ra.

Bạn thấy bài viết này có ích?
  • Không

  • Bình thường

Bình luận
DMCA.com Protection Status