logo

Đang load dữ liệu

logo devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER

Đào tạo - Phần mềm - Cho thuê nhân sự

  • 0969.609.003
  • 0978.611.889
  • Trang chủ
  • Các khoá đào tạo
    • Chuyên đề WEB - PHP

      • Lập trình web với HTML5 - CSS3- JQuery - Bootstrap - Ajax - [36 giờ]
      • Lập trình web frontend - reactjs - [75 giờ]
      • Lập trình web với mã nguồn mở PHP&MYSQL - PHP FRAMEWORK [126 giờ]

      Chuyên đề Mobile

      • Lập trình Games/Apps trên nền tảng Android - [120 giờ]
      • Lập trình Games/Apps trên nền tảng IOS - [120 giờ]

      Chuyên đề JAVA

      • Ngôn ngữ lập trình hướng đối tượng với java - [40 giờ]
      • Lập trình ứng dụng với java - [100 giờ]
      • Lập trình web site với java framework (JPA, HIBERNATE, SPRING MVC, SPRINGBOOT) - [276 giờ]

      Chuyên đề NETWORK/SECURITY

      • Khoá học Quản trị hạ tầng mạng CCNA v6 - [72 giờ]
      • Khoá học quản trị hệ thống với Windows SERVER 2012- [72 giờ]
      • Chuyên gia bảo mật hệ thống CompTIA + - [110 giờ]

      Chuyên đề .NET

      • Nền tảng lập trình hướng đối tượng với C# - [40 giờ]
      • Lập trình ứng dụng WINDOWS FORM - [100 giờ]
      • Lập trình Web với ASP.NET MVC 5, WebAPI - [145 giờ]

      Chuyên đề khác

      • Ngôn ngũ lập trình C/C++ - [80 giờ]
  • Lập trình cho trẻ em
  • Dịch vụ
    • Đào tạo theo như cầu
    • Cung cấp thiết bị - Phần mềm
    • Tư vấn - Thiết kế mạng hạ tầng
    • Tư vấn - Triển khai dịch vụ mạng
    • Tư vấn - Tư vấn, triển khai giám sát hệ thống
    • Thực tập dự án
  • Lịch khai giảng
  • Tin tức
    • Tin tức và sự kiện
    • Tin hoạt động
    • Tin công nghệ
    • Hội thảo, workshop, Codecam
    • Thông tin việc làm
    • Cẩm nang chia sẻ kiến thức
  • Tiện ích
  • Liên hệ

Tin công nghệ

Aug - 2019

07

Package-lock.json và những điều có thể bạn chưa biết

Tin công nghệ

 

Giới thiệu

Với những lập trình viên nodejs nói riêng cũng như các lập trình viên web nói chung hẳn không còn lạ gì khi thấy trong một project tồn tại một file tên là package.json. Okay, có thể nói đơn giản thì package.json là một file chứa thông tin giúp bạn biết được để vận hành được project cần đến những modules nào. Có thể coi những modules chính là sức mạnh của nodejs với một bộ mã nguồn mở khổng lồ cũng như cộng đồng lớn mạnh đến nỗi cứ vài phút lại có một module mới. Wait, thế còn package-lock.json thì sao ? Bài viết này mình sẽ chia sẻ những kiến thức nhỏ bé của mình về cái file mà mình tưởng chừng như vô dụng này =)) . Bài viết mình tham khảo chính được viết trên medium với 9.4k claps, các bạn có thể tham khảo tại đây: Everything You Wanted To Know About package-lock.json But Were Too Afraid To Ask

Tóm lược

Những phần chính để mọi người có thể overview qua về package-lock.json :

  • package-lock.json sẽ tự động được tạo khi bạn sử dụng npm từ bản ^5.x.x
  • Nên giữ lại file package-lock.json để đảm bảo tính tương thích giữa các dependencies
  • Nên COMMIT package-lock.json vào hệ thống quản lý code mà bạn sử dụng (Git, SVN,…)
  • Không được xóa package-lock.json chỉ để chạy npm install và generate lại nó
  • Từ phiên bản ^5.1.x, package.json có quyền hạn cao hơn package-lock.json (source of truth)

Kiến thức nên tảng

Semantic Versioning (semver)

Các bạn có thể tạm hiểu đây chính là tập hợp các luật để quy định về cách đánh version cho một modules. Các bạn vẫn khai báo những dependencies theo cách này :

Các bạn có thể thấy rõ rằng mỗi module đều được mô tả phiên bản dưới dạng X.Y.Z, hay chính xác hơn là MAJOR.MINOR.PATCH .Các bạn có thể đọc thêm chi tiết về phần này tại đây : https://semver.org/. Trong khuôn khổ bài viết mình chỉ giải thích cơ bản để các bạn có thể hiểu về 3 chỉ số này có ý nghĩa gì với các module:

  • MAJOR : Thay đổi (hay còn gọi là breaking changes) khi những API cũ không còn tương thích nữa . VD : gọi là 2.0.0 khi các api từ bản 1.0.0 không còn dùng được nữa.
  • MINOR: Thay đổi khi thêm những tính năng mới tuy nhiên những API từ phiên phản trước đó vẫn có thể dùng trong phiên bản này. VD: Phiên bản 1.1.0 thêm một số tính năng tuy nhiên những API từ phiên bản 1.0.0 vẫn được giữ nguyên
  • PATCH: Phiên bản thay đổi khi có những fix bug cho những phiên bản trước đó và API hoàn toàn vẫn tương thích với các phiên bản cũ.

Quản lý các package

Các dev hẳn sẽ không lạ lẫm gì với trình quản lý các modules npm . Nhờ có npm việc quản lý các dependencies cho project dễ dàng hơn rất nhiều. Thử tưởng tượng một dự án của bạn có thể chứa đến hàng trăm các dependencies, trong những dependencies đó lại chứa tiếp các dependencies khác => dependencies hell => khá đau đầu. Nhưng nhờ có các trình quản lý các gói module như npm thì chúng ta sẽ chỉ phải quẳng gánh lo đi mà sống: khai báo các dependencies vào package.json và npm install

Có một điều cần note lại khi install các package có kí hiệu ^ thì trình quản lý dependencies sẽ tự động install phiên bản mới nhất cùng MAJOR version. VD với

<span class="token property">"redux-thunk"</span><span class="token operator">:</span> <span class="token string">"^2.3.0"</span>

npm sẽ tự động tải xuống phiên bản 2.3.0 hoặc những phiên bản nâng cấp thay đổi MINOR hoặc PATCH

Chia sẻ mã nguồn

Các mã nguồn chia sẻ trên nền tảng github (đặc biệt là các javascript project) các bạn có thể thấy thường có 1 file package.json để định nghĩa những dependencies cần thiết để có thể run được thành công project. Lý thuyết là vậy nhưng vẫn có những trường hợp ngoại lệ, dưới đây chính là một trong những trường hợp có thể xảy ra:

Trong project có định nghĩa một dependencies trong file package.json như sau :

<span class="token property">"redux-thunk"</span><span class="token operator">:</span> <span class="token string">"^2.3.0"</span>
 
 

Như giải thích ở trên, với tiền tố ^ , npm sẽ tự động install phiên bản mới nhất miễn là nó cùng MAJOR version. Một kịch bản có thể xảy ra ở đây là : Owner của dự án đặt version của gói redux-thunk như trên, tuy nhiên khi bạn clone về và chạy npm installthì gói redux-thunk mới được cập nhật một bản vá và hiện tại đang ở 2.3.1 . Tất nhiên là ở phiên bản clone của bạn npm sẽ tự động tải xuống phiên bản mới nhất. Và biết sao được, chẳng may với bản và này lại gây xung đột với những chức năng đang sử dụng, và khi đó kết quả chạy của 2 phiên bản 2.3.1 và 2.3.0 sẽ khác nhau

package-lock

Mục đích

Mục đích của package-lock.json chính là việc ngăn chặn những tính huống được mô tả phía trên : Cài đặt các dependencies từ cùng một file package.json nhưng lại dẫn đến 2 phiên bản cài đặt khác nhau

Định dạng

Mở package-lock.json lên các bạn có thể thấy nó có vẻ gì đó rất giống package.json nhưng dài dòng hơn nhiều. Dưới đây là một list các dependencies của express:

<span class="token property">"express"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token property">"version"</span><span class="token operator">:</span> <span class="token string">"4.15.4"</span><span class="token punctuation">,</span>
      <span class="token property">"resolved"</span><span class="token operator">:</span> <span class="token string">"https://registry.npmjs.org/express/-/express-4.15.4.tgz"</span><span class="token punctuation">,</span>
      <span class="token property">"integrity"</span><span class="token operator">:</span> <span class="token string">"sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE="</span><span class="token punctuation">,</span>
      <span class="token property">"requires"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">"accepts"</span><span class="token operator">:</span> <span class="token string">"1.3.3"</span><span class="token punctuation">,</span>
        <span class="token property">"array-flatten"</span><span class="token operator">:</span> <span class="token string">"1.1.1"</span><span class="token punctuation">,</span>
        <span class="token property">"content-disposition"</span><span class="token operator">:</span> <span class="token string">"0.5.2"</span><span class="token punctuation">,</span>
        <span class="token property">"content-type"</span><span class="token operator">:</span> <span class="token string">"1.0.2"</span><span class="token punctuation">,</span>
        <span class="token property">"cookie"</span><span class="token operator">:</span> <span class="token string">"0.3.1"</span><span class="token punctuation">,</span>
        <span class="token property">"cookie-signature"</span><span class="token operator">:</span> <span class="token string">"1.0.6"</span><span class="token punctuation">,</span>
        <span class="token property">"debug"</span><span class="token operator">:</span> <span class="token string">"2.6.8"</span><span class="token punctuation">,</span>
        <span class="token property">"depd"</span><span class="token operator">:</span> <span class="token string">"1.1.1"</span><span class="token punctuation">,</span>
        <span class="token property">"encodeurl"</span><span class="token operator">:</span> <span class="token string">"1.0.1"</span><span class="token punctuation">,</span>
        <span class="token property">"escape-html"</span><span class="token operator">:</span> <span class="token string">"1.0.3"</span><span class="token punctuation">,</span>
        <span class="token property">"etag"</span><span class="token operator">:</span> <span class="token string">"1.8.0"</span><span class="token punctuation">,</span>
        <span class="token property">"finalhandler"</span><span class="token operator">:</span> <span class="token string">"1.0.4"</span><span class="token punctuation">,</span>
        <span class="token property">"fresh"</span><span class="token operator">:</span> <span class="token string">"0.5.0"</span><span class="token punctuation">,</span>
        <span class="token property">"merge-descriptors"</span><span class="token operator">:</span> <span class="token string">"1.0.1"</span><span class="token punctuation">,</span>
        <span class="token property">"methods"</span><span class="token operator">:</span> <span class="token string">"1.1.2"</span><span class="token punctuation">,</span>
        <span class="token property">"on-finished"</span><span class="token operator">:</span> <span class="token string">"2.3.0"</span><span class="token punctuation">,</span>
        <span class="token property">"parseurl"</span><span class="token operator">:</span> <span class="token string">"1.3.1"</span><span class="token punctuation">,</span>
        <span class="token property">"path-to-regexp"</span><span class="token operator">:</span> <span class="token string">"0.1.7"</span><span class="token punctuation">,</span>
        <span class="token property">"proxy-addr"</span><span class="token operator">:</span> <span class="token string">"1.1.5"</span><span class="token punctuation">,</span>
        <span class="token property">"qs"</span><span class="token operator">:</span> <span class="token string">"6.5.0"</span><span class="token punctuation">,</span>
        <span class="token property">"range-parser"</span><span class="token operator">:</span> <span class="token string">"1.2.0"</span><span class="token punctuation">,</span>
        <span class="token property">"send"</span><span class="token operator">:</span> <span class="token string">"0.15.4"</span><span class="token punctuation">,</span>
        <span class="token property">"serve-static"</span><span class="token operator">:</span> <span class="token string">"1.12.4"</span><span class="token punctuation">,</span>
        <span class="token property">"setprototypeof"</span><span class="token operator">:</span> <span class="token string">"1.0.3"</span><span class="token punctuation">,</span>
        <span class="token property">"statuses"</span><span class="token operator">:</span> <span class="token string">"1.3.1"</span><span class="token punctuation">,</span>
        <span class="token property">"type-is"</span><span class="token operator">:</span> <span class="token string">"1.6.15"</span><span class="token punctuation">,</span>
        <span class="token property">"utils-merge"</span><span class="token operator">:</span> <span class="token string">"1.0.0"</span><span class="token punctuation">,</span>
        <span class="token property">"vary"</span><span class="token operator">:</span> <span class="token string">"1.1.1"</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>

Ý tưởng ở đây là sẽ sử dụng package-lock.json thay vì package.json để cài đặt các modules do package-lock.json đã chỉ định rõ phiên bản, location, mã băm toàn vẹn integrity cho mỗi module và từng dependencies của nó => Cài đặt của nó tạo ra sẽ luôn giống nhau cho dù bạn cài đặt vào lúc nào.

Bàn luận

Từ những ý trên có thể thấy package-lock.json được cho là có thể giải quyết các vấn đề phổ biến tuy nhiên những tìm kiếm hàng đầu trên Google lại thường hỏi cách disabled nó cũng như hỏi về tác dụng của nó.

Trước phiên bản npm 5.x.x, package.json được coi là một “source of truth” cho dự án. Tất cả những gì được định nghĩa trong package.json sẽ được tự động install. Các dev tỏ ra khá hưởng ứng với mô hình này . Tuy nhiên khi package-lock.json được giới thiệu thì nó lại không hoạt động như sự kì vọng của nhiều người. Sự thay đổi trong package.json không được phản ánh trong package-lock.json. Trong 2 trường hợp dưới đây sẽ thể hiện rõ lí do khiến package-lock.json đã làm cho người dùng có chút thất vọng:

Trường hợp 1: Gói A có phiên bản 1.0.0 trong package.json và package-lock.json, tuy nhiên trong package.json được chỉnh sửa thủ công lại thành phiên bản 1.1.0, khi đó nếu người dùng vẫn tin tưởng package.json là “source of truth” thì họ sẽ hi vọng phiên bản 1.1.0 được install tuy nhiên sự thật thì phiên bản 1.0.0 mới là thứ được instaall

Trường hợp 2 : Một module không tồn tại trong package-lock.json, nhưng nó tồn tại trong package.json. Là một người dùng xem package.json là “source of truth”, mong muốn module sẽ được cài đặt. Tuy nhiên, do module không có trong package-lock.json, nó không được cài đặt và code bị lỗi vì không thể tìm thấy module.

Do đó, những người sử dụng không hiểu tại sao những dependencies của mình không được cài đặt chính xác và do đó họ tìm cách xóa package-lock.json rồi cài đặt lại hoặc tìm cách disabled nó.

Tuy nhiên trong PR #17508, các maintainers của Npm đã thêm một thay đổi khiến cho package.json ghi đè package-lock.json nếu package.json đã được cập nhật. Bây giờ trong cả hai trường hợp trên, các gói mà người dùng mong đợi được cài đặt sẽ được cài đặt chính xác.

Kết luận

Trên đây là những kiến thức mình đã tham khảo cũng như tìm hiểu về những thứ vẫn thường được dùng nhưng lại khá ít người biết tại sao lại dùng chúng. Trong bài này mình chủ yếu nói về trình quản lý gói npm, tuy nhiên về các ý tưởng hay concepts nó cũng khá tương đồng với các trình quản lý gói khác như yarn, gem, … Hi vọng bài viết có thể giúp ích cho các bạn.

Nguồn: Devmaster Academy via Viblo


 

Các bài viết cùng chủ đề

Việt Nam khả năng thiếu 150.000 đến 200.000 nhân sự IT mỗi năm
Việt Nam khả năng thiếu 150.000 đến 200.000 nhân s...
Tổng quan ngành khoa học máy tính
Tổng quan ngành khoa học máy tính
8 xu thế công nghệ đáng chú ý nhất trong năm 2021
8 xu thế công nghệ đáng chú ý nhất trong năm 2021...
Tìm hiểu về API? Tại sao API lại được trọng dụng!
Tìm hiểu về API? Tại sao API lại được trọng dụng!...
Học ngôn ngữ lập trình nào để bắt kịp xu thế công nghệ năm 2021
Học ngôn ngữ lập trình nào để bắt kịp xu thế công ...
Nên làm việc ở công ty Product hay công ty Outsourcing?
Nên làm việc ở công ty Product hay công ty Outsour...

Các khóa đào tạo chuyên đề

Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Lập trình ứng dụng trên nền tảng android Lập trình ứng dụng trên nền tảng android
Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack

Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
Lập trình ứng dụng với WINDOWS FORM Lập trình ứng dụng với WINDOWS FORM
Lập trình ứng dụng với JAVA (FORM) Lập trình ứng dụng với JAVA (FORM)
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
Lập trình frontend với reacjs (Full) Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

DEVMASTER ACADEMY

Địa chỉ: Tầng 6 - Tòa nhà VIỆN CÔNG NGHỆ
Số 25, Vũ Ngọc Phan - Láng Hạ - Đống Đa - Hà Nội

Hotline: 0969 609 003 | 0978 611 889

devmaster.contact@gmail.com

hna.tvchung@gmail.com

CÁC KHÓA HỌC CHUYÊN ĐỀ

  • Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
  • Lập trình ứng dụng trên nền tảng android
  • Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
  • Lập trình ứng dụng với WINDOWS FORM
  • Lập trình ứng dụng với JAVA (FORM)
  • Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
  • Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
  • Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER - Học thực tế * Làm thực tế * Cam kết việc làm
Copyright by Ⓒ DEVMASTER 2015