Вы, вероятно, что-то вроде:
"typescript":"~2.1.6"
в вашем, package.json
который npm обновляет до последней минорной версии, в вашем случае2.4.1
Изменить: вопрос от ОП
Но это не объясняет, почему «npm install» изменит файл блокировки. Разве файл блокировки не предназначен для создания воспроизводимой сборки? Если это так, независимо от значения semver, он все равно должен использовать ту же версию 2.1.6.
Ответ:
Это предназначено для блокировки вашего полного дерева зависимостей. Допустим, typescript v2.4.1
требует widget ~v1.0.0
. Когда вы устанавливаете npm, он захватывает widget v1.0.0
. Позже ваш коллега-разработчик (или сборка CI) устанавливает npm и получает, typescript v2.4.1
но widget
был обновлен до widget v1.0.1
. Теперь ваш модуль узла не синхронизирован. Это то, что package-lock.json
мешает.
Или в более общем плане:
В качестве примера рассмотрим
пакет А:
{"name": "A", "version": "0.1.0", "dependencies": {"B": "<0.1.0"}}
пакет B:
{"name": "B", "version": "0.0.1", "dependencies": {"C": "<0.1.0"}}
и пакет C:
{"name": "C", "version": "0.0.1"}
Если это единственные версии A, B и C, доступные в реестре, то обычная установка npm A установит:
A@0.1.0 - B@0.0.1 - C@0.0.1
Однако, если B@0.0.2 опубликован, то новая установка npm установит:
A@0.1.0 - B@0.0.2 - C@0.0.1 при условии, что новая версия не изменила зависимости B. Конечно, новая версия B может включать новую версию C и любое количество новых зависимостей. Если такие изменения нежелательны, автор A может указать зависимость от B@0.0.1. Однако, если автор A и автор B не являются одним и тем же лицом, у автора A нет возможности сказать, что он или она не хотят добавлять недавно опубликованные версии C, когда B вообще не изменился.
ОП Вопрос 2: Итак, давайте посмотрим, правильно ли я понимаю. Вы говорите, что файл блокировки определяет версии вторичных зависимостей, но все еще использует нечеткое соответствие package.json для определения зависимостей верхнего уровня. Это точно?
Ответ: Нет. Package-lock блокирует все дерево пакетов, включая корневые пакеты, описанные в package.json
. Если typescript
он заблокирован 2.4.1
в вашем package-lock.json
, он должен оставаться таким до тех пор, пока он не будет изменен. И скажем, завтра typescript
выпускает версию 2.4.2
. Если я проверю вашу ветку и npm install
запустлю, npm будет уважать файл блокировки и установить 2.4.1
.
Подробнее о package-lock.json
:
package-lock.json автоматически генерируется для любых операций, где npm изменяет либо дерево node_modules, либо package.json. Он описывает точное дерево, которое было сгенерировано, так что последующие установки могут генерировать идентичные деревья, независимо от промежуточных обновлений зависимостей.
Этот файл предназначен для фиксации в исходных хранилищах и предназначен для различных целей:
Опишите единственное представление дерева зависимостей, чтобы товарищи по команде, развертывания и непрерывная интеграция гарантированно устанавливали одинаковые зависимости.
Предоставьте пользователям возможность «путешествовать во времени» к предыдущим состояниям node_modules без необходимости фиксации самого каталога.
Для облегчения видимости изменений в дереве с помощью читабельных исходных текстов контроля.
И оптимизировать процесс установки, позволяя npm пропускать повторные разрешения метаданных для ранее установленных пакетов.
https://docs.npmjs.com/files/package-lock.json