
Начальный курс по фронтенду (vue): Начало обучения
В настоящее время студенты, изучающие фронтенд-разработку, не могут обойтись без npm , инструмента управления пакетами. Его превосходный механизм управления версиями пакетов охватывает все процветающее сообщество NodeJS . Он очень полезен. понять его внутренний механизм. Это помогает углубить наше понимание разработки модулей и различных внешних инженерных конфигураций, чтобы ускорить устранение неполадок (я считаю, что многие студенты были обеспокоены различными проблемами зависимостей).
В этой статье проводится подробный анализ механизма управления пакетами npm с трех точек зрения: package.json , управление версиями, установка зависимостей и конкретные примеры.

В Node.js модуль — это библиотека или платформа, а также проект Node.js Проект Node.js имеет модульную архитектуру. Когда мы создаем проект Node.js , это означает создание модуля. Этот модуль должен иметь файл описания, а именно package.json . Это наш самый распространенный файл конфигурации, но действительно ли вы поняли его конфигурацию в деталях? Разумная настройка файла package.json напрямую определяет качество нашего проекта, поэтому сначала мы проанализируем детальную настройку package.json .
В package.json имеется множество атрибутов, из которых необходимо заполнить только два: name и version . Эти два атрибута образуют уникальный идентификатор модуля npm .
name — это имя модуля. При присвоении имени необходимо следовать некоторым официальным спецификациям и рекомендациям:
имя пакета станет параметром в url модуля, командной строке или имени папки. Любые символы, не относящиеся url . находятся в имени пакета. Ни один из них не может быть использован. Вы можете использовать пакет validate-npm-package-name чтобы проверить, является ли имя пакета допустимым.
Семантические имена пакетов могут помочь разработчикам быстрее найти необходимые пакеты и избежать случайного получения неправильного пакета.
Если в имени пакета есть какие-либо символы, они не должны повторяться с существующим именем пакета после их удаления.
Например: поскольку react-native уже существует, react.native и reactnative не могут быть созданы снова.
Например: имя пользователя — conard , область — @conard , а опубликованный пакет может быть @conard/react .
name является уникальным идентификатором пакета и не должно повторяться с другими именами пакетов. Мы можем выполнить npm view packageName чтобы узнать, занят ли пакет, и просмотреть некоторую базовую информацию о нем:

Если имя пакета никогда не использовалось, будет выдана ошибка 404 :

Кроме того, вы также можете перейти на https://www.npmjs.com/ для получения более подробной информации о пакете.
{
"description": "Язык проектирования пользовательского интерфейса корпоративного класса и реализация компонентов React",
"ключевые слова": [
"муравей",
«компонент»,
«компоненты»,
"дизайн",
"рамки",
"внешний интерфейс",
«реагировать»,
"реагирующий компонент",
"уй"
]
} description используется для добавления информации об описании модуля, чтобы другие могли понять ваш модуль.
keywords используются для добавления ключевых слов в ваш модуль.
Конечно, они также играют очень важную роль, заключающуюся в облегчении поиска модулей. Когда вы используете npm search для поиска модуля, он будет соответствовать description и keywords . Написание хорошего description и keywords поможет вашему модулю получить более точную информацию:

: author и contributors . author относится к основному автору пакета, а один author соответствует одному человеку. contributors относятся к информации об участниках. Один contributors соответствует нескольким участникам. Значение представляет собой массив. Описание человека может быть строкой или следующей структурой:
{.
"имя" : "КонардЛи",
"электронная почта": "[email protected]",
"url": "https://github.com/ConardLi"
} {
"домашняя страница": "http://ant.design/",
"ошибки": {
"url": "https://github.com/ant-design/ant-design/issues"
},
"хранилище": {
"тип": "мерзавец",
"url": "https://github.com/ant-design/ant-design"
},
} homepage используется для указания домашней страницы этого модуля.
repository используется для указания репозитория кода модуля.

В bugs указывается адрес или электронная почта, куда люди, у которых есть вопросы о вашем модуле, могут обратиться сюда, чтобы задать вопросы.
Наш проект может зависеть от одного или нескольких пакетов внешних зависимостей. В зависимости от различных вариантов использования пакетов зависимостей мы настраиваем их со следующими атрибутами: dependencies、devDependencies、peerDependencies、bundledDependencies、optionalDependencies .
Прежде чем представить несколько конфигураций зависимостей, сначала давайте взглянем на правила конфигурации зависимостей. Конфигурация пакета зависимостей, которую вы видите, может быть следующей:
«зависимости»: {.
"antd": "ant-design/ant-design#4.0.0-alpha.8",
"аксиос": "^1.2.0",
"test-js": "файл:../test",
"test2-js": "http://cdn.com/test2-js.tar.gz",
"core-js": "^1.1.5",
} Конфигурация зависимостей соответствует следующим правилам конфигурации:
依赖包名称:VERSION VERSION ВЕРСИЯ — это конфигурация номера версии, соответствующая спецификации SemVer . При npm install она отправляется на сервер npm для загрузки пакетов, соответствующих указанному диапазону версий.依赖包名称:DWONLOAD_URL DWONLOAD_URL — это адрес загружаемого сжатого пакета tarball . Когда модуль установлен, этот .tar будет загружен и установлен локально.依赖包名称:LOCAL_PATH LOCAL_PATH — это локальный путь к пакету зависимостей, например file:../pacakges/pkgName . Подходит для локального тестирования пакета npm , этот метод не следует применять онлайн.依赖包名称:GITHUB_URL GITHUB_URL — это метод записи username/modulename github , например: ant-design/ant-design . Вы также можете указать tag и commit id позже.依赖包名称:GIT_URL GIT_URL — это git url нашей обычной базы кода клона, которая имеет следующий вид:<протокол>://[<пользователь>[:<пароль>]@]<имя хоста>[:<порт>] [: ][/]<путь>[#<commit-ish> | #semver:<semver>]
protocal может иметь следующие формы:
git://github.com/user/project.git#commit-ishgit+ssh://user@hostname:project.git#commit-ishgit+ssh://user@hostname/project.git#commit-ishgit+http://user@hostname/project/blah.git#commit-ishgit+https://user@hostname/project/blah.git#commit-ishdependencies указывают модули, от которых зависит проект. Здесь можно настроить как среду разработки, так и модули зависимостей производственной среды, например
". зависимости": {
"lodash": "^4.17.13",
"момент": "^2.24.0",
} В , которые вы можете использовать только в среде разработки, например eslint для проверки спецификаций кода и jest для тестирования. Когда пользователи используют ваш пакет, он может нормально работать даже без установки этих зависимостей. потребуется больше времени и ресурсов, поэтому вы можете добавить эти зависимости в devDependencies . Эти зависимости по-прежнему будут устанавливаться и управляться при локальной npm install , но не будут установлены в рабочую среду:
"devDependities" : {
"шутка": "^24.3.1",
"eslint": "^6.1.0",
} peerDependencies используются для указания версии, от которой зависит разрабатываемый вами модуль, и совместимости версии зависимого пакета, установленной пользователем.
Приведенное выше утверждение может быть слишком абстрактным. Давайте возьмем в качестве примера ant-design . package.json ant-design имеет следующую конфигурацию:
"peerDependities": {.
"реагировать": ">=16.0.0",
"реагировать-дом": ">=16.0.0"
} Когда вы разрабатываете систему и используете ant-design , вам обязательно нужно полагаться на React . В то же время ant-design также должен полагаться на React . Версия React , необходимая для поддержания стабильной работы, — 16.0.0 , а версия React на которую вы полагаетесь при разработке, — 15.x :
В настоящее время ant-design нужно использовать React и импортировать его:
import * as React from 'react'; import * as ReactDOM из 'react-dom';
На данный момент вы получаете среду хоста, которая является версией React в вашей среде, что может вызвать некоторые проблемы. В npm2 указание вышеперечисленных peerDependencies будет означать принуждение среды хоста к установке версий react@>=16.0.0和react-dom@>=16.0.0 .
В будущем npm3 больше не будет требовать принудительной установки пакетов зависимостей, указанных в параметре peerDependencies . Напротив npm3 будет проверять правильность установки после ее завершения. Если она неверна, пользователю будет выведено предупреждение. .
"зависимости": {
"реагировать": "15.6.0",
"antd": "^3.22.0"
} Например, я использую в проекте последнюю версию antd , а затем использую версию react 15.6.0 . При установке зависимости будет выдано следующее предупреждение:

В некоторых сценариях зависимый пакет может не являться сильной зависимостью. Функция этого зависимого пакета необязательна. Если этот зависимый пакет не может быть получен, вы хотите, чтобы npm install продолжала работать, не вызывая сбоя. Вы можете разместить эту зависимость. optionalDependencies . Обратите внимание, что конфигурация в optionalDependencies переопределяет dependencies поэтому ее необходимо настроить только в одном месте.
Конечно, при ссылке на зависимости, установленные в optionalDependencies , необходимо выполнить обработку исключений, иначе будет сообщено об ошибке, когда модуль не может быть получен.
отличается от приведенного выше. Значение bundledDependencies представляет собой массив. Некоторые модули могут быть указаны в массиве. Эти модули будут упакованы вместе при выпуске этого пакета.
"bundledDependities": ["package1", "package2"]
{
"лицензия": "MIT"
} Поле license используется для указания соглашения об открытом исходном коде программного обеспечения. В соглашении об открытом исходном коде подробно описаны права, которые другие имеют после получения вашего кода, какие операции они могут выполнять с вашим кодом и какие операции запрещены. Существует множество вариантов одного и того же соглашения. Слишком свободное соглашение приведет к потере автором многих прав на произведение, а слишком строгое соглашение будет неудобно для использования и распространения произведения. Авторы открытого исходного кода должны подумать, какие права они хотят сохранить, а какие ограничения они хотят ослабить.
Соглашения о программном обеспечении можно разделить на две категории: соглашения с открытым исходным кодом и коммерческие. В коммерческих соглашениях, также называемых юридическими заявлениями и лицензионными соглашениями, каждое программное обеспечение имеет свой собственный набор текстов, написанный автором программного обеспечения или специализированным юристом. нет необходимости делать это самостоятельно. Лучше всего выбрать широко распространенную лицензию с открытым исходным кодом.
Ниже приведены несколько основных протоколов с открытым исходным кодом:

MIT : Пока пользователи включают уведомление об авторских правах и уведомление о лицензии в свои копии проекта, они могут делать с вашим кодом все, что захотят, без какой-либо ответственности с вашей стороны.Apache : похож на MIT , но также включает условия, связанные с лицензированием патентов, предоставляемые участниками пользователям.GPL : Пользователи, изменяющие код проекта, должны публиковать свои соответствующие изменения при распространении исходного или двоичного кода.Если у вас есть более подробные требования к соглашению об открытом исходном коде, вы можете перейти на сайт Choosealicense.com/, чтобы получить более подробное описание соглашения об открытом исходном коде.

{
"main": "lib/index.js",
} Атрибут main может указывать основной файл записи программы. Например, запись модуля lib/index.js указанная выше в antd . Когда мы вводим antd в код: import { notification } from 'antd'; то, что представлено, — это lib/index.js .

Если ваш модуль является инструментом командной строки, вам необходимо указать запись для инструмента командной строки, то есть указать соответствие между именем вашей команды и локальным определяемым файлом. При глобальной установке npm будет использовать символическую ссылку для связи исполняемого файла с /usr/local/bin . При локальной установке он будет ссылаться на ./node_modules/.bin/ .
{
"корзина": {
"conard": "./bin/index.js"
}
} Например, приведенная выше конфигурация: Когда ваш пакет установлен глобально: npm создаст программную ссылку с именем conard в /usr/local/bin , указывающую на "./bin/index.js" . В это время, если вы выполните conard в командной строке, будет вызван связанный файл js.
Я не буду здесь вдаваться в подробности, больше информации будет подробно объяснено в моих последующих статьях об инструментах командной строки.
{
"файлы": [
"расстояние",
"либ",
"эс"
]
} Атрибут files используется для описания списка файлов, которые вы отправляете на сервер npm после npm publish . Если вы укажете папку, будет включено все содержимое папки. Мы видим, что загруженный пакет имеет следующую структуру каталогов:

Кроме того, вы также можете настроить файл
.npmignoreдля исключения некоторых файлов, чтобы предотвратить отправку большого количества ненужных файлов вnpm. Правила такие же, как и.gitignoreкоторый вы используете. Файлы.gitignoreтакже могут действовать как файлы.npmignore.
Команда man — это справочная команда в Linux . С помощью команды man вы можете просмотреть справку по команде, справку по файлу конфигурации, справку по программированию и другую информацию в Linux .
Если ваш модуль node.js является глобальным инструментом командной строки, вы можете указать адрес документа, который ищется командой man , через атрибут man в package.json .
Файлы man должны заканчиваться цифрой или, если они сжаты, расширением .gz . Число указывает, в какую часть man будет установлен файл. Если имя файла man не начинается с имени модуля, во время установки имя модуля будет иметь префикс.
Например, следующая конфигурация:
{
"мужчина" : [
"/Users/isaacs/dev/npm/cli/man/man1/npm-access.1",
"/Users/isaacs/dev/npm/cli/man/man1/npm-audit.1"
]
} Введите man npm-audit в командной строке:

. Модуль node.js реализован на основе модульной спецификации CommonJS . В строгом соответствии со спецификацией CommonJS , помимо файла описания пакета package.json , каталог модуля также должен содержать следующие каталоги:
bin : где. хранятся исполняемые двоичные файлы. Каталогlib : каталог для хранения кода jsdoc : каталог для хранения документовtest : каталог для хранения кода модульного тестаВ каталоге модуля вы не можете строго следовать приведенной выше структуре, чтобы организовать или назвать его. Вы можете указать directories в свойствах package.json чтобы указать, насколько ваша структура каталогов соответствует канонической структуре, указанной выше. Помимо этого, атрибут directories пока не имеет других применений.
{
"каталоги": {
"lib": "src/lib/",
"bin": "источник/bin/",
"man": "src/man/",
"док": "источник/док/",
"пример": "источник/пример/"
}
} Однако в официальном документе указано, что, хотя этот атрибут в настоящее время не играет важной роли, в будущем могут быть разработаны некоторые трюки. Например, файлы уценки, хранящиеся в doc, и файлы примеров, хранящиеся в example, могут отображаться в удобной форме.
{
"скрипты": {
"test": "jest --config .jest.js --no-cache",
"dist": "antd-tools запускает dist",
"compile": "antd-tools запустите компиляцию",
"build": "npm run compile && npm run dist"
}
} scripts используются для настройки сокращений некоторых команд скриптов. Каждый скрипт можно использовать в сочетании друг с другом. Эти скрипты могут охватывать весь жизненный цикл проекта. После настройки их можно вызывать с помощью npm run command . Если это ключевое слово npm , его можно вызвать напрямую. Например, в приведенной выше конфигурации указаны следующие команды: npm run test , npm run dist , npm run compile , npm run build .
Поле config используется для настройки переменных среды, используемых в сценарии. Например, следующую конфигурацию можно получить с помощью process.env.npm_package_config_port в сценарии.
{
"конфигурация": { "порт": "8080" }
} Если ваш модуль node.js в основном используется для установки глобальных инструментов командной строки, то для этого значения установлено значение true , и пользователи получат предупреждение при локальной установке модуля. Эта конфигурация не помешает пользователям выполнить установку, но предложит пользователям предотвратить неправильное использование, которое может вызвать некоторые проблемы.
Если для атрибута private установлено true , npm откажется публиковать его. Это сделано для предотвращения случайной публикации частного модуля.

"publishConfig": {
"реестр": "https://registry.npmjs.org/"
}, более подробная настройка при публикации модуля, например, вы можете настроить публикацию только определенного tag , настроить частный источник npm для публикации.
более подробной настройки обратитесь к npm-config
Если вы разрабатываете модуль, который может работать только в системе darwin , вам необходимо убедиться, что пользователи windows не будут устанавливать ваш модуль, чтобы избежать ненужных ошибок.
Использование атрибута os может помочь вам выполнить вышеуказанные требования. Вы можете указать, что ваш модуль может быть установлен только в определенных системах, или указать черный список систем, которые нельзя установить:
«os» : [ «darwin», «linux» ] "os" : [ "!win32" ]
Например, я помещаю тестовый модуль в черный список системы: "os" : [ "!darwin" ] . Когда я устанавливаю его в этой системе, появляется следующая ошибка:

В среде узла вы можете использоватьprocess.platform для определения операционной системы.
аналогичен приведенной выше os . Мы можем использовать атрибут cpu , чтобы более точно ограничить среду установки пользователя:
«cpu» : [ «x64», «ia32» ] "cpu" : [ "!arm", "!mips" ]
В среде узла вы можете использовать Process.arch для определения архитектуры ЦП.
Успех Nodejs неотделим от превосходной системы управления зависимостями npm . Прежде чем знакомиться со всей системой зависимостей, вы должны понять, как npm управляет версиями зависимых пакетов. В этой главе будут представлены спецификации выпуска версий npm包, как управлять версиями различных зависимых пакетов, а также некоторые лучшие практики в отношении версий пакетов.

Вы можете запустить npm view package version чтобы просмотреть последнюю версию package .
Запустите npm view conard versions чтобы просмотреть все опубликованные версии package на сервере npm.

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

модулей в npm包должны соответствовать спецификации SemVer — руководящему унифицированному правилу представления номера версии, разработанному Github . На самом деле это аббревиатура Semantic Version .
Официальный сайт спецификации SemVer: https://semver.org/Standard
Стандартный номер версии спецификации SemVer принимает формат XYZ , где X, Y и Z — неотрицательные целые числа, а заполнение нулями перед числами — запрещенный. X — основной номер версии, Y — дополнительный номер версии, а Z — номер версии. Каждый элемент должен быть увеличен численно.
major ): при внесении несовместимых модификаций API.minor ): при создании функций обратной совместимости. Новыйpatch ): при возникновении проблем с обратной совместимостью. Исправление.Например: 1.9.1 -> 1.10.0 -> 1.11.0
Если версия содержит серьезные изменения, не является стабильной и может не соответствовать ожидаемым требованиям совместимости, вы можете сначала выпустить расширенную версию.
Первый номер версии можно добавить в конец «основного номера версии. дополнительного номера версии. номера версии». Сначала добавьте номер соединения, а затем ряд идентификаторов и информацию о компиляции версий, разделенных точками.
alpha ):beta ):rc Release candiateДавайте посмотрим на исторические версии React :

Видно, что версия выпущена строго в соответствии со спецификацией SemVer :
主版本号.次版本号.修订号Именование16.8.0 -> 16.8.1 -> 16.8.216.8.0 -> 16.8.1 -> 16.8.2alpha , beta , rc и другие расширенные версииПосле изменения определенных функций пакета npm обычно необходимо выпустить пакет. новая версия Наш обычный подход — напрямую изменить package.json до указанной версии. Если операция неверна, легко вызвать путаницу в номере версии. Для завершения этой операции мы можем использовать команды, соответствующие спецификации Semver :
npm version patch : обновить номер версииnpm version minor : обновить дополнительный номер версииnpm version major : обновить основной номер версиипри разработке определенно необходимо для работы с некоторыми номерами версий. Если эти номера версий соответствуют спецификации SemVer , мы можем использовать пакет npm semver для рабочих версий, чтобы помочь нам. сравнивать размеры версий, извлекать информацию о версии и выполнять другие операции.
Npm также использует этот инструмент для управления версиями.
npm install semver
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true semver.valid('1.2.3') // '1.2.3'
semver.valid('abc') // null semver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.minVersion('>=1.0.0') // '1.0.0' Выше приведены наиболее распространенные варианты использования semver. Для получения более подробной информации просмотрите документацию semver: https://github.com/npm/node. -semver
Мы часто видим разные способы написания различных зависимостей в package.json :
"зависимости": {
"сигнал": "1.4.0",
"фиглет": "*",
"реагировать": "16.x",
"таблица": "~5.4.6",
"yargs": "^14.0.0"
} Первые три легко понять:
"signale": "1.4.0" : фиксированный номер версии"figlet": "*" : любая версия ( >=0.0.0 )"react": "16.x" : совпадение Основная версия ( >=16.0.0 <17.0.0 )"react": "16.3.x" : Сопоставить основную и дополнительную версии ( >=16.3.0 <16.4.0 ).Давайте посмотрим на последние две: номер версии Символы ~ и ^ заключены в кавычки:
~ : Если при установке зависимостей получена новая версия, установите последнюю версию z в xyz . То есть, сохраняя основной номер версии и дополнительный номер версии неизменными, сохраняется номер последней версии.^ : Когда при установке зависимостей получается новая версия, и y , и z в установленных xyz являются последними версиями. То есть, сохраняя основной номер версии неизменным, сохраняйте второстепенный номер версии и номер редакции как последнюю версию.Наиболее распространенной зависимостью в файле package.json должна быть "yargs": "^14.0.0" , поскольку когда мы используем npm install package для установки пакета, npm по умолчанию устанавливает последнюю версию, а затем устанавливает ее в разделе «Добавить». знак ^ перед номером версии.
Обратите внимание: если основной номер версии равен 0 , он будет считаться нестабильной версией. Ситуация отличается от приведенной выше:
0 : ^0.0.z и ~0.0.z оба. считаются фиксированными версиями, при установке зависимостей не произойдет никаких изменений.0 : ^0.yz ведет себя так же, как ~0.yz , только номер версии сохраняется как последняя версия.2.5Номер версии 1.0.0 используется для определения общедоступного API. Когда ваше программное обеспечение будет выпущено в официальную среду или будет иметь стабильный API, вы сможете выпустить версию 1.0.0. Итак, когда вы решите выпустить официальную версию пакета npm для внешнего мира, отметьте ее версию как 1.0.0.
В реальной разработке часто возникают странные проблемы из-за несоответствий в различных зависимостях, или в некоторых сценариях мы не хотим, чтобы зависимости обновлялись. Во время разработки рекомендуется использовать package-lock.json .
Блокировка версии зависимости означает, что, если мы не будем выполнять обновления вручную, исправленная версия будет устанавливаться каждый раз, когда мы устанавливаем зависимость. Убедитесь, что вся команда использует зависимости с одинаковыми номерами версий.
Каждый раз при установке фиксированной версии нет необходимости рассчитывать диапазон версий зависимостей, что может значительно ускорить время установки зависимостей в большинстве сценариев.
При использовании package-lock.json убедитесь, что версия npm выше 5.6, поскольку между версиями 5.0 и 5.6 логика обработки package-lock.json обновлялась несколько раз, а логика постобработки версии 5.6 постепенно стабилизировалась.
Мы проанализируем подробную структуру package-lock.json в последующих главах.
Наша цель
В реальных сценариях разработки, хотя нам не нужно каждый раз устанавливать новую версию, нам все равно необходимо регулярно обновлять версии зависимостей, чтобы мы могли пользоваться исправлениями проблем, улучшениями производительности и новыми обновлениями функций, вызванными обновлениями пакетов зависимостей.

Использование npm outdated может помочь нам составить список зависимостей, которые не были обновлены до последней версии:
и выполнить npm update . Обновите все красные зависимости.
1.0.0 .主版本号.次版本号.修订号alpha、beta、rcnpm , разработанные участниками команды. На данный момент рекомендуется изменить префикс версии ~ . Зависимости основного проекта необходимо обновлять каждый раз при обновлении вложенных зависимостей, что очень обременительно. Если вложенные зависимости полностью доверительны, каждый раз открывайте напрямую ^ Обновляйте до последней версии.docker , а дополнительные зависимости все еще разрабатываются и обновляются локально. Перед выпуском версии docker все версии зависимостей должны быть заблокированы, чтобы гарантировать отсутствие проблем в сети после установки локальных дополнительных зависимостей. выпущенный.npm выше 5.6 , и убедитесь, что файл package-lock.json включен по умолчанию.npm inatall членом инициализации package-lock.json отправляется в удаленный склад. Не отправляйте node_modules непосредственно в удаленный репозиторий.npm update для обновления зависимостей и отправляйте файл lock , чтобы другие участники одновременно обновляли свои зависимости. Не изменяйте файл lock вручную.package.json и выполните npm installnpm install package@version (изменение package.json не приведет к понижению версии зависимостей.lock
npm install , вероятно, пройдет через описанные выше процессы. В этой главе будут рассмотрены детали реализации, разработка и причины каждого процесса.
Мы все знаем, что после выполнения npm install зависимые пакеты устанавливаются в node_modules . Давайте подробнее рассмотрим конкретный механизм, с помощью которого npm устанавливает зависимые пакеты в node_modules .
В ранних версиях npm способ обработки зависимостей npm был простым и грубым. Он устанавливал зависимости в соответствующие node_modules рекурсивным образом и строго в соответствии со структурой package.json и структурой package.json пакетов субзависимостей. Пока не появятся субзависимые пакеты, которые больше не зависят от других модулей.
Например, наш модуль my-app теперь зависит от двух модулей: buffer и ignore :
{
"name": "мое приложение",
"зависимости": {
"буфер": "^5.4.3",
"игнорировать": "^5.1.4",
}
} ignore — это чистый JS модуль, который не зависит ни от каких других модулей, а buffer зависит от следующих двух модулей: base64-js и ieee754 .
{
"имя": "буфер",
"зависимости": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
} Затем, после выполнения npm install , структура каталогов модулей в node_modules получается следующая:

Преимущества такого подхода очевидны: структура node_modules соответствует структуре package.json один в один, иерархическая структура очевидна, а структура каталогов каждой установки гарантированно одинакова.
Однако представьте себе: если вы зависите от большого количества модулей, ваши node_modules будут очень большими, а уровень вложенности — очень глубоким:

Windows максимальная длина пути к файлу составляет 260 символов, а слишком глубокий уровень вложенности может вызвать непредсказуемые проблемы.Чтобы решить вышеуказанные проблемы, NPM внес большое обновление в версию 3.x Он меняет раннюю вложенную структуру на плоскую структуру:
node_modules .Тем не менее, используя вышеуказанную структуру зависимостей, после выполнения npm install мы получим следующую структуру каталогов:


В настоящее время, если мы полагаемся на версию [email protected] в модуле:
{
"имя": "my-app",
"зависимости": {
"Буфер": "^5.4.3",
"Игнорировать": "^5.1.4",
"BASE64-JS": "1.0.1",
}
} node_modules соответствует ли установленная версия модуля новым модулем.На этом этапе мы получим следующую структуру каталога после выполнения npm install :


Соответственно, если мы ссылаемся на модуль в коде проекта, процесс поиска модуля выглядит следующим образом:
node_modulesnode_modulesnode_modules путьbuffer2@^5.4.3 [email protected]

Следовательно, версия npm 3.x не полностью решает проблему избыточности модуля старой версии и может даже вызвать новые проблемы.
Представьте, что ваше приложение не зависит от версии [email protected] , но вы также зависите от buffer и buffer2 , которые зависят от различных версий base64-js . Поскольку при выполнении npm install зависимости в package.json проанализируются по порядку, порядок, в котором buffer и buffer2 помещаются в package.json определяет структуру зависимости node_modules :
сначала зависит от buffer2 :

Сначала зависит от buffer :

Кроме того, чтобы позволить разработчикам использовать новейшие пакеты зависимостей в соответствии с тем, что мы обычно блокируем большую версию в package.json , что означает, что после обновления незначительной версии некоторых пакетов зависимостей структура зависимости может Также будет изменена.
Чтобы решить проблему неопределенности npm install , файл package-lock.json был добавлен в версии npm 5.x , а метод установки также следует за плоским методом npm 3.x
Функция package-lock.json package-lock.json в npm install node_modules чтобы заблокировать структуру зависимости. .
Например, у нас есть следующая структура зависимости:
{
"имя": "my-app",
"зависимости": {
"Буфер": "^5.4.3",
"Игнорировать": "^5.1.4",
"BASE64-JS": "1.0.1",
}
} package-lock.json , сгенерированный после выполнения npm install выглядит следующим образом:
{
"имя": "my-app",
"версия": "1.0.0",
"зависимости": {
"BASE64-JS": {
"Версия": "1.0.1",
«Решен»: «https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz»,
«Целостность»: «sha1-asbrszt7xze47tutdw3i/np+pag ="
},
"Буфер": {
"Версия": "5.4.3",
"Решен": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
«Целостность»: «SHA512-ZVJ65TKFEIT3I6AJ5BIVJDZJJQGS4O/SNOEZG1F1KYAP9NU2JCUDPWZRSJTHMMSG0H7BZKN4RNQPIMHUXWX2A ==»,
"требует": {
"BASE64-JS": "^1.0.2",
"IEEE754": "^1.1.4"
},
"зависимости": {
"BASE64-JS": {
"Версия": "1.3.1",
«Решен»: «https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz»,
«Целостность»: «SHA512-MLQ4I2QO1YTVGWFWMCNGKO // JXAQUEZVWEKTJGQFM4JIK0KU+YTMFPLL8J+N5MSPOFJHWOAG+9YHB7BWAHM36G ==»
}
}
},
"IEEE754": {
"Версия": "1.1.13",
«Решен»: «https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz»,
«Целостность»: «SHA512-4VF7I2LYV/HAWERSO3XMLMKP5EZ83I+/CDLUXI/IGTS/O1SEJBNHTTNXZMRZFVOUQJ7LZJQHKETVPGSFDLWZTG =
},
"Игнорировать": {
"Версия": "5.1.4",
«Решен»: «https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz»,
«Целостность»: «SHA512-MZBUSAHKTW1U7JPKKJY7LCARD1FU5W2RLDXLM4KDKAYUCWZIMJKPLUF9CM1ALEWYJGUPDQEWLALM18Y6AU69A8A ==»
}
}
} Давайте поближе посмотрим на вышеуказанную структуру:

Два внешних атрибута name и version совпадают с name и version в package.json , и используются для описания текущего имени и версии пакета.
dependencies - это key , который соответствует структуре node_modules
resolvedversion node_modulesSubresource Integrity integrity hashrequires dependencies package.json зависимости.json.dependencies : структура совпадает с структурой наружных dependencies , и хранит пакеты зависимостей, установленные в подразделении node_modules .Обратите внимание, что не все подзадачи имеют атрибут dependencies node_modules
Например, просмотрите вышеприведенные зависимости:

Версия [email protected] , на которую мы полагаемся в конфликтах my-app с base64-js@^1.0.2 на buffer мы полагаемся, поэтому [email protected] должен быть установлен в node_modules buffer пакет, соответствующий атрибуту dependencies buffer в package-lock.json был изменен. Это также соответствует плоскому подходу npm к зависимостям.
Следовательно, в соответствии с вышеупомянутым анализом, файл package-lock.json package-lock.json структура каталога node_modules находятся в соответствии с индивидуальной перепиской. генерируется каждой установкой одинаковой.
Кроме того, использование package-lock.json в проекте может значительно ускорить время установки зависимостей.
Мы используем команду npm i --timing=true --loglevel=verbose lock lock полный процесс npm install . Очистите кэш npm перед сравнением.
Без использования файла lock :

Используйте файл lock :

Видно, что конкретная версия и ссылка на скачивание каждого пакета были кэшированы в package-lock.json . Большое количество сетевых запросов.
по разработке системных приложений рекомендуется отправить файл package-lock.json в репозиторий кодовой версии, чтобы гарантировать, что версии зависимости, установленные всеми разработчиками команды и ссылки CI согласованы при выполнении npm install .
При разработке semver npm ваш пакет npm должен зависеть от других репозиториев В рамках прицела, что вызовет ненужную избыточность. Таким образом, мы не должны публиковать файл package-lock.json ( npm не будет публиковать файл package-lock.json по умолчанию).
После выполнения команды npm install или npm update для загрузки зависимостей, в дополнение к установке пакета зависимости в каталоге node_modules , копия также будет кэширована в каталоге локального кеша.
Вы можете запросить его через команду npm config get cache : В Linux или Mac по умолчанию есть каталог .npm/_cacache в домашнем каталоге пользователя.
В этом каталоге есть tar каталога hash content-v2 content-v2 tar index-v5 index-v5
Когда NPM выполняет установку, он может генерировать уникальный key , соответствующий записи кэша в каталоге index-v5 на основе integrity、version、name хранящихся в package-lock.json , тем самым обнаружив hash пакета tar , И затем ищу его на основе hash tar
Мы можем найти пакет для поиска и тестирования в каталоге кэша и поиск пути пакета в index-v5 :
grep "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1. TGZ "-R Index -V5

Затем мы форматируем JSON:
{
"Key": "Pacote: версия-manifest: https: //registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz: sha1-asbrszt7xze47tutdw3i/np+pag =", "
«Целостность»: «sha512-c2ekhxwxvlsbrucjtrs3xfhv7mf/y9klmkdxpte8yevcoh5h8ae69y+/lp+ahpw91crnzgo78elok2e6apjfiq ==»,
«Время»: 1575554308857,
"размер": 1,
"Метаданные": {
"id": "[email protected]",
"Манифест": {
"Имя": "BASE64-JS",
"Версия": "1.0.1",
"Двигатели": {
"Узел": "> = 0,4"
},
"Зависимости": {},
"OptionaldEpendences": {},
"DEVDEPEDENDIENTS": {
"Стандарт": "^5.2.2",
"лента": "4.x"
},
"BundleDependencies": ложь,
"PeerdePendencies": {},
"Увиновлен": ложь,
"_Resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz",
"_inteGrity": "sha1-asbrszt7xze47tutdw3i/np+pag =",
"_Shasum": "6926D1B194FBC737B8EED513756DE2FCDA7EA408",
"_shrinkwrap": null,
"Bin": null,
"_id": "[email protected]"
},
"Тип": "Закончил манифест"
}
} Приведенный выше атрибут _shasum 6926d1b194fbc737b8eed513756de2fcda7ea408 - hash пакета tar , а первые несколько цифр 6926 hash - это первые два уровня кэшированных каталогов.

Приведенная выше стратегия кэширования начинается с версии NPM V5. }.
npm предоставляет несколько команд для управления данными кэша:
npm cache add : Официальное объяснение заключается в том, что эта команда в основном используется внутри npm , но его также можно использовать для вручную добавить кэш в указанный пакет.npm cache clean : Удалить все данные в каталоге кэша --forcenpm cache verify : Проверьте обоснованность и целостность кэшированных данных и очистить нежелательные данные.--prefer-offline, которые являются следующими:
--prefer-online : Распределите приоритет использование сетевых данных.--offline : не запрашивайте сеть и используйте кэшированные данные напрямую.Мы упоминали целостность файла много раз выше, так что же такое проверка целостности файла?
tarball загрузкой shasum зависимостей мы обычно можем hash npm info hash , рассчитанное npm для пакета зависимости

hash того, как пользователь загружает пакет зависимости локально, он или она должен убедиться, что во время процесса загрузки не было hash . Являются одинаковыми, убедитесь, что загруженная зависимость завершена.
Теперь, когда общий процесс завершен, давайте суммируем приведенный выше процесс:
Проверьте файл .npmrc : Приоритет: файл на уровне проекта .npmrc > Файл пользовательского уровня .npmrc > Файл глобального уровня .npmrc > NPM встроенный .npmrc
Проверьте, есть ли файл lock в проекте.
Нет файла lock :
npmpackage.json . node_modules .node_modules текущего модуля.npm пакет загрузки удаленного складаnpmnode_modules в соответствии со структурой зависимостиlocknode_modules в соответствииnode_moduleslock
package-lock.json package.json package-lock.json .
Приведенный выше процесс кратко описывает общий процесс npm install npm install package --timing=true --loglevel=verbose Процесс установки и детали определенного пакета.

yarn была выпущена в 2016 package-lock.json то время npm все еще находилась в периоде V3 . разработчиков. На данный момент рождается yarn :

Вышеупомянутые преимущества yarn упомянутые на официальном сайте, которые в то время были очень привлекательными. Конечно, npm позже осознал свои yarn yarn и lock много оптимизации. Дизайн все еще очень хороший.
yarn также использует плоскую структуру yarn.lock npm v3 для управления yarn.lock
. Это автогенсный файл. # пряжа блокировки v1 [email protected]: Версия "1.0.1" Разрешено "https://registry.yarnpkg.com/base64-js/-/base64-js-1.0.1.tgz#6926d1b194fbc737b8eed513756de2fcda7ea408" целостность sha1-asbrszt7xze47tutdw3i/np+pag = base64-js@^1.0.2: Версия "1.3.1" Разрешен "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" Целостность SHA512-MLQ4I2QO1YTVGWFWMCNGKO // jxaquezvwektjgqfm4jik0ku+ytmfpll8j+n5mspoffjhwoag+9yhb7bwahm36g == buffer@^5.4.3: Версия "5.4.3" Разрешен "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" целостность SHA512-ZVJ65TKFEIT3I6AJ5BIVJDZJJQGS4O/SNOEZG1F1KYAP9NU2JCUDPWZRSJTHMMZG0H7BZKN4RNQPIMHUXWX2A == зависимости: base64-js "^1.0.2" IEEE754 "^1.1.4" ieee754@^1.1.4: Версия "1.1.13" Разрешено "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" Целостность SHA512-4VF7I2LYV/HAWERSO3XMLMKP5EZ83I+/CDLUXI/IGTS/O1SEJBNHTTNXZMRZFVOUQJ7LZJQHKETVPGSFDLWZTG == Игнорировать @^5.1.4: Версия "5.1.4" Разрешен "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" Целостность SHA512-MZBUSAHKTW1U7JPKKJY7LCARD1FU5W2RLDXLM4KDKAYUCWZIMJKPLUF9CM1ALEWYJGUPDQEWLALM18Y6AU69A8A ==
Это видно, что он очень похож package-lock.json
yarn.lock package-lock.json jsonyarn.lock Номер версии зависимости от нейтронов yarn.lock не является фиксированным, что означает, что только yarn.lock . LOLLOCK не может определить структуру каталога node_modules и должна быть скоординирована с файлом package.json . И package-lock.json нуждается только в одном файле, чтобы определить.Стратегия кэширования yarn выглядит очень похоже на то, что npm v5 . Используйте командный yarn cache dir чтобы просмотреть каталог кэшированных данных:

По умолчанию
yarnиспользует режимprefer-online, что означает, что сетевые данные используются в первую очередь.
Я надеюсь, что после прочтения этой статьи она поможет вам:
npmpacakge.json получить дальнейшее представление о конфигурации проекта.npm npm install package-lock.json