Поработав сверхурочно из-за проблем с зависимостями, я написал такой небольшой инструмент...

Node.js NPM

Некоторое время назад я столкнулся с очень запутанной проблемой: код, который я запускаю в своей локальной среде разработки и средах других коллег, несовместим с онлайн-кодом после упаковки. Меня это очень смущает, мой локальный код точно такой же, как онлайн-код,package.jsonЭто точно так же, поэтому, чтобы быть разумным, выводnode_modulesЭто одно и то же, эффект от обоих должен быть одинаковым. В итоге, после многократной очистки кеша и повторного развертывания проблема так и не решилась.

Было 7 часов вечера, и женский билет прислал мне сообщение WeChat с вопросом: «Когда я выйду с работы?» И эту проблему нужно решать сегодня, потому что среда uat будет тестироваться завтра, иначе она затянется и повлияет на итерацию.

С одной стороны продакт-менеджер снова и снова призывал к спросу, а с другой стороны женский билет назначал встречу и назначал встречу.Это действительно дилемма верности и сыновней почтительности издревле.

После умелых извинений я легко перекусила внизу в компании, потом поднялась наверх и продолжила умирать. После консультации с некоторой информацией у меня есть некоторые идеи. Конечно же, в местной средеnode_modulesОн отличается от сервера. Когда сервер развернут, команда для установки зависимостей (таких как:npm install), npm попытаетсяpackage-lock.jsonСкачать зависимости в файле, если такого файла нет, пройтиpackage.jsonПравила зависимости файла используются для загрузки пакета зависимостей соответствующей версии. будетpackage-lock.jsonПо сравнению с онлайн, оказывается, что действительно есть несоответствие. С тех пор нераскрытое дело было раскрыто.

Если вы хотите узнать причину и следствие этого, пожалуйста, подождите, пока я расскажу это медленно. Сначала поймите необходимые знания.

package.json

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

существуетpackage.jsonВ зависимостях используется номер версииобозначение версии semver, то есть формат "основная версия.дополнительная версия.версия патча". Правила увеличения номеров версий следующие:

  • Номер основной версии, некоторые несовместимые критические изменения
  • Дополнительный номер версии, обеспечивающий обратную совместимость. Некоторые API могут быть добавлены или объявлены устаревшими, что не повлияет на использование более ранней версии, но обеспечит обратную совместимость.
  • Номер версии патча, некоторые исправления обратной совместимости, в основном исправления некоторых ошибокПри выходе новой версии нельзя увеличивать количество по своему желанию, необходимо соблюдать вышеперечисленные правила, которые являются базовыми условиями квалифицированного проекта. в то же время,npmТакже установите некоторые правила для запускаnpm updateкогда, дляpackage.jsonЗависимости в обновлении до номера последней версии, насколько это возможно, вы должны знать:
  • : обновить только номер версии, используемый для автоматического получения последней версии для исправления ошибок в некоторых пакетах.
  • ^: Выполняйте только те обновления, которые не обновляют самый левый ненулевой номер версии. Например^0.1.0, который можно обновить до0.1.1 0.1.2и т. д., но не будет обновляться до0.2.0или позднее; и1.0.0можно обновить до1.0.1или1.1.0и т. д., но не будет обновляться до2.0.0или позже
  • >: принимать только любую версию выше указанной версии
  • : принимать только любую версию выше или равную указанной версии
  • <: принимать только любую версию ниже указанной версии
  • : принимать только любую версию, меньшую или равную указанной версии
  • =: принять точную версию
  • -: принимает ряд версий, таких как:2.1.0-2.6.2
  • ||: Объединение коллекций, таких как:< 2.1 || > 2.6
  • latest: использовать последнюю доступную версию
  • беззнаковый, эквивалентный=

файл блокировки пакета

В выпуске npm 5 представленоpackage-lock.jsonфайл, другие инструменты управления пакетами также имеют соответствующие файлы блокировки, такие какyarnизyarn.lock,pnpmизpnpm-lock.yaml.package-lock.jsonфайл по сравнению сpackage.jsonне только для отслеживания пакетов npm, используемых в проекте, но и для отслеживания точной версии каждого пакета npm, чтобы гарантировать, что продукт может иметь полную и идентичнуюnode_modulesДерево, продукт имеют такую ​​же форму выражения. как выше оpackage.jsonзависит от должностной инструкцииpackage.jsonВсегда была довольно неловкая проблема, то есть запускnpm updateилиnpm installКогда придет время, самые последние зависимости будут установлены как можно больше, если, хотя версии патчей и минорные версии не должны вносить критические изменения, не все авторы проектов с открытым исходным кодом следуют правилам semver (я полагаю, что некоторые люди могут не знать этот материал ), неизбежно, все еще могут быть ошибки. Затем, если он находится на ci-сервере сервера, каждый раз он сначалаnpm installПри установке зависимостей и последующем выполнении пакетных сборок не могут возникнуть проблемы? Здесь необходимо упомянутьnpm ciэтот заказ,npm ciиnpm installразные. Когда вы видите ci, вы также должны думать об этом ci в непрерывной интеграции. Правильно, это специально используется для зависимостей установки в CI/CD.npm ciпо сравнению сnpm installКоманда имеет несколько особенностей:

  1. версия npm должна быть ≥v5.7.1
  2. не изменитсяpackage.json,package-lock.jsonдокумент
  3. Если он существует до выполненияnode_modules, он будет удален первым
  4. Приоритет зависит отpackage-lock.jsonилиnpm-shrinkwrap.jsonзависимости установки файла
  5. Если зависимости в двух вышеуказанных файлах находятся вpackage.jsonЕсли не найдено, выдать ошибку и выйти из выполнения Эти функции гарантируют, что один и тот же файл блокировки может иметь одну и ту же среду зависимостей, что позволяет избежать несогласованности среды разработки во время сборки.

Восстановление истины по делу

После понимания этих ям и рассмотрения проблем, с которыми я столкнулся той ночью, становится очевидным, что проблема была вызвана несоответствием файла блокировки npm между моим локальным и тестовым сервером. Так почему же хороший файл блокировки кем-то изменен? Выяснилось, что ранее, после того, как я объединил код, некий симпатичный в группе сегодня принес в компанию свой персональный компьютер для разработки (компьютер компании описать сложнее), а npm-версия его компьютера была v7 или выше. , а npm, используемый в нашем проекте, является версией v6.Файлы блокировки, созданные двумя версиями npm, сильно различаются, что приводит к более чем 2000 изменениям в файле блокировки (в основном эквивалентно преобразованию 🤦), который отозван во время мистера Да, но файл блокировки потерял мои изменения, что вызвало проблему сегодня вечером.

Взял небольшой инструмент

Я много думал об этом по дороге домой.Соответствующие документы и спецификации в группе очень полные, а ситуации, которые могут вызвать несоответствия в базовой разработке, подробно указаны. Но документы мертвы, люди живы, а люди не машины. Даже если вы будете осторожны, вы все равно можете совершать ошибки. Могу ли я что-нибудь сделать, чтобы помочь нам избежать таких оплошностей? Проезжая по пути мимо Chongqing Mala Tang, я сначала упаковал один в качестве ночной закуски, чтобы компенсировать женский билет. Находитьpackage.jsonКогда искал информацию случайно нашел в скриптах скриптpreinstallХук, вы можете выполнить некоторые скриптовые операции до того, как будет установлен инструмент управления пакетами.У меня возникла идея.Я оцениваю инструмент управления пакетами и соответствующий ему номер версии в этом хуке.npm@6.14.11Для управления зависимостями используйтеyarnилиnpm@7для установки зависимостей) Об ошибке сообщу строго, а то эти ошибки можно задушить в кредле. За выходные добился того, что хотел. Очень прост в использовании, в проекте необходимо контролировать инструмент управления пакетами.package.jsonизscriptsДобавьте крючок следующим образом:

{
  "preinstall": "npx pm-keeper npm"
}

Вы также можете контролировать номер версии npm

{
  "scripts": {
    "preinstall": "npx pm-keeper npm@6.14.11",
    // or
    "preinstall": "npx pm-keeper npm 6.14.11"
  }

}

Вы также можете добавить один из этихpmKeeperэлемент конфигурации

{
  "scripts": {
    "preinstall": "npx pm-keeper"
  },
  "pmKeeper": {
    "name": "npm",
    "version": "6.14.1"
}

Если я использую нестандартный пакетный менеджер или версию, я выдам ошибку 😏

В случае установки с пряжей 使用 yarn 安装的情况

При использовании установки npm, которой нет в спецификации 使用了不在规范内版本的 npm 安装的情况

Это так просто, сумка теперь вgithubОткрытый исходный код, также выпущенный дляnpm, добро пожаловать на обмен

использованная литература

[1] package.json: узел будет apt/learn/he и - страх...

[2] обозначение версии semver:semver.org

[3] package-lock.json: узел будет apt/learn/he и - страх...