В чем разница между тильдой (~) и кареткой (^) в package.json?

2686

После того, как я обновился до последних стабильных node и npm, я попробовал npm install moment --save. Он сохраняет запись в package.json с префиксом caret(^). Раньше это был префикс tilde(~).

  • Почему эти изменения сделаны в npm?
  • В чем разница между tilde(~) и caret(^)?
  • В чем преимущества над другими?
  • 28
    К вашему сведению, вы можете предотвратить префиксы или использовать пользовательские, выполнив: npm config set save-prefix='' . (Вставьте ~ в кавычки, если это то, что вы предпочитаете.) Я лично делаю это и упаковываю вещи в производство.
  • 15
    Все подробности о том, как работают тильда и карета, и различия: github.com/npm/node-semver#tilde-ranges-123-12-1
Показать ещё 5 комментариев
Теги:
npm

16 ответов

2944
Лучший ответ

Проще говоря, тильда соответствует последней младшей версии (среднему числу). ~ 1.2.3 будет соответствовать всем версиям 1.2.x, но будет отсутствовать 1.3.0.

Каретка, с другой стороны, более расслабленная. Он обновит вас до самой последней основной версии (первый номер). ^ 1.2.3 будет соответствовать любому выпуску 1.xx, включая 1.3.0, но будет удерживаться на 2.0.0.

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

Обратите внимание, что терминология автора несколько вводит в заблуждение: когда он говорит "самая последняя дополнительная версия", он означает "самая последняя версия патча в указанной дополнительной версии". Аналогично для ^, "самая последняя основная версия" следует читать как "самый последний младшую версию в указанной основной версии".

  • 236
    Публикация здесь, чтобы надеяться поймать людей, которые не совсем продумали это, но и ^, и ~ предполагают, что вы можете доверять второстепенным и точечным релизам из ваших зависимостей. Если вы публикуете библиотеку и хотите, чтобы другие люди доверяли вам, НЕ ПРИНИМАЙТЕ ВЗГЛЯД НА ЗАВИСИМОСТЬ DOWNSTREAM. Плохое снятие точки с вашей зависимости может вызвать цепную реакцию вверх по течению, и люди будут стучать в вашу дверь, когда все станет грушевидным. Это еще одна серьезная причина для использования npm shrinkwrap в вашем производственном коде.
  • 3
    Вы также можете просто покончить со всей ерундой npm, добавив свои версии с помощью ^ или ~ . Установите это, если вы хотите иметь жесткий контроль над вашими версиями: npm config set save-prefix=''
Показать ещё 19 комментариев
708

Я также хотел бы добавить официальную документацию по npmjs, в которой описаны все методы, относящиеся к конкретным версиям, включая методы, упомянутые в вопросе.

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

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

  • ~version "Приблизительно эквивалентна версии" См. раздел npm - Tilde Ranges & semver (7)
  • ^version "Совместимо с версией" См. npm semver - Caret Ranges & semver (7)
  • version должна точно соответствовать версии
  • >version должна быть больше версии
  • >=version т.д.
  • <version
  • <=version
  • 1.2.x 1.2.0, 1.2.1 и т.д., Но не 1.3.0
  • http://sometarballurl (это может быть URL тарбола, который будет загружен и установлен локально
  • * Соответствует любой версии
  • latest Получает последний выпуск

Приведенный выше список не является исчерпывающим. Другие спецификаторы версий включают в себя URL-адреса GitHub и репозитории пользователей GitHub, локальные пути и пакеты с конкретными тегами npm.

  • 7
    Также можно указать точный диапазон версий, например 1.2.0 || >=1.2.2 <1.3.0 : точно 1.2.0 или все от 1.2.2 до 1.3.0 (включительно), но не 1.2.1 или 1.3.1 и выше, а также не 1.1.x и ниже ,
  • 1
    @CoDEmanX почему 1.3.0 включен, если вы используете < ?
Показать ещё 4 комментария
399

Npm позволяет установить более новую версию пакета, чем указанная. Использование тильды (~) дает вам исправления ошибок, а символ вставки (^) также обеспечивает обратную совместимость новых функций.

Проблема в том, что старые версии обычно не получают исправлений ошибок, поэтому npm использует символ вставки (^) по умолчанию для --save.

Изображение 2098

Согласно: "Семвер объяснил - почему в моем package.json есть каретка (^)?" ,

Обратите внимание, что правила применяются к версиям выше 1.0.0, и не каждый проект следует семантическому версионированию. Для версий 0.xx каретка допускает только обновления патчей, то есть ведет себя так же, как тильда. Смотрите раздел "Кареты"

Вот наглядное объяснение понятий:

Изображение 2099

Источник: "Semantic Versioning Cheatsheet".

  • 1
    Как насчет ^ 0.2.5? из docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4 : диапазоны карет ^ 1.2.3 ^ 0.2.5 ^ 0.0.4. Позволяет вносить изменения, которые не изменяют крайнюю левую ненулевую цифру в кортеже [major, minor, patch]. Другими словами, это позволяет использовать исправления и незначительные обновления для версий 1.0.0 и выше, обновления исправлений для версий 0.X> = 0.1.0 и не обновлять версии 0.0.X.
  • 3
    @rofrol любая версия до 1.0.0 считается нестабильной, и эти правила не применяются
Показать ещё 7 комментариев
78

~ фиксирует основные и младшие номера. Он используется, когда вы готовы принять исправления ошибок в своей зависимости, но не хотите никаких потенциально несовместимых изменений.

^ фиксирует только основное число. Он используется, когда вы внимательно следите за своими зависимостями и готовы быстро изменить свой код, если незначительная версия будет несовместимой.

В дополнение к этому ^ не поддерживается старыми версиями npm и следует использовать с осторожностью.

Итак, ^ является хорошим дефолтом, но он не идеален. Я предлагаю тщательно выбрать и настроить наиболее удобный для вас оператор semver.

  • 12
    не соответствует действительности: диапазоны карет ^ 1.2.3 ^ 0.2.5 ^ 0.0.4. Позволяет вносить изменения, которые не изменяют крайнюю левую ненулевую цифру в кортеже [major, minor, patch]. Другими словами, это позволяет использовать исправления и незначительные обновления для версий 1.0.0 и выше, обновления исправлений для версий 0.X> = 0.1.0 и не обновлять версии 0.0.X. docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4
  • 5
    Этот ответ совершенно неверен (как и многие другие здесь). Ни один из них никогда не исправит главное число! Как сказал @rofrol, ^ просто оставляет самую левую ненулевую цифру без изменений. С другой стороны, ~ разрешает только обновления патчей, если указана младшая версия (например, ~ 1.2.3 или ~ 1.2), и разрешает второстепенные обновления, если младшая версия не указана (например, ~ 1).
Показать ещё 1 комментарий
72

Semver

<major>.<minor>.<patch>-beta.<beta> == 1.2.3-beta.2
  • Для тестирования используйте калькулятор npm. (Хотя объяснения ^ (включают в себя все, что больше определенной версии в том же основном диапазоне) и ~ (включают все, что выше определенной версии в том же младшем диапазоне) не являются на 100% правильными, калькулятор работает нормально )
  • В качестве альтернативы, используйте SemVer Check, который не требует выбора пакета, а также предлагает объяснения.

Разрешить или запретить изменения

  • Версия для пин- 1.2.3: 1.2.3.
  • Используйте ^ (как голова). Разрешает обновления на втором ненулевом уровне слева: ^0.2.3 означает 0.2.3 <= v < 0.3.
  • Используйте ~ (как хвост). Обычно замораживают самый правый уровень или устанавливают ноль, если опущен:
    • ~1 означает 1.0.0 <= v < 2.0.0
    • ~1.2 означает 1.2.0 <= v < 1.3.0.
    • ~1.2.4 означает 1.2.4 <= v < 1.3.0.
  • Пропустить самый правый уровень: 0.2 означает 0.2 <= v < 1. Отличается от ~ потому что:
    • Начиная с опущенной версии уровня всегда 0
    • Вы можете установить начальную основную версию без указания подуровней.

Все (надеюсь) возможности

Установить начальный основной уровень и разрешить обновления вверх

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

Заморозить основной уровень

~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

Заморозить второстепенный уровень

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

Запретить обновления

1.2.3             1.2.3
^0.0.3 (0.0.3)    0.0.3

Примечание: Отсутствует крупный, незначительный, патч или с указанием beta без номера, так же, как any пропавшего уровня.

Примечание: При установке пакета которым имеет 0 в качестве основного уровня, обновление будет только установить новую бета/пр версии уровня! Это потому, что npm устанавливает ^ по умолчанию в package.json и когда установленная версия похожа на 0.1.3, он замораживает все основные/второстепенные/патч-уровни.

  • 0
    Говорить людям, чтобы они не запускали проекты с 0, потому что разработчики из библиотек и потребителей не понимают систему, это ужасное решение. Я думаю, что @asdfasdfads имеет гораздо лучшую информацию.
  • 0
    @ProLoser Я просто считаю, что система должна быть упрощена, и мы не должны использовать версии 0.x.
Показать ещё 6 комментариев
46

~: разумно закрыть до

   ~1.1.5: 1.1.0 <= accepted < 1.2.0

^: Совместимый с

   ^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
  • 8
    ^0.1.3: 0.1.3 <= accepted < 1.0.0 вместо, нет?
  • 16
    @kytwb - нет. В специальном случае номеров версий нулевого выпуска карат эквивалентен тильде. Таким образом, ^0.1.3 принимает только версии 0.1.x и не принимает 0.2.0 , даже если это небольшое увеличение. Это поведение эквивалентно ~0.1.3 . Причиной такого поведения является то, что пакеты с нулевым выпуском все еще считаются нестабильными; по словам semver.org , # 4, «все может измениться в любое время» (включая несовместимые назад изменения).
26

^ - 1. [любой]. [любой] (последняя младшая версия)
~ - 1.2. [любой] (последний патч)

Отличное чтение это сообщение в блоге о том, как semver относится к npm
и что они делают, чтобы он соответствовал стандарту semver
http://blog.npmjs.org/post/98131109725/npm-2-0-0

  • 2
    не соответствует действительности: диапазоны карет ^ 1.2.3 ^ 0.2.5 ^ 0.0.4. Позволяет вносить изменения, которые не изменяют крайнюю левую ненулевую цифру в кортеже [major, minor, patch]. Другими словами, это позволяет использовать исправления и незначительные обновления для версий 1.0.0 и выше, обновления исправлений для версий 0.X> = 0.1.0 и не обновлять версии 0.0.X. docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4
23

Совпадение шляпы может считаться "сломанным", потому что оно не обновляет ^0.1.2 до 0.2.0. Когда программное обеспечение появляется, используйте версии 0.x.y, и соответствие шлям будет соответствовать только последней переменной (y). Это делается специально. Причина в том, что в то время как программное обеспечение развивается, API меняется быстро: однажды у вас есть эти методы, и на днях у вас есть эти методы, а старые исчезли. Если вы не хотите разорвать код для людей, которые уже используют вашу библиотеку, вы идете и увеличиваете основную версию: например. 1.0.02.0.03.0.0. Таким образом, к тому времени, когда ваше программное обеспечение, наконец, будет выполнено на 100% и полнофункционально, оно будет похоже на версию 11.0.0, и это не выглядит очень значимым и на самом деле выглядит запутанным. Если бы вы были, с другой стороны, используя версии 0.1.x0.2.x0.3.x, то к моменту завершения программного обеспечения на 100% и полнофункционального он будет выпущен как версия 1.0.0, и это означает "Этот выпуск является долгосрочным сервисом, вы можете продолжить и использовать эту версию библиотеки в своем производственном коде, и автор не изменит все завтра или в следующем месяце, и он не откажется от пакета".

Правило: используйте версию 0.x.y, когда ваше программное обеспечение еще не созрело и не выпустило его с увеличением средней цифры при изменении общедоступного API (поэтому люди, имеющие ^0.1.0, не получат обновление 0.2.0, и это не нарушит их код). Затем, когда программное обеспечение созреет, отпустите его под 1.0.0 и увеличивайте левую цифру каждый раз, когда изменится ваш открытый API (поэтому люди, имеющие ^1.0.0, не получат обновление 2.0.0 и не нарушат свой код).

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.
  • 0
    Этот комментарий был до смешного полезен и, похоже, не очень хорошо задокументирован. У вас есть ссылка на документацию об этом поведении? Этот ответ о v0 проектах мне очень помог.
  • 0
    У меня нет ссылки: я тоже нашел эту информацию, погуглив и поиграв с калькулятором семантической версии npm semver.npmjs.com
Показать ещё 1 комментарий
11

Объяснение одного лайнера

Стандартная система управления версиями - major.minor.build(например, 2.4.1)

npm проверяет и исправляет версию конкретного пакета на основе этих символов

~: исправлена ​​основная версия, исправлена ​​незначительная версия, соответствует любому номеру сборки

например.: ~ 2.4.1 означает, что он будет проверять на 2.4.x, где x - это что-то

^: основная версия исправлена, соответствует любой второстепенной версии, соответствует любому номеру сборки

например.: ^ 2.4.1 означает, что он проверит 2.x.x, где x - что-то

  • 2
    Я вижу 7 строк в этом ответе
9

Возможно, вы видели тильду (~) и каретку (^) в package.json. В чем разница между ними?

Когда вы устанавливаете npm момент --save, он сохраняет запись в package.json с префиксом caret (^).

Тильда (~)

Проще говоря, тильда (~) соответствует самой последней младшей версии (среднее число). ~ 1.2.3 будет соответствовать всем версиям 1.2.x, но будет отсутствовать 1.3.0.

Каретка (^)

Каретка (^), с другой стороны, более расслабленная. Он обновит вас до самой последней основной версии (первый номер). ^ 1.2.3 будет соответствовать любому выпуску 1.xx, включая 1.3.0, но будет удерживаться на 2.0.0.

Ссылка: https://medium.com/@Hardy2151/caret-and-tilde-in-package-json-57f1cbbe347b

  • 0
    Опять же, этот ответ вводит в заблуждение. SemVer четко заявляет, что нормальный номер версии ДОЛЖЕН принимать форму XYZ [где] X - основная версия, Y - вспомогательная версия, а Z - версия исправления.
5

~ Тильда:

  • ~ исправляет основные и второстепенные числа.
  • Он используется, когда вы готовы принять исправления ошибок в своей зависимости, но не хотят каких-либо потенциально несовместимых изменений.
  • Тильда соответствует последней второстепенной версии (среднее число).
  • ~ 1.2.3 будет соответствовать всем версиям 1.2.x, но пропустит 1.3.0.
  • Tilde (~) дает вам исправления ошибок.

^ Caret:

  • ^ исправляет только основное число.
  • Он используется, когда вы внимательно наблюдаете за своими зависимостями и готовы быстро изменить свой код, если незначительная версия будет несовместимой.
  • Он обновит вас до самой последней основной версии (первое число).
  • ^ 1.2.3 будет соответствовать любому выпуску 1.x.x, включая 1.3.0, но он будет отключен на 2.0.0.
  • Caret (^) дает вам и обратно совместимую новую функциональность.
  • 0
    Тильда соответствует самой последней версии патча (последний номер). Каретка соответствует самой последней вспомогательной версии (среднее число).
  • 1
    @AbdulRauf правильно. Ваше объяснение неверно
3

Тильда (~)

исправлена основная версия, исправлена вспомогательная версия, соответствует любому номеру сборки

"express": "~4.13.3" 

~4.13.3 означает, что он проверит 4.13.x, где x - это что-то, а 4.14.0

Карета (^)

исправлена основная версия, соответствует любой дополнительной версии, соответствует любому номеру сборки

"supertest": "^3.0.0"

^3.0.0 означает, что он проверит на 3.xx, где х что-нибудь

1

Тильда ~ соответствует второстепенной версии, если вы установили пакет с 1.4.2, и после установки также доступны версии 1.4.3 и 1.4.4, если в вашем package.json он используется как ~ 1.4.2, а затем npm install В вашем проекте после обновления будет установлена версия 1.4.4. Но для этого пакета доступно 1.5.0, и он не будет установлен ~. Это называется минорной версией.

Знак ^ соответствует основной версии, если пакет 1.4.2 остановлен в вашем проекте и 1.5.0 также доступен, то ^ установит основную версию. Он не позволит установить 2.1.0, если у вас есть ^ 1.4.2.

Фиксированная версия, если вы не хотите менять версию пакета при каждой установке, тогда использовали фиксированную версию без какого-либо специального символа, например, "1.4.2"

Последняя версия * Если вы хотите установить последнюю версию, используйте только * перед именем пакета.

  • 1
    Этот ответ вводит в заблуждение. SemVer четко заявляет, что нормальный номер версии ДОЛЖЕН принимать форму XYZ [где] X - основная версия, Y - вспомогательная версия, а Z - версия исправления.
1

Номер версии в синтаксисе, который обозначает каждый раздел с различным значением. синтаксис разбит на три части, разделенные точкой.

major.minor.patch 1.0.2

Major, minor и patch представляют разные версии пакета.

npm использует тильду (~) и каретку (^), чтобы указать, какой патч и второстепенные версии использовать соответственно.

Так что, если вы видите ~ 1.0.2, это значит установить версию 1.0.2 или последнюю версию патча, такую как 1.0.4. Если вы видите ^ 1.0.2, это значит установить версию 1.0.2 или последнюю минорную версию или версию патча, такую как 1.1.0.

0

~ спецификации для минорных выпусков версий ^ указывает на основные выпуски версий

Например, если версия пакета 4.5.2, при обновлении ~ 4.5.2 будет установлена последняя версия 4.5.x (МЕНЬШАЯ ВЕРСИЯ) ^ 4.5.2 установит последнюю версию 4.xx (ОСНОВНАЯ ВЕРСИЯ)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню