Telerik использует менеджеров пакетов NPM и Bower для разработки нескольких своих продуктов. В качестве примера, NPM и Bower используются при конструировании (т. Е. Исходном коде для сборки) и доставке открытого кода Kendo UI Core . Если вы не знакомы с назначением диспетчера пакетов и, в частности, с вышеупомянутыми менеджерами пакетов, было бы разумно остановиться сейчас и прочитать статью, которую я написал под названием « Менеджеры пакетов: вводное руководство для непосвященного фронтенд-разработчика ».
Твердо понимая назначение и использование NPM и Bower, не удивительно, что в документации упоминается «semver», описывающий, как добавить правильно версионный пакет в репозиторий . Когда вы видите термин «semver», вы можете считать, что это означает, что требуется номер версии, и он должен следовать семантическим предписаниям, подробно изложенным в спецификации Semantic Versioning 2.0.0 от Tom Preston-Werner .
Я не собираюсь предполагать, что спецификация semver совершенно ясна для всех. Итак, прежде чем я перейду к сути этой статьи, которая на самом деле касается всех этих мистических и магических символов, анализируемых синтаксическим анализатором node semver , я собираюсь быстро рассмотреть цель и семантику управления версиями semver.
Что такое Семвер?
По словам автора спецификации semver, и кратко говоря, цель semver — избежать «ада зависимости». Том, автор, описывает это явление «ада зависимости» как:
Ад зависимостей — это то, где вы находитесь, когда блокировка версии и / или разнородность версии не позволяют вам легко и безопасно продвигать ваш проект вперед.
Чтобы избежать этого адского места, Том предлагает 11 правил, которые определяют, что составляет номер версии, и семантическое значение, связанное с числовым изменением номеров версий. Короче говоря, Том считает, что решение обновить зависимость (т. Е. Пакет с API) должно передать очень специфическое семантическое значение разработчикам, которые используют пакет в большей системе. Это кажется разумным. Давайте рассмотрим, что именно это влечет за собой.
Построение номера версии
Том рекомендует, чтобы номер версии состоял из трех цифр, разделенных точкой. Примером semver будет:
Version 1.0.0
Первый номер (слева направо) называется ОСНОВНЫМ номером и изменяется только при внесении несовместимых изменений API. Второй номер называется номером MINOR и изменяется только при добавлении функциональности обратно совместимым образом. Третий номер называется номером PATCH и изменяется только при внесении обратно совместимых исправлений ошибок.
Если только что приведенное описание версионирования semver, почти вербатом из спецификации, содержит слишком много слов, похожих на спецификации, вы можете найти объяснение и пример из semver-ftw.org (показанный ниже), чтобы быть более дружественным для человека.
version [Major].[Minor].[Patch]
- Major = «критические изменения» — Увеличьте ОСНОВНУЮ версию, когда вы удалили или изменили функцию, и зависимые модули должны быть изменены, чтобы быть совместимыми с новой версией.
- Minor = «новая функция» — увеличивает версию MINOR, когда вы добавили функцию, но модуль обратно совместим.
- Patch = «bugfix» — увеличивает версию PATCH, когда вы исправили проблему, но не исправили или не изменили что-либо еще.
Ниже приведен пример из semver-ftw.org о том, как вы можете интерпретировать изменения версии в пакете на основе приведенных выше определений.
Предположим, что новый модуль под названием pizza публикуется в NPM как версия 0.0.1. Когда автор модуля решает добавить несколько новых функций,
.pepperoni()
он должен быть увеличен до 0.1.0. Когда на GitHub открывается проблема, связанная с ошибкой,.pepperoni()
и ошибка исправляется, она должна быть выдвинута как 0.1.1. Когда автор становится вегетарианцем и исключает.pepperoni()
метод, его следует опубликовать как 1.0.0.
Надеемся, что после этой великолепной иллюстрации пиццы значение, которое семвер заключает в капсулу, не является мистическим. То есть теперь, когда вы читаете semver пакета, вы должны понимать, что семантически выражается, чтобы вы могли принимать разумные решения об обновлении пакета. Или, может быть, более того, какие диапазоны версий вы, скорее всего, тоже захотите немедленно обновить (например, «1.2.3 || 1.2.4. || 1.2.5 ″, или, может быть, проще думать об этом как о диапазоне например, что-либо равное или равное «1,2,3 — 1,2,5»).
Когда semver понимается разработчиками и уважается авторами пакетов, среди инженеров-программистов царит спокойная гармония во избежание адской зависимости. Или так теория идет. На самом деле, это неосуществимое соглашение семантического соглашения между автором пакета и разработчиком, похоже, работает. И ничего лучшего не произошло. Итак, на данный момент у нас есть семантическое управление версиями или «semver», и оно предполагается и используется повсеместно, даже за пределами NPM и Bower .
Semver Ranges
Абсолютно лучшее место, где можно найти группировку чисел в дикой природе, — это файл package.json или bower.json. Назначение строк semver, найденных в файле package.json, состоит в том, чтобы указать на текущую приемлемую версию (и) пакета (ов), от которых зависит разработчик в своем проекте, сегодня и в будущем. Подробнее о будущей части через минуту.
Ниже приведен пример package.json из хранилища Kendo UI Core GitHub.
{ "name": "kendo-ui-core", "version": "1.0.0", "dependencies": { }, "devDependencies": { "optimist": "0.3.7", "typescript": ">=1.0.0", "uglify-js": "2.4.15", "cssmin": "0.3.2", "faye": "0.8.3", "xmlbuilder": "0.4.2", "colors": "0.6.0-1", "cookiejar": "1.3.0", "faye-websocket": "0.4.4", "less": "1.3.3", "jshint": "1.1.0", "grunt": "~0.4.2", "grunt-cli": "~0.1.0", "grunt-contrib-jshint": "~0.7.2", "grunt-contrib-copy": "~0.5.0", "grunt-debug-task": "0.1.3", "grunt-karma": "0.6.2", "qunitjs": "~1.12.0", "karma": "0.10.5", "karma-chrome-launcher": "~0.1", "karma-firefox-launcher": "~0.1", "karma-html2js-preprocessor": "~0.1", "karma-qunit": "0.1.1", "karma-junit-reporter": "0.2.1", "karma-osx-reporter": "0.0.4", "karma-ie-launcher": "~0.1", "karma-coffee-preprocessor": "~0.1.3" }, "scripts": { "build": "npm install && grunt build", "test": "./node_modules/.bin/grunt travis" } }
Ого … это много зависимостей. Этого следует ожидать в крупных проектах. Разве это не раздражало бы ваше мнение разработчика, если бы вам пришлось управлять путем обновления (patch> minor> major) для всех этих зависимостей вручную? Конечно, это можно сделать таким образом, и это именно то, что нужно было бы сделать, если зависимость указана с помощью номера разделителя вне диапазона (например, «faye-websocket»: «0.4.4»).
Программные операторы
Тем не менее, обратите внимание , что некоторые из semver чисел есть то , что , как представляется, программные операторы (например >=
, ~
, -
) вокруг них. Эти полезные символы — то, что синтаксические анализаторы узлов-семверов считают операторами (иначе говоря, semver sugar) в выражении сравнения, используемом для определения приемлемых диапазонов семвер. В основном, операторы узла-узла позволяют определить приемлемые пути обновления для каждого пакета на основе диапазона принятых версий. Другими словами, операторы могут указывать системе (или человеку) менеджера пакетов, на какую версию (версии) можно перейти, при наличии, при установке или обновлении зависимостей.
Если вы думаете о семантике semver, то, скорее всего, незначительные обновления и обновления патча не нарушат API пакета, или теория такова. Итак, вы не всегда хотели бы, чтобы эти обновления автоматически? Что ж, это именно то, что можно сделать с помощью нескольких дополнительных символов в строке semver, чтобы определить диапазон допустимых версий, которые будут обновлены и в будущем. Например, semver >=1.0.0
означает всегда получать последние обновления при обновлении, даже нарушая изменения API. Это безумие, верно? Но это, конечно, возможно, используя несколько операторов диапазона сахара.
Часто встречающиеся образцы диапазона
Тип и область действия диапазонов, которые можно определить, — сложная тема, которую можно выразить словами, особенно для новичков в концепции диапазонов версий. Чтобы познакомить вас со значением операторов диапазона, встречающихся в семимерных строках, я просто продемонстрирую и объясню в таблице ниже несколько наиболее часто встречающихся шаблонов полумного диапазона, встречающихся в дикой природе.
Семь бывшего |
Тип ассортимента |
Что это означает |
Диапазон многословного сем. |
* |
X-Range |
Будет использоваться самая последняя версия, что бы это ни было (обратите внимание, что можно использовать либо *, либо X, либо x) |
> = 0.0.0 |
1.2.3 — 2.3.4 |
Диапазон дефиса |
использовать самую последнюю версию, большую или равную 1.2.3 и меньшую или равную 2.3.4, найденную в хранилище |
> = 1.2.3 <= 2.3.4 |
1.2.3 — 2 |
Диапазон дефиса |
используйте самую последнюю |
> = 1.2.3 <3.0.0 |
1. * |
X-Range |
используйте самую последнюю версию, большую или равную 1.0.0 и меньшую, чем 2.0.0, в хранилище (т.е. получить любое значительное изменение версии больше или равное 1.0.0 и меньше, чем 2.0.0) |
> = 1.0.0 <2.0.0 |
1.2. * |
X-диапазонов |
используйте самую последнюю версию больше или равную 1.2.0 и меньше чем 1.3.0 в хранилище (т.е. получить любое изменение основной и вспомогательной версии больше или равно 1.2.0 и меньше 1.3.0) |
> = 1.2.0 <1.3.0 |
~ 1.2.3 |
Диапазоны Тильды |
используйте самую последнюю версию больше или равную 1.2.3 и меньше чем 1.3.0 в хранилище (т. е. разрешает изменения уровня исправления, если на компараторе указана вспомогательная версия. Если нет, позволяет изменения второстепенного уровня.) |
> = 1.2.3 <1.3.0 |
^ 1.2.3 |
Диапазоны карет |
используйте самую последнюю версию, большую или равную 1.2.3 и меньшую, чем 2.0.0, в хранилище (т.е. разрешает изменения, которые не изменяют крайнюю левую ненулевую цифру в [major, minor, patch]) |
> = 1.2.3 <2.0.0 |
Примечание: для меня подробности о рядах Тильды и Карета смотрите в разделе « Semver: Тильда и Карет » Тима Оксли в блоге Nodesource.com .
Если вы уже понимаете основы, о которых говорится в таблице выше, и хотите получить более исчерпывающее объяснение диапазонов, вы можете прочитать документацию по NPM / Github . Я предупреждаю вас, хотя, я нашел объяснения в документации довольно трудными для понимания. Мой совет, если вы удовлетворены только знанием основ, пропустите умственное упражнение, пытаясь понять документацию. Просто поймите, что практически любая сложность диапазонов может быть достигнута, особенно если вы считаете, что можете объединять наборы компараторов с помощью
||
(например, диапазон 1.2.7 || >=1.2.9 <2.0.0
будет соответствовать версиям 1.2.7, 1.2.9 и 1.4.6, но не версиям 1.2. 8 или 2.0.0.).
Мониторинг пакетов, используя диапазоны Semver
Когда у вас есть общее представление о том, что возможно с семверскими диапазонами, следующий логический вопрос — как автоматизировать процесс:
- Быть в курсе, что может произойти обновление, которое находится в пределах досягаемости;
- Обновление до этой версии автоматически, без участия человека, вручную, без вмешательства (т. Е. Ввода текста
bower update
илиnpm update
из командной строки).
Одним из способов решения этой проблемы является запуск bower update
или npm update
с некоторым интервалом в процессе сборки / развертывания. Это нормально, я полагаю. Но это 2014 год, и, как вы можете догадаться, есть сервис для такого рода вещей. Тот, который я использовал в прошлом, это Гемназиум . Gemnasium может проинформировать вас, когда пакеты будут доступны для обновления на основе диапазонов семвер. Затем он также может автоматически обновлять ваши пакеты , если вы дадите ему правильное разрешение на это. И это, друг мой, это какой-то автомат-соус-соус!
Ниже я показываю панель управления Gemnasium для зависимостей пакета Kendo UI Core NPM, найденных в файле package.json на GitHub.
Вывод
Как вы можете видеть, диапазоны semver являются мощными и полезными, когда дело доходит до управления кодом. Такие мощные, что они могут быть использованы такой службой, как Gemnasium, для автоматизации управления пакетами, их взаимоотношениями и путями обновления.
Надеюсь, эта статья прояснила любую путаницу вокруг semver и, казалось бы, мистических и магических символов в строке semver, представляющих диапазоны semver.