Câu hỏi Sự khác biệt giữa dấu ngã (~) và dấu mũ (^) trong package.json là gì?


Sau khi tôi nâng cấp lên bản ổn định mới nhất node và npm, Tôi đã thử npm install moment --save. Nó lưu mục nhập trong package.json với caret(^) tiếp đầu ngữ. Trước đây, đó là một tilde(~) tiếp đầu ngữ.

  1. Tại sao những thay đổi này được thực hiện trong npm?
  2. Sự khác biệt giữa tilde(~) và caret(^)?
  3. Những lợi thế hơn những người khác là gì?

2249
2018-03-12 06:02


gốc


FYI bạn có thể ngăn chặn tiền tố hoặc sử dụng một tiền tố tùy chỉnh bằng cách thực hiện: npm config set save-prefix=''. (Gậy ~ trong báo giá nếu đó là những gì bạn thích.) Cá nhân tôi làm điều này và thu nhỏ cho những thứ trong sản xuất. - fncomp
Tất cả các chi tiết gritty nitty làm thế nào tilde và caret làm việc và sự khác biệt: github.com/npm/node-semver#tilde-ranges-123-12-1 - Jeffrey Martinez
Công cụ này là một trợ giúp tuyệt vời để kiểm tra semver.npmjs.com - chaiyachaiya
@ fncomp chỉ muốn làm rõ nếu tôi nhận được bình luận của bạn đúng .. bạn chỉ sử dụng phiên bản cụ thể của phụ thuộc trong dự án của bạn? nhóm của chúng tôi là do dự của nâng cấp phụ thuộc .. bạn sẽ khuyên bạn nên sử dụng các phiên bản cụ thể hoặc tiền tố '~' cho các phụ thuộc ..? - blogs4t
@fncomp bạn có thể vui lòng chi tiết những gì bạn có nghĩa là bằng cách nói "Cá nhân tôi làm điều này và shrinkwrap cho những thứ trong sản xuất". cảm ơn! - blogs4t


Các câu trả lời:


Theo thuật ngữ đơn giản nhất, dấu ngã khớp với phiên bản phụ gần đây nhất   (số giữa). ~ 1.2.3 sẽ khớp với tất cả các phiên bản 1.2.x nhưng sẽ   bỏ lỡ 1.3.0.

Mặt khác, caret lại thoải mái hơn. Nó sẽ cập nhật cho bạn   phiên bản chính mới nhất (số đầu tiên). ^ 1.2.3 sẽ khớp   bất kỳ phiên bản 1.x.x nào bao gồm 1.3.0, nhưng sẽ giữ trên 2.0.0.

http://fredkschott.com/post/2014/02/npm-no-longer-defaults-to-tildes/


2640
2018-03-12 08:28



Đăng ở đây để hy vọng bắt những người không hoàn toàn nghĩ rằng điều này thông qua, nhưng cả hai ^ và ~ giả định bạn có thể tin tưởng phát hành nhỏ và điểm từ phụ thuộc của bạn. Nếu bạn đang xuất bản một thư viện và muốn người khác tin tưởng bạn, KHÔNG CHẤP NHẬN CHẤP NHẬN CÁC PHỤ LỤC XUỐNG. Một dấu chấm phát hành xấu từ sự phụ thuộc của bạn có thể gây ra một phản ứng dây chuyền ngược dòng, và sẽ có người gõ cửa CỦA BẠN khi mọi thứ đi hình quả lê. Đây là một lý do rất lớn để sử dụng npm shrinkwrap trên mã sản xuất của bạn. - tehfoo
Điều này gây hiểu lầm cho ^. Nó nói rằng ^  sẽ cập nhật cho bạn gần đây nhất chính phiên bản, khi trong thực tế nó cập nhật cho bạn gần đây nhất diễn viên phụ phiên bản. tức là: - ^ 1.2.3: => = 1.2.3 <2.0.0 - ^ 0.2.3: => = 0.2.3 <0.3.0 - ^ 0.0.3: => = 0.0.3 <0.0.4 - prasanthv
@jgillich trong semver khi bạn sử dụng 0.2.x, 2 không phải là major version. Đó là lý do docs.npmjs.com sử dụng các từ cụ thể: the left-most non-zero digit. Còn về trường hợp này: ^ 0.0.4 có nghĩa là 0.0.4 - rofrol
@FagnerBrack: Ví dụ cụ thể mà bạn cung cấp là chính xác, nhưng nhìn chung cách suy nghĩ của bạn là sai. Ví dụ: giả sử bạn có gói A trong 3 phiên bản: 0.0.1, 0.0.2 và 0.0.3. Có một lỗi trong 0.0.1 vì vậy bạn muốn có ít nhất 0.0.2 trong gói của bạn B. Nếu bạn viết 0.0.x bạn sẽ nhận được 0.0.3, đó là OK. Nhưng nếu một số gói khác C yêu cầu cả hai B và A và bổ sung có hạn chế "A": "<0.0.2" bạn sẽ nhận được 0.0.1 mà không hiển thị bất kỳ vấn đề xung đột nào, đó không phải là điều bạn muốn. Sử dụng dấu ngã ~0.0.2 sẽ giúp bạn tránh được vấn đề này. - Maciej Sz
Lạ lùng rằng câu trả lời không chính xác này It will update you to the most recent major version có 2k + upvotes. Tôi tự hỏi có bao nhiêu người ngoài kia nghĩ rằng ^ cập nhật phiên bản chính !! Không có sự mơ hồ xung quanh những gì lớn / nhỏ / vá có nghĩa là trong phiên bản semserv - nó chỉ đơn giản là sai - Drenai


Tôi muốn thêm tài liệu chính thức của npmjs cũng như mô tả tất cả các phương pháp cho tính đặc hiệu của phiên bản bao gồm cả các phương pháp được đề cập trong câu hỏi -

https://docs.npmjs.com/files/package.json

https://docs.npmjs.com/misc/semver#x-ranges-12x-1x-12-

  • ~version "Tương đương với phiên bản" Xem npm semver - Tilde Ranges & semver (7)
  • ^version "Tương thích với phiên bản" Xem npm semver - Caret Ranges & semver (7)
  • version Phải khớp chính xác phiên bản
  • >version Phải lớn hơn phiên bản
  • >=version v.v.
  • <version
  • <=version
  • 1.2.x 1.2.0, 1.2.1, v.v., nhưng không phải 1.3.0
  • http://sometarballurl (đây có thể là URL của một tarball sẽ được tải xuống và cài đặt cục bộ
  • * Phù hợp với bất kỳ phiên bản nào
  • latest Nhận bản phát hành mới nhất

Danh sách trên không toàn diện. Các thông số phiên bản khác bao gồm các url GitHub và các gói và gói cục bộ của người dùng GitHub, với các thẻ npm cụ thể


571
2017-09-16 06:25



Cũng có thể chỉ định một loạt các phiên bản chính xác, như 1.2.0 || >=1.2.2 <1.3.0: Chính xác 1.2.0 hoặc mọi thứ từ 1.2.2 đến 1.3.0 (bao gồm), nhưng không phải 1.2.1 hoặc 1.3.1 trở lên và cũng không phải 1.1.x trở xuống. - CoDEmanX
@CoDEmanX tại sao lại bao gồm 1.3.0 nếu bạn sử dụng <? - Janus Troelsen
Tệ của tôi, nó được cho là đã đọc <=1.3.0. - CoDEmanX
Có phải 1.x.x có thể không? - Venryx
@Venryx có nó được. Đây sẽ là tất cả phiên bản> = 1.0.0 và <2.0.0 - Ahmad


Npm cho phép cài đặt phiên bản mới hơn của gói hơn gói được chỉ định. Sử dụng dấu ngã (~) cung cấp cho bạn phiên bản sửa lỗi và dấu sót (^) cũng cung cấp cho bạn chức năng mới tương thích ngược.

Vấn đề là các phiên bản cũ thường không nhận được bản sửa lỗi nhiều, vì vậy npm sử dụng dấu mũ (^) làm mặc định cho --save.

semver table

Theo: "Semver giải thích - tại sao có một dấu mũ (^) trong package.json của tôi?".

chú thích rằng các quy tắc áp dụng cho các phiên bản trên 1.0.0 và không phải mọi dự án đều tuân theo phiên bản ngữ nghĩa. Đối với phiên bản 0.x.x, dấu mũ chỉ cho phép  cập nhật, tức là nó hoạt động giống như dấu ngã. Xem "Caret Ranges"

Dưới đây là giải thích trực quan về các khái niệm:

semver diagram

Nguồn: "Bảng tính phiên bản ngữ nghĩa".


349
2017-07-30 20:40



Điều gì về ^ 0.2.5? từ docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4: Phạm vi Caret ^ 1.2.3 ^ 0.2.5 ^ 0.0.4. Cho phép các thay đổi không sửa đổi chữ số không phải không phải là số 0 bên trái trong tuple [major, minor, patch]. Nói cách khác, điều này cho phép cập nhật bản vá và cập nhật nhỏ cho phiên bản 1.0.0 trở lên, cập nhật bản vá cho các phiên bản 0.X> = 0.1.0 và không cập nhật phiên bản 0.0.X. - rofrol
@rofrol bất kỳ phiên bản nào trước 1.0.0 được coi là không ổn định và các quy tắc này không áp dụng - pspi
Vì vậy, lời giải thích của bạn chưa hoàn tất - rofrol
@rofrol yeah, bỏ qua cho dễ đọc là tốt đôi khi, cơ hội có bất cứ điều gì dưới đây 1.0.0 cho một phụ thuộc trong gói json là khá thấp. xem thêm nguyên tắc 20/80, là một quy tắc tuyệt vời để tập trung vào những gì quan trọng - pspi
Xem câu trả lời của tôi. Bạn nghĩ sao? stackoverflow.com/questions/22343224/… - rofrol


~ sửa các số lớn và nhỏ. Nó được sử dụng khi bạn đã sẵn sàng chấp nhận sửa lỗi trong sự phụ thuộc của bạn, nhưng không muốn bất kỳ thay đổi có khả năng không tương thích nào.

^ chỉ sửa số chính. Nó được sử dụng khi bạn đang theo dõi chặt chẽ các phụ thuộc của bạn và sẵn sàng thay đổi nhanh mã của bạn nếu phát hành nhỏ sẽ không tương thích.

Thêm vào đó, ^ Là không được hỗ trợ bằng các phiên bản npm cũ và nên được sử dụng thận trọng.

Vì thế, ^ là một mặc định tốt, nhưng nó không hoàn hảo. Tôi đề nghị chọn cẩn thận và định cấu hình toán tử semver hữu ích nhất cho bạn.


74
2018-03-12 23:05



không đúng: Phạm vi Caret ^ 1.2.3 ^ 0.2.5 ^ 0.0.4. Cho phép các thay đổi không sửa đổi chữ số không phải không phải là số 0 bên trái trong tuple [major, minor, patch]. Nói cách khác, điều này cho phép cập nhật bản vá và cập nhật nhỏ cho phiên bản 1.0.0 trở lên, cập nhật bản vá cho các phiên bản 0.X> = 0.1.0 và không cập nhật phiên bản 0.0.X. docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4 - rofrol
Câu trả lời này hoàn toàn sai (như nhiều người khác ở đây). Không ai trong số này sửa chữa một số lượng lớn! Như @rofrol đã nói, ^ chỉ đơn giản là giữ nguyên chữ số không phải bằng không nhất. ~ mặt khác chỉ cho phép cập nhật bản vá nếu phiên bản phụ được chỉ định (ví dụ: ~ 1.2.3 hoặc ~ 1.2) và cho phép cập nhật nhỏ nếu phiên bản phụ không được chỉ định (ví dụ: ~ 1). - TheBaj
@ TheBaj Họ có nghĩa là "sửa chữa" là "xác định" ("sửa lỗi") thay vì "điều chỉnh", vì vậy tất cả các bạn đồng ý về cách số lượng lớn được xử lý. - maaartinus


Semver

<major>.<minor>.<patch>-beta.<beta> == 1.2.3-beta.2
  • Sử dụng npm semver máy tính để thử nghiệm. (Mặc dù các giải thích cho ^ (bao gồm mọi thứ lớn hơn một phiên bản cụ thể trong cùng phạm vi chính) và ~ (bao gồm mọi thứ lớn hơn một phiên bản cụ thể trong cùng phạm vi nhỏ) không đúng 100%, máy tính có vẻ hoạt động tốt )
  • Cách khác, sử dụng Kiểm tra SemVer thay vào đó, không yêu cầu bạn chọn một gói và cũng cung cấp giải thích.

Cho phép hoặc không cho phép thay đổi

  • Phiên bản pin: 1.2.3.
  • Sử dụng ^ (như đầu). Cho phép cập nhật ở cấp độ khác thứ hai từ bên trái: ^0.2.3 có nghĩa 0.2.3 <= v < 0.3.
  • Sử dụng ~ (như đuôi). Thường đóng băng mức cao nhất hoặc đặt 0 nếu bỏ qua:
    • ~1 có nghĩa 1.0.0 <= v < 2.0.0
    • ~1.2 có nghĩa 1.2.0 <= v < 1.3.0.
    • ~1.2.4 có nghĩa 1.2.4 <= v < 1.3.0.
  • Cấp độ ngoài cùng bên phải: 0.2 có nghĩa 0.2 <= v < 1. Khác với ~ bởi vì:
    • Bắt đầu phiên bản cấp bị bỏ qua luôn là 0
    • Bạn có thể thiết lập bắt đầu phiên bản chính mà không chỉ định các sublevels.

Tất cả (hy vọng) khả năng

Đặt bắt đầu ở cấp độ chính và cho phép cập nhật trở lên

*  or "" (empty string)   any version
1                         v >= 1

Đóng băng cấp chính

~0 (0)            0.0 <= v < 1
0.2               0.2 <= v < 1          // Can't do that with ^ or ~ 
~1 (1, ^1)        1 <= v < 2
^1.2              1.2 <= v < 2
^1.2.3            1.2.3 <= v < 2
^1.2.3-beta.4     1.2.3-beta.4 <= v < 2

Cố định cấp độ nhỏ

^0.0 (0.0)        0 <= v < 0.1
~0.2              0.2 <= v < 0.3
~1.2              1.2 <= v < 1.3
~0.2.3 (^0.2.3)   0.2.3 <= v < 0.3
~1.2.3            1.2.3 <= v < 1.3

Freeze patch-level

~1.2.3-beta.4     1.2.3-beta.4 <= v < 1.2.4 (only beta or pr allowed)
^0.0.3-beta       0.0.3-beta.0 <= v < 0.0.4 or 0.0.3-pr.0 <= v < 0.0.4 (only beta or pr allowed)
^0.0.3-beta.4     0.0.3-beta.4 <= v < 0.0.4 or 0.0.3-pr.4 <= v < 0.0.4 (only beta or pr allowed)

Không cho phép cập nhật

1.2.3             1.2.3
^0.0.3 (0.0.3)    0.0.3

Để ý: Thiếu chính, nhỏ, vá hoặc chỉ định beta không có số, giống như any cho cấp độ còn thiếu.

Để ý: Khi bạn cài đặt một gói có 0 là cấp độ chính, bản cập nhật sẽ chỉ cài đặt phiên bản cấp độ beta / pr mới! Đó là bởi vì npm bộ ^ như mặc định trong package.json và khi phiên bản được cài đặt giống như 0.1.3, nó đóng băng tất cả các cấp độ chính / nhỏ / bản vá.


66
2017-10-11 16:52



Nói cho mọi người tránh bắt đầu các dự án từ 0 vì thư viện và các nhà phát triển tiêu thụ không hiểu hệ thống là một giải pháp khủng khiếp. Tôi nghĩ @asdfasdfads có thông tin tốt hơn nhiều. - ProLoser
@ProLoser Tôi chỉ nghĩ rằng hệ thống nên được đơn giản hóa và chúng tôi không nên sử dụng phiên bản 0.x. - rofrol
Các trường hợp sử dụng xung quanh phát triển vòng đời sớm và v0 làm cho rất nhiều ý nghĩa. Học cách v0 hành xử đúng cách đã thực sự khiến tôi mong đợi các dự án vòng đời sớm khác. Nó có nghĩa là bạn có thể có một API thay đổi nhanh chóng với nhiều khả năng tương thích ngược mà không bị buộc phải khai báo dự án của bạn là 1.x (aka: stable) khi nó thực sự không. - ProLoser
Tôi hiểu nó, nhưng tôi không thích cách nó hoạt động với semver và qualifiers - rofrol
Nó cảm thấy giống như một ý kiến ​​và không nên được đóng khung như một cách tiếp cận chung được chấp nhận. Và ^ 0.1.x được bản vá hoàn toàn tốt đẹp. - ProLoser


~ : Hợp lý gần đến

   ~1.1.5: 1.1.0 <= accepted < 1.2.0

^: Tương thích với

   ^1.1.5: 1.1.5 <= accepted < 2.0.0

   ^0.1.3: 0.1.3 <= accepted < 0.2.0

   ^0.0.4: 0.0.4 <= accepted < 0.1.0

42
2018-06-27 16:12



^0.1.3: 0.1.3 <= accepted < 1.0.0 thay vào đó, không? - kytwb
@kytwb - không. Trong trường hợp đặc biệt của số phiên bản zeroth-release, carat tương đương với dấu ngã. Như vậy ^0.1.3 chỉ chấp nhận các phiên bản 0.1.x và sẽ không chấp nhận 0.2.0, mặc dù đó là một sự gia tăng nhỏ. Hành vi này tương đương với ~0.1.3. Lý do đằng sau hành vi này là do thực tế là các gói giải phóng zeroth vẫn được coi là không ổn định; theo lời của semver.org, # 4, "mọi thứ có thể thay đổi bất kỳ lúc nào" (bao gồm các thay đổi không tương thích ngược). - chharvey


Kết hợp mũ có thể được coi là "bị hỏng" vì nó không cập nhật ^0.1.2 đến 0.2.0. Khi phần mềm đang nổi lên sử dụng 0.x.y các phiên bản và kết hợp mũ sẽ chỉ khớp với chữ số thay đổi cuối cùng (y). Điều này được thực hiện trên mục đích. Lý do là trong khi phần mềm đang phát triển các thay đổi API nhanh chóng: một ngày bạn có những phương pháp này và ngày kia bạn có những phương pháp đó và những cái cũ đã biến mất. Nếu bạn không muốn phá vỡ mã cho những người đã sử dụng thư viện của bạn, bạn hãy truy cập và tăng phiên bản chính: ví dụ: 1.0.0 -> 2.0.0 -> 3.0.0. Vì vậy, vào thời điểm phần mềm của bạn cuối cùng được thực hiện 100% và đầy đủ tính năng, nó sẽ giống như phiên bản 11.0.0 và điều đó không có ý nghĩa lắm, và thực sự có vẻ khó hiểu. Mặt khác, nếu bạn sử dụng 0.1.x -> 0.2.x -> 0.3.x phiên bản sau đó bởi thời gian phần mềm cuối cùng được thực hiện 100% và đầy đủ tính năng nó được phát hành dưới dạng phiên bản 1.0.0 và có nghĩa là "Bản phát hành này là bản dịch vụ dài hạn, bạn có thể tiếp tục và sử dụng phiên bản thư viện này trong mã sản xuất của mình và tác giả sẽ không thay đổi mọi thứ vào ngày mai hoặc tháng sau và sẽ không từ bỏ gói ".

Quy tắc là: sử dụng 0.x.y phiên bản khi phần mềm của bạn chưa trưởng thành và phát hành nó bằng cách tăng số giữa khi API công khai của bạn thay đổi (do đó mọi người có ^0.1.0 sẽ không nhận được 0.2.0 cập nhật và nó sẽ không phá vỡ mã của họ). Sau đó, khi phần mềm chín, hãy phát hành nó dưới 1.0.0 và tăng chữ số tận cùng bên trái mỗi khi API công khai của bạn thay đổi (do đó mọi người có ^1.0.0 sẽ không nhận được 2.0.0 cập nhật và nó sẽ không phá vỡ mã của họ).

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.

21
2017-10-19 11:24



Nhận xét này rất hữu ích và dường như không được ghi chép rất rõ. Bạn có liên kết đến tài liệu xung quanh hành vi này không? Câu trả lời này về các dự án v0 đã giúp tôi rất nhiều. - ProLoser
Tôi không có liên kết: Tôi cũng tìm thấy thông tin này bằng cách googling và chơi với máy tính phiên bản ngữ nghĩa npm semver.npmjs.com - asdfasdfads
Cần phải được thêm vào tài liệu của họ theo cách chính thức hơn. Tôi đã nói chuyện với Sony về đội ngũ kỹ thuật của tôi vì dường như rất dễ bị bỏ qua. slides.com/proloser/semver-v0 - ProLoser


^ là 1. [bất kỳ]. [bất kỳ] (phiên bản phụ mới nhất)
~ là 1.2 [bất kỳ] (bản vá mới nhất)

Đọc tuyệt vời là bài đăng trên blog này về cách semver áp dụng cho npm
và những gì họ đang làm để làm cho nó phù hợp tiêu chuẩn semver
http://blog.npmjs.org/post/98131109725/npm-2-0-0


20
2017-12-15 18:07



không đúng: Phạm vi Caret ^ 1.2.3 ^ 0.2.5 ^ 0.0.4. Cho phép các thay đổi không sửa đổi chữ số không phải không phải là số 0 bên trái trong tuple [major, minor, patch]. Nói cách khác, điều này cho phép cập nhật bản vá và cập nhật nhỏ cho phiên bản 1.0.0 trở lên, cập nhật bản vá cho các phiên bản 0.X> = 0.1.0 và không cập nhật phiên bản 0.0.X. docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4 - rofrol


Giải thích một lớp lót

Hệ thống phiên bản tiêu chuẩn là major.minor.build (ví dụ: 2.4.1)

npm kiểm tra và sửa phiên bản của một gói cụ thể dựa trên các ký tự này

~ : phiên bản chính là cố định, phiên bản nhỏ được cố định, khớp với bất kỳ số bản dựng nào

ví dụ. : ~ 2.4.1 có nghĩa là nó sẽ kiểm tra 2.4.x trong đó x là gì

^ : phiên bản chính được sửa, khớp với bất kỳ phiên bản phụ nào, khớp với bất kỳ số bản dựng nào

ví dụ. : ^ 2.4.1 có nghĩa là nó sẽ kiểm tra 2.x.x trong đó x là bất cứ điều gì


8
2018-01-21 08:00



Tôi thấy 7 dòng trong câu trả lời này - FluxLemur