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

Những mẩu tin ngắn hàng ngày dành cho bạn
  • smee.io là một cách đơn giản để tạo một địa chỉ webhook và ánh xạ nó về địa chỉ localhost trong máy tính của bạn.

    $ npm install --global smee-client $ smee -u https://smee.io/eu4UoW8vrKSZtTB

    » Xem thêm
  • javascript.tm được Ryan Dahl - cha đẻ của Node.js tạo ra với mục tiêu trình bày và kêu gọi cộng đồng ủng hộ việc Oracle "giải phóng" cái tên JavaScript, trả lại nó cho cộng đồng.

    Anh cho rằng Oracle sau nhiều thương vụ mua bán đã gián tiếp sở hữu cái tên JavaScript, nhưng họ lại không sử dụng cái tên này. Một điều nữa là JavaScript đã trở thành tên gọi chung, cộng đồng sử dụng rất nhiều mà ít ai biết rằng nó thuộc về Oracle.

    Việc Oracle nắm giữ thương hiệu này gây ra sự nhầm lẫn không cần thiết. Anh kêu gọi Oracle từ bỏ quyền sở hữu, trả nó về với cộng đồng. Nếu được như vậy, nhiều hiểu lầm được xoá bỏ và mọi người sẽ có nhiều quyền hạn với cái tên này. Ví dụ, chúng ta sẽ có một "Hội nghị về JavaScript" trong tương lai mà không phải lo lắng về vấn đề pháp lý.

    Thông tin mới nhất, Vào ngày 22 tháng 11 năm 2024: Anh đã nộp đơn lên USPTO. Chúng ta cùng chờ xem kết quả ra sao nhé! Ngoài ra bạn cũng có thể bày tỏ sự ủng hộ bằng cách truy cập vào địa chỉ ở trên và tiến hành "ký" vào lá đơn 😇

    » Xem thêm
  • Nhớ mấy ngày đầu đi phỏng vấn, có một câu hỏi là JavaScript có phải là Java không? Thì mình trả lời ngay là có 😆. Buồn cười thật, vì đúng ra JavaScript và Java là hai ngôn ngữ khác nhau hoàn toàn.

    Sự nhầm lẫn này mà mới đây đã dẫn đến vụ kiện đòi Oracle trả lại cái tên JavaScript cho cộng đồng. Oracle? Đúng vậy, cái tên liên quan rất mật thiết đến Java, nhưng tại sao lại kiện họ với JavaScript cơ chứ?

    Hic, hôm nay làm việc mệt mỏi quá nên xin phép ngày mai mình kể chi tiết hơn nha vì câu chuyện khá dài đấy 😅

    » Xem thêm

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.

Cao cấp
Hello

Tôi & khao khát "chơi chữ"

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

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

Bình luận (0)

Nội dung bình luận...