Фронтенд-инжиниринг (5): все необходимые знания по npm здесь.

NPM

npmВ непрерывной итерации эта статья будет продолжать обновляться, вы можете поставить лайк👍собрать💖Подписаться~

npmОн предоставляет очень полную автоматизированную цепочку инструментов в процессе разработки интерфейса, который стал обязательным инструментом для каждого разработчика интерфейса, но также из-за его мощности многие разработчики интерфейса просто используют его. В этой статье мы обобщим то, что необходимо для ежедневной разработки.npmОчки знаний, чтобы разработчики могли лучшеnpmиспользуется в реальной разработке.

1. Механизм установки npm

мы все знаем,npm installОн используется для установки пакетов зависимостей в проекте, но то, как он устанавливается, часто игнорируется. Потому что многие студенты обращают внимание только на функции, предоставляемые зависимыми пакетами в реальной разработке, и не обращают внимания на иерархические отношения, в которых расположены зависимые пакеты. Установка зависимых пакетов сложна, что также приводит многих студентов в недоумение при возникновении проблем с установочным пакетом. Значит, надо еще понятьnpm installмеханизм, чтобы мы могли более спокойно решать проблему установки.

Гипотетический проектAppВот три зависимости:

"dependencies": {
    A: "1.0.0",
    B: "1.0.0",
    C: "1.0.0"
}

A,B,CТри модуля имеют следующие зависимости:

A@1.0.0 -> D@1.0.0

B@1.0.0 -> D@2.0.0

C@1.0.0 -> D@2.0.0

Вложенная установка

существуетnpm 2.xВ эту эпоху способ установки зависимостей относительно прост и понятен.Рекурсивным способом загрузите и заполните структуру локального каталога в соответствии с древовидной структурой зависимостей пакета.То есть каждый пакет будет устанавливать зависимости пакета к текущему пакету.node_modulesв каталоге.

воплощать в жизньnpm installПосле проектаAppизnode_modulesЭто станет следующей структурой каталогов:

├── node_modules
│   ├── A@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0
│   ├── B@1.0.0
│   │   └── node_modules
│   │   │   └── D@2.0.0
│   └── C@1.0.0
│   │   └── node_modules
│   │   │   └── D@2.0.0

Очевидно, что такая зависимая организационная структура имеет следующие преимущества:

  • Иерархическая структура очевидна
  • Простая реализация совместимости нескольких версий
  • Обеспечивает одинаковое поведение и структуру для зависимых пакетов независимо от того, установлены они или удалены.

Но недостатки тоже очевидны:

  • Может вызвать большое количество проблем с резервированием для одного и того же модуля.
  • Это может вызвать проблему глубоко вложенной структуры каталогов.

плоское крепление

отnpm 3.xВ начале для установки модуля использовался плоский метод (т.к. автор находится вnpm 6.14.5Проверка выполняется по версииnode_modulesсередина. При установке в тот же модуль оценивается, соответствует ли версия установленного модуля диапазону версий нового модуля.node_modulesУстановите модуль ниже.

вернуть проектAppНапример, выполнитьnpm installназад,node_modulesЭто станет следующей структурой каталогов:

├── node_modules
│   ├── A@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0
│   ├── B@1.0.0
│   ├── C@1.0.0
│   └── D@2.0.0

Это также может быть следующая структура каталогов:

├── node_modules
│   ├── A@1.0.0
│   ├── B@1.0.0
│   │   └── node_modules
│   │   │   └── D@2.0.0
│   ├── C@1.0.0
│   │   └── node_modules
│   │   │   └── D@2.0.0
│   └── D@1.0.0

D@2.0.0модули иD@1.0.0Модули скорее всего будут установлены на первом уровнеnode_modulesПод содержанием. Из этих нескольких модулей с одинаковыми, но разными версиями, какой из них будет установлен первым на первом уровнеnode_modulesЧто насчет каталога? Есть два наиболее распространенных утверждения:

  • согласно сpackage.jsonПорядок зависимостей устанавливается последовательно, то есть какой модуль имеет приоритетpackage.jsonперед ним будет установлен первыйnode_modulesПод содержанием;
  • Отдавайте приоритет модулям высокой версии (крупной версии) на первом уровнеnode_modulesПакеты средней и низкой версии будут установлены в текущем модуле.node_modulesсередина.

К сожалению, после неоднократных экспериментов автора два приведенных выше утверждения неверны. Автор пришел к выводу, что:

npm install, сначалаpackage.jsonЗависимости сортируются по первой букве (@ идет первой), а затем устанавливаются отсортированные пакеты зависимостей по алгоритму обхода в ширину, причем модули, которые установлены первыми, будут установлены первыми на первом уровне.node_modulesПод содержанием.

Метод установки так называемого обхода в ширину заключается в том, чтобы сначала установить пакет модуля и его зависимости на том же уровне, а не сначала установить модуль и все его подмодули.

Вот несколько реальных модулей, протестированных автором, если вам интересно, вы можете их проверить:

image.png

image.png

Когда все тестируют, удаляйтеnode_modulesПри этом не забывайтеpackage-lock.jsonФайлы также удаляются!

ПредположениеD@2.0.0Монтируется на приоритетnode_modulesкаталог, а затем установите модуль в проектE@1.0.0(в зависимости от модуляD@1.0.0), структура каталогов становится следующей:

├── node_modules
│   ├── A@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0
│   ├── B@1.0.0
│   ├── C@1.0.0
│   ├── D@2.0.0
│   ├── E@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0

можно увидеть,EМодуль все равно будет установлен под модулемD@1.0.0. Таким образом, можно сделать вывод, чтоВnode_moudlesЕсли пакет зависимостей уже существует во вновь установленном пакете зависимостей, если во вновь установленном пакете зависимостей возникает конфликт версий, он будет установлен в новом пакете зависимостей.node_modulesсередина.

Затем установите модуль в проектF@1.0.0(в зависимости от модуляD@2.0.0), структура каталогов становится следующей:

├── node_modules
│   ├── A@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0
│   ├── B@1.0.0
│   ├── C@1.0.0
│   ├── D@2.0.0
│   ├── E@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0
│   └── F@1.0.0

Как видите, только установитьFмодуль. Таким образом, можно сделать вывод, чтона первом уровнеnode_moudlesЕсли во вновь установленном пакете зависимостей уже есть пакет зависимостей, если нет конфликта версий, установка будет проигнорирована..

Как видно из приведенного выше примера,npm 6.xнет идеального решенияnpm 2.xпроблемы и даже вырождаются вnpm 2.xповедение.

Чтобы решить ситуацию, когда в каталоге много копий, вы можете передатьnpm dedupeДиректива для размещения всех зависимых модулей второго уровняD@1.0.0Перенаправление в каталог первого уровня (при условии, что зависимыйD@1.0.0Модуль был обновлен доD@2.0.0):

├── node_modules
│   ├── A@1.0.0
│   ├── D@2.0.0
│   ├── B@1.0.0
│   ├── C@1.0.0
│   ├── E@1.0.0
│   └── F@1.0.0

node_modulesМеханизм поиска пути: когда модуль находит соответствующий пакет зависимостей,nodejsпопытается запуститься из каталога, в котором находится текущий модуль,node_modulesЗагрузите соответствующий модуль в папку, если он не найден, то перейдите в каталог выше, пока модуль не появится в глобальном пути установки.node_modulesдо.

package-lock.json

отnpm 5.xНачать выполнениеnpm installавтоматически сгенерируетpackage-lock.jsonдокумент.

npmдля разработчиковИспользуйте последние пакеты зависимостей в целях безопасности,существуетpackage.jsonОбычно делают операцию блокировки большой версии, чтобы каждый разnpm installКаждый раз он будет извлекать последнюю версию из основной версии пакета зависимостей. Один из самых больших недостатков этого механизма заключается в том, что при наличии зависимых пакетов с младшими обновлениями версий может возникнуть проблема несогласованных зависимостей между соразработчиками.

package-lock.jsonДокумент точно описываетnode_modulesДревовидная структура зависимостей всех пакетов в каталоге и номер версии каждого пакета абсолютно точны. кsass-loaderсуществуетpackage-lock.jsonНапример:

"dependencies": {
  "sass-loader": {
    "version": "7.1.0",
    "resolved": "http://registry.npm.taobao.org/sass-loader/download/sass-loader-7.1.0.tgz",
    "integrity": "sha1-Fv1ROMuLQkv4p1lSihly1yqtBp0=",
    "dev": true,
    "requires": {
      "clone-deep": "^2.0.1",
      "loader-utils": "^1.0.1",
      "lodash.tail": "^4.1.1",
      "neo-async": "^2.5.0",
      "pify": "^3.0.0",
      "semver": "^5.5.0"
    },
    "dependencies": {
      "pify": {
        "version": "3.0.0",
        "resolved": "http://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
        "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
        "dev": true
      }
    }
  }
}

package-lock.jsonПодробное описание в основном состоит изversion,resolved,integrity,dev,requires,dependenciesЭти поля состоят из:

  • version: уникальный номер версии пакета.
  • resolved: источник установки
  • integrity: хеш-значение, указывающее на целостность пакета (проверяет, является ли пакет недействительным).
  • dev: если true, эта зависимость является только зависимостью разработки модуля верхнего уровня или транзитивной зависимостью одного модуля.
  • requires: все зависимости, требуемые зависимым пакетом, соответствующие зависимому пакету.package.jsonвнутриdependenciesзависимости в
  • dependencies: зависимый пакетnode_modulesЗависимые пакеты на верхнем уровнеdependenciesтакая же структура

надpackage-lock.jsonможно найти в файле, вrequiresа такжеdependenciesсуществуют вpifyзависимости. тогда давай зайдемnode_modulesЗагляните внутрь:

  1. открыть корневой каталогnode_modulesнайдет установленнымsass-loaderВсе необходимые зависимости, кроме этих зависимостейpify, номера основных версий всех зависимых пакетов такие же, какsass-loaderтребуемая консистенция.
  2. в корневой каталогnode_modulesоказатьсяpifyПакет зависимостей, обнаружил, что версия4.0.1.
  3. оказатьсяsass-loaderпакет зависимостей проекта, откройте егоnode_modulesобнаружил, что существует такжеpifyЗависимый пакет, но версия3.0.0. эта версияsass-loaderНа самом деле зависит от этой версииpify.

Благодаря вышеперечисленным шагам,package-lock.jsonдокументы иnode_modulesСтруктура каталогов один к одному, то есть каталог проекта существуетpackage-lock.jsonСтруктуру каталогов зависимостей, созданную при каждой установке, можно сохранить одинаковой.

При разработке приложения рекомендуется ставитьpackage-lock.jsonОтправьте файлы в репозиторий версий кода, что позволит членам вашей команды, специалистам по развертыванию операций илиCIСистема может выполнятьnpm installВерсии установленных зависимостей совпадают.

Но при разработке библиотеки не стоит ставитьpackage-lock.jsonФайл публикуется в репозиторий. Фактически,npmПо умолчанию не будетpackage-lock.jsonФайл выпущен. Причина этого в том, что проекты библиотек обычно зависят от других проектов.Пакеты, которые были загружены основным проектом, могут быть повторно использованы без жесткого кодирования.Поскольку библиотека зависит от точного номера версии, это может быть пакет причин. избыточность.

2. Зависимости в нпм

Классификация пакетов зависимостей

существуетnodeНа самом деле всего 5 зависимостей:

  • зависимости - бизнес-зависимости

  • devDependencies - зависимости разработки

  • peerDependencies - одноранговые зависимости

  • bundledDependencies/bundleDependencies — связанные зависимости

  • optionDependencies — необязательные зависимости

так какnpmпользователи , наши часто используемые зависимости:dependenciesа такжеdevDependencies, остальные три зависимости — это поля, которые используются только издателем пакета.

dependencies

Эта зависимость, наконец, запущена или выпущена в проектеnpmpackage, то есть зависимости в нем должны быть частью онлайн-кода. например, рамкаvue, сторонняя библиотека компонентовelement-uiИ т. д., эти пакеты зависимостей должны быть установлены в этом варианте для производственного использования.

по командеnpm install/i packageName -S/--saveОберните его в эту зависимость. Если версия не указана, просто напишите имя пакета и установите последнюю версию пакета в текущем репозитории npm. Если вы хотите указать версию, вы можете написать номер версии после имени пакета, напримерnpm i vue@3.0.1 -S.

отnpm 5.xДля начала вы можете добавить его вручную-S/--saveкоманда, выполнить напрямуюnpm i packageNameдобавить зависимости кdependenciesвходить.

devDependencies

Такого рода зависимости нужны только во время разработки проекта, то есть зависимости в нем не должны быть частью онлайн-кода. такие как инструменты для сборкиwebpack,gulp, препроцессорbabel-loader,scss-loader,тестовые инструментыe2e,chaiи т. д. Это наборы инструментов для вспомогательной разработки, и их не нужно использовать в производственной среде.

по командеnpm install/i -D/--save-devУстановите пакет как зависимость разработки. Если вы хотите уменьшить инсталляционный пакет, вы можете использовать командуnpm i --productionИгнорируйте зависимости разработки и устанавливайте только базовые зависимости, которые обычно являются онлайновыми машинами (илиQAокружающая обстановка).

Не думайте, что только вdependenciesМодули в будут упакованы вместе, а вdevDependenciesв не будет! Возможность упаковки модуля зависит от того, импортирован ли модуль в проект!

в бизнес проектахdependenciesа такжеdevDependenciesСущественной разницы нет, это просто нормативная роль, в реализацииnpm iмодули под обе зависимости будут загружены;npmКогда пакет в пакетеdependenciesЗависимости загружаются вместе при установке пакета,devDependenciesЗависимости нет.

peerDependencies

Роль этой зависимости состоит в том, чтобы предложить хост-среде установить подключаемый модуль вpeerDependenciesПакеты, указанные в пакете зависимостей, а затем пакеты, от которых зависит подключаемый модуль, всегда устанавливаются единообразно хост-средой.npmПакет, наконец, решить проблему несоответствия плагина искупленному пакету.

Это предложение может показаться немного неуклюжим, позвольте мне привести пример, чтобы проиллюстрировать это.element-ui@2.6.3Просто предоставьте набор на основеvueизuiбиблиотеки компонентов, но для этого требуется, чтобы хост-среда установила указанныйvueверсия, чтобы вы могли видетьelementв проектеpackage.jsonимеет конфигурацию в:

"peerDependencies": {
    "vue": "^2.5.16"
}

Требуется установка среды хостинга3.0.0 > vue@ >= 2.5.16версия, то естьelement-uiОперация зависит от диапазона версий, предоставляемого хост-средой.vueПакет зависимостей.

При установке плагинаpeerDependenciesсуществуетnpm 2.xа такжеnpm 3.xПроизводительность отличается:

существуетnpm 2.xв установочном пакетеpeerDependenciesУказанные зависимости будут следоватьnpm install packageNameвынуждены устанавливать вместе, иpeerDependenciesЗависимости, указанные в, будут установлены в среде хоста, поэтому нет необходимости устанавливать зависимости в среде хоста.package.jsonфайл, указанный в установленном пакетеpeerDependenciesзависимость от содержания.

существуетnpm 3.x, больше не потребуетсяpeerDependenciesУказанный пакет зависимостей устанавливается принудительно,npm 3.xОн проверит правильность установки только после установки.Если это не так, он напечатает пользователю предупреждение, например, о том, что некоторые пакеты должны быть установлены или некоторые пакеты имеют разные версии.

Просторечие: если вы устанавливаете меня, то вам лучше установить A, B и C в соответствии с моими требованиями.

bundledDependencies / bundleDependencies

Эта зависимостьnpm packотносится к команде упаковки. Предположениеpackage.jsonСуществуют следующие конфигурации:

{
  "name": "font-end",
  "version": "1.0.0",
  "dependencies": {
    "fe1": "^0.3.2",
    ...
  },
  "devDependencies": {
    ...
    "fe2": "^1.0.0"
  },
  "bundledDependencies": [
    "fe1",
    "fe2"
  ]
}

Выполните команду пакетаnpm pack, будет генерироватьfront-end-1.0.0.tgzсжатый пакет, а сжатый пакет содержитfe1а такжеfe2Два установочных пакета, чтобы пользователь выполнялnpm install front-end-1.0.0.tgzЭти две зависимости также установлены.

существуетbundledDependenciesЗависимости, указанные вdependenciesа такжеdevDependenciesОбъявлено, иначе упаковка сообщит об ошибке.

optionalDependencies

Даже если зависимости в этой зависимости не устанавливаются, это не влияет на весь процесс установки. Обратите внимание, что если зависимость также присутствует вdependenciesа такжеoptionalDependencies, тогдаoptionalDependenciesОн получит более высокий приоритет и может вызвать некоторые неожиданные эффекты, поэтому постарайтесь избежать этой ситуации.

В реальных проектах, если пакет вышел из строя, мы обычно ищем его замену или меняем на другую реализацию. Неопределенные зависимости усложняют оценку кода и тестирование, поэтому старайтесь не использовать эту зависимость.

Номер версии пакета зависимостей

npmУсыновленныйsemverСпецификация как схема управления версиями зависимостей.

согласно сsemverсоглашение, аnpmФормат версии пакета зависимостей обычно следующий:Основной номер версии Дополнительный номер версии Номер редакции(x.y.z), значение каждого числа:

  • основной номер версии(Также называется большой версией,major version)

    Изменение основной версии, вероятно, будет подрывным изменением, а это означает, что могут быть несовместимы с более низкой версиейAPIили использования (например,vue 2 -> 3).

  • дополнительный номер версии(Также называется маленькой версией,minor version)

    Второстепенные изменения версии должны быть совместимы с изменениями в той же основной версии.APIи использования, так что это должно оставить разработчиков равнодушными. Таким образом, мы обычно говорим только о номере основной версии, и он редко соответствует номеру дополнительной версии.

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

  • Поправка №(Также называется патч,patch)

    Обычно используется для ремонтаbugИли очень незначительное изменение, но также необходимость поддерживать обратную совместимость.

Ниже приведены несколько распространенных форматов версий:

  • "1.2.3"

    Указывает точный номер версии. Любые другие номера версий не совпадают. В некоторых более важных онлайн-проектах рекомендуется использовать этот метод для блокировки версии.

  • "^1.2.3"

    Указывает номер версии совместимых исправлений и дополнительных обновлений версии. Официальное определение: «Разрешает изменения, которые не изменяют крайнюю левую ненулевую цифру в кортеже [основной, второстепенный, патч]». Это предложение очень аппетитно, и вы можете понять его на нескольких примерах:

    "^1.2.3" 等价于 ">= 1.2.3 < 2.0.0"。即只要最左侧的 "1" 不变,其他都可以改变。所以 "1.2.4", "1.3.0" 都可以兼容。
    
    "^0.2.3" 等价于 ">= 0.2.3 < 0.3.0"。因为最左侧的是 "0",那么只要第二位 "2" 不变,其他的都兼容,比如 "0.2.4" 和 "0.2.99"。
    
    "^0.0.3" 等价于 ">= 0.0.3 < 0.0.4"。大版本号和小版本号都为 "0" ,所以也就等价于精确的 "0.0.3"。
    

    Как видно из этих примеров,^Это обновленный и безопасный способ записи, но для версий с основными номерами версий 1 и 0 будут использоваться другие механизмы обработки.

  • "~1.2.3"

    Указывает номер версии, который совместим только с обновлениями исправлений. о~Определение разделено на две части: если указан минорный номер версии (вторая цифра), совместимы только модификации патча (третья цифра); если минорный номер версии не указан, совместимы модификации второй и третьей цифр . Давайте разберемся с этим определением в двух случаях:

    "~1.2.3" 列出了小版本号 "2",因此只兼容第三位的修改,等价于 ">= 1.2.3 < 1.3.0"。
    
    "~1.2" 也列出了小版本号 "2",因此和上面一样兼容第三位的修改,等价于 ">= 1.2.0 < 1.3.0"。
    
    "~1" 没有列出小版本号,可以兼容第二第三位的修改,因此等价于 ">= 1.0.0 < 2.0.0"
    

    Как видно из этих примеров,~это соотношение^более аккуратное и безопасное письмо, и~Основные номера версий 0 или 1 не обрабатываются по-разному, поэтому «~ 0.2.3» — это тот же алгоритм, что и «~ 1.2.3». Когда первая цифра равна 0, а указана вторая цифра, они эквивалентны, например, «~0.2.3» и «^0.2.3».

  • "1.х", "1.Х", 1.*", "1", "*"

    Указывает номер версии с помощью подстановочных знаков. x, X, * и (null) означают одно и то же, и все они означают, что можно сопоставить что угодно. Конкретно:

    "*" 、"x" 或者 (空) 表示可以匹配任何版本。
    
    "1.x", "1.*" 和 "1" 表示匹配主版本号为 "1" 的所有版本,因此等价于 ">= 1.0.0 < 2.0.0"。
    
    "1.2.x", "1.2.*" 和 "1.2" 表示匹配版本号以 "1.2" 开头的所有版本,因此等价于 ">= 1.2.0 < 1.3.0"。
    
  • «1.2.3-альфа.1», «1.2.3-бета.1», «1.2.3-rc.1»

    Номер версии с ключевыми словами предварительной версии. Давайте поговорим об определениях нескольких ключевых слов в предварительной версии:

    alpha(α):预览版,或者叫内部测试版;一般不向外部发布,会有很多bug;一般只有测试人员使用。
    
    beta(β):测试版,或者叫公开测试版;这个阶段的版本会一直加入新的功能;在alpha版之后推出。
    
    rc(release candidate):最终测试版本;可能成为最终产品的候选版本,如果未出现问题则可发布成为正式版本。
    

    Подумайте об этом с точки зрения разработчика пакета: скажем, текущая живая версия «1.2.3», если я внесу некоторые изменения, мне нужно выпустить версию «1.2.4», но я не хочу запускать ее напрямую. (поскольку при использовании «~ 1.2. 3» или «^ 1.2.3» пользователи будут автоматически обновляться напрямую), что требует использования функции предварительного выпуска. Так что я мог бы выпустить "1.2.4-альфа.1" или "1.2.4-бета.1" и т.д.

    ">1.2.4-alpha.1"表示接受 "1.2.4-alpha" 版本下所有大于 1 的预发布版本。因此 "1.2.4-alpha.7" 是符合要求的,但 "1.2.4-beta.1" 和 "1.2.5-alpha.2" 都不符合。此外如果是正式版本(不带预发布关键词),只要版本号符合要求即可,不检查预发布版本号,例如 "1.2.5", "1.3.0" 都是认可的。
    
    "~1.2.4-alpha.1" 表示 ">=1.2.4-alpha.1 < 1.3.0"。这样 "1.2.5", "1.2.4-alpha.2" 都符合条件,而 "1.2.5-alpha.1", "1.3.0" 不符合。
    
    "^1.2.4-alpha.1" 表示 ">=1.2.4-alpha.1 < 2.0.0"。这样 "1.2.5", "1.2.4-alpha.2", "1.3.0" 都符合条件,而 "1.2.5-alpha.1", "2.0.0" 不符合。
    

Есть и другие способы записи номеров версий, например диапазоны (a - b), больше или равно знаку (>=), чем меньше или равен знак (<=),или(||) и так далее, так как он мало используется, здесь он не будет расширяться. Подробную документацию можно найти наСемантическое управление версиями (semver). Это такжеnpmpackage, который можно использовать для сравнения размера двух номеров версий, их соответствия требованиям и т. д.

Управление версиями пакетов зависимостей

npm 2.x/3.xстало прошедшим временемnpm 5.xВ приведенной выше среде (версия лучше всего в5.6выше, потому что в5.0 ~ 5.6средняя параpackage-lock.jsonЛогика обработки обновлена ​​в нескольких версиях,5.6Вышеупомянутое только начинает стабилизироваться), вы должны знать версию пакета зависимостей в проекте управления (с^Версия в качестве примера, другие типы версий могут относиться к):

  1. В той же предпосылке основной версии, если модуль находится вpackage.jsonВторостепенная версия вбольше, чемpackage-lock.jsonв минорной версии, затем выполнениеnpm install, модуль будет обновлен до последней версии в соответствии с основной версией, а номер версии будет обновлен доpackage-lock.json. еслименьше, чем, затемpackage-lock.jsonБлокировка версии.
// package-lock.json 中原版本
"clipboard": {
  "version": "1.5.10", 
},
"vue": {
  "version": "2.6.10",
}
// package.json 中修改版本
"dependencies": {
  "clipboard": "^1.5.12",
  "vue": "^2.5.6"
  ...
}

// 执行完 npm install 后,package-lock.json 中
"clipboard": {
  "version": "1.7.1", // 更新到大版本下的最新版本
},
"vue": {
  "version": "2.6.10", // 版本没发生改变
}
  1. Если модульpackage.jsonа такжеpackage-lock.jsonОсновная версия не совпадает, затем выполнитеnpm install, будет основываться наpackage.jsonОбновите последнюю версию под версией CUHK и обновите номер версии доpackage-lock.json.
// package-lock.json 中原版本
"clipboard": {
  "version": "2.0.4",
}
// package.json 中修改版本
"dependencies": {
  "clipboard": "^1.6.1",
}

// 执行完npm install后,package-lock.json 中
// 
"clipboard": {
  "version": "1.7.1", // 更新到大版本下的最新版本
}
  1. Если модуль находится вpackage.jsonзаписывается, в то время как вpackage-lock.jsonВ реализации нет записиnpm install, это будет вpackage-lock.jsonСоздайте подробные записи для этого модуля. Точно так же модуль вpackage.jsonНет записи вpackage-lock.jsonЕсть записи, исполняйтеnpm install, это будет вpackage-lock.jsonУдалите подробную запись для этого модуля.

  2. Если вы хотите обновить последнюю версию под основной версией модуля (обновить дополнительный номер версии), выполните следующую команду:

npm update packageName
  1. Если вы хотите выполнить обновление до указанного номера версии (обновить основной номер версии), выполните следующую команду:
npm install packageName@x.x.x
  1. Чтобы удалить модуль, выполните следующую команду:
npm uninstall packageName
  1. Установите точную версию модуля:
npm install packageName -D/S --save-exact  # 安装的版本号将会是精准的,版本号前面不会出现^~字符

Управляйте зависимостями с помощью приведенной выше команды,package.jsonа такжеpackage-lock.jsonНомера версий будут соответствующим образом обновлены.

Когда мы обновляем/удаляем зависимые пакеты, мы пытаемся реализовать их с помощью команд, чтобы избежать ручных модификаций.package.jsonНомер версии в , особенно не изменяйте его вручнуюpackage-lock.json.

3. нпм-скрипты

package.jsonсерединаscriptsПоля можно использовать для настройки команд сценария, и каждое из его свойств соответствует сценарию. кvue-cli3Например:

"scripts": {
  "serve": "vue-cli-service serve",
  ...
}

так что черезnpm run serveсценарий вместо этогоvue-cli-service servescript, чтобы запустить проект, не набирая каждый раз такой длинный скрипт.

npm runдаnpm run-scriptАббревиатура , как правило, используется в первом случае, но второе может лучше отражать суть команды.

Принцип работы

поле bin в package.json

package.jsonполя вbinозначаетСопоставление исполняемых файлов с указанными источниками файлов. пройти черезnpm binКоманда отображает текущий проектbinПуть к каталогу. Например, в@vue/cliизpackage.jsonсередина:

"bin": {
  "vue": "bin/vue.js"
}

Если установлено глобально@vue/cliесли,@vue/cliИсходные файлы будут установлены в глобальный каталог установки исходных файлов (/user/local/lib/node_modules), покаnpmбудет выполняться глобальноbinкаталог установки файла (/usr/local/bin) создает указатель на/usr/local/lib/node_modules/@vue/cli/bin/vue.jsимя файлаvueмягкая ссылка, так что вы можете ввести прямо в терминалеvueдля выполнения соответствующей команды. Как показано ниже:

Если установить локально@vue/cliесли,npmместный проект./node_modules/.binСоздать указатель на каталог./node_moudles/@vue/cli/bin/vue.jsпо имениvueмягкая ссылка, на этот раз вам нужно войти в терминал./node_modules/.bin/vueвыполнить.

Мягкая ссылка (символическая ссылка) — это особый тип исполняемого файла, который содержит ссылку на другой файл или каталог в виде абсолютного или относительного пути. существуетbinВыполнить в каталогеllИнструкции могут просматривать конкретное указание мягкой ссылки. При чтении или записи связанного файла система автоматически преобразует операцию в операцию над исходным файлом, но при удалении связанного файла система удаляет только связанный файл, а не сам исходный файл.

переменная окружения PATH

существуетterminalПри выполнении команды вкоманда будет вPATHНайдите исполняемый файл с таким же именем в пути, содержащемся в переменной окружения.. Локально установленные пакеты доступны только в./node_modules/.binИсполняемые файлы, которые регистрируют их в , не будут включены вPATHпеременные среды, на этот раз вterminalВвод команды в команду сообщит об ошибке, которую невозможно найти.

тогда зачем проходитьnpm runКак насчет пакетов командной строки, которые могут выполнять частичную установку?

Потому чтовсякий раз, когда выполняетсяnpm run, он автоматически создаст новыйShell,этоShellпреобразует текущий проектnode_modules/.binДобавьте абсолютный путь к переменной окруженияPATH, после завершения выполнения установите переменную окруженияPATHВосстановлены в исходное состояние.

Давайте проверим это утверждение. сначала выполнитьenvПросмотрите все текущие переменные среды, вы можете увидетьPATHПеременные среды:

PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

Выполнить снова в рамках текущего проектаnpm run envГлядя на переменные среды во время работы скрипта, вы можете увидетьPATHПеременные среды:

PATH=/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/mac/Vue-projects/hao-cli/node_modules/.bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

можно увидеть время выполненияPATHЕсть еще два пути для переменных окружения:npmПуть директивы и проектnode_modules/.binабсолютный путь.

Итак, поnpm runДоступ к текущему проекту возможен напрямую без добавления префикса пути.node_modules/.binИсполняемые файлы в каталоге.

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

Руководство по использованию

Входящие параметры

оscriptsПараметры в , вот еще несколько слов. В интернете много неточных утверждений.После собственных проб и ошибок,nodeиметь дело сscriptsПараметры на самом деле очень простые, такие как:

"scripts": {
  "serve": "vue-cli-service serve",
  "serve1": "vue-cli-service --serve1",
  "serve2": "vue-cli-service -serve2",
  "serve3": "vue-cli-service serve --mode=dev --mobile -config build/example.js"
}

За исключением первой исполняемой команды, любая строка, разделенная пробелами (за исключением некоторого синтаксиса оболочки), является аргументом и может быть передана черезprocess.argvдоступ к собственности.

process.argvСвойство возвращает массив, содержащий запускnodeАргументы командной строки для времени процесса. Первый элемент — началоnodeАбсолютный путь к исполняемому файлу процессаprocess.execPath, второй элемент — это путь к исполняемому в данный момент файлу JavaScript. Остальные элементы являются другими аргументами командной строки.

такие как выполнениеnpm run serve3Заказ,process.argvКонкретное содержание:

[ '/usr/local/Cellar/node/7.7.1_1/bin/node',
  '/Users/mac/Vue-projects/hao-cli/node_modules/.bin/vue-cli-service',
  'serve',
  '--mode=dev',
  '--mobile',
  '-config',
  'build/example.js']

Причина, по которой многие пакеты командной строки написаны таким образом, заключается в том, что они зависят отminimistилиyargsи другие инструменты анализа параметров для анализа параметров командной строки.

кminimistправильноvue-cli-service serve --mode=dev --mobile -config build/example.jsЕсли взять синтаксический анализ в качестве примера, результат после синтаксического анализа:

{ _: [ 'serve' ],
  mode: 'dev',
  mobile: true,
  config: 'build/example.js',
  '$0': '/Users/mac/Vue-projects/hao-cli/node_modules/.bin/vue-cli-service'}

существует./node_modules/.bin/vue-cli-serviceможно посмотреть в файлеminimistОбработка аргументов командной строки:

const rawArgv = process.argv.slice(2)
const args = require('minimist')(rawArgv, {
  boolean: [
    // build
    'modern',
    'report',
    'report-json',
    'watch',
    // serve
    'open',
    'copy',
    'https',
    // inspect
    'verbose'
  ]
})
const command = args._[0]
service.run(command, args, rawArgv).catch(err => {
  error(err)
  process.exit(1)
})

Мы также можем передавать параметры в виде параметров командной строки:

npm run serve --params  // 参数params将转化成process.env.npm_config_params = true
npm run serve --params=123 // 参数params将转化成process.env.npm_config_params = 123
npm run serve -params  // 等同于--params参数

npm run serve -- --params  // 将--params参数添加到process.argv数组中
npm run serve params  // 将params参数添加到process.argv数组中
npm run serve -- params  // 将params参数添加到process.argv数组中

Запустить несколько команд

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

серийное исполнение

Последовательное выполнение требует, чтобы предыдущая задача могла быть успешно выполнена до того, как следующая задача может быть выполнена, используйте&&символ для подключения.

npm run script1 && npm run script2

Во время последовательного выполнения команды, пока одна команда не выполняется, весь сценарий завершается.

параллельное выполнение

Параллельное выполнение, то есть несколько команд могут выполняться параллельно одновременно, используя&символ для подключения.

npm run script1 & npm run script2

Два символаBashвстроенный функционал. Дополнительно можно использовать сторонние модули диспетчера задач:script-runner,npm-run-all,redrun.

переменная окружения env

в исполненииnpm runПри написании сценарияnpmустановит некоторые специальныеenvпеременные окружения. вpackage.jsonВсе поля в , должны начинаться сnpm_package_переменные окружения в начале. Напримерpackage.jsonИмеются следующие поля:

{
  "name": "sh",
  "version": "1.1.1",
  "description": "shenhao",
  "main": "index.js",
  "repository": {
    "type": "git",
    "url": "git+ssh://git@gitlab.com/xxxx/sh.git"
  }
}

в состоянии пройтиprocess.env.npm_package_nameможет быть полученpackage.jsonсерединаnameзначение поляshИли путемprocess.env.npm_package_repository_typeПолучить вложенные атрибутыtypeзначениеgit.

в то же время,npmВсе связанные конфигурации также настроены на запуск сnpm_config_переменные окружения в начале.

Кроме того, будет установлена ​​специальная переменная окруженияnpm_lifecycle_eventnpm run serveprocess.env.npm_lifecycle_eventservenpm scripts

npm runnodeenv $npm_package_namescripts"scripts": {"bundle": "echo $npm_package_name"}

npm scriptsprepost

npm run servenpm run preservenpm run servenpm run postserve

"scripts": {
  "preserve": "xxxxx",
  "serve": "vue-cli-service serve",
  "postserve": "xxxxxx"
}

preservepostserveprepost

process.env.npm_lifecycle_event

const event = process.env.npm_lifecycle_event

if (event === 'preserve') {
    console.log('Running the preserve task!')
} else if (_event === 'serve') {
    console.log('Running the serve task!')
}

npmnpmnpm

npm

npm run serve --params=123

params123process.env.npm_config_paramsparamsparams

envnpm_config_npmenvnpm_config_package_lock

export npm_config_package_lock=false // 修改的是内存中的变量,只对当前终端有效

npm installnpmpackage-lock.json

echo $NODE_ENV

unset NODE_ENV

npmrcnpmrcnpmrc

  • .npmrcдокумент

    Работает только под этим пунктом. В других проектах эти настройки не действуют. создав это.npmrcДокументы могут сплотить командуnpmСпецификация конфигурации.

  • уровень пользователя.npmrcдокумент

    macАдрес ниже~/.npmrc. (npm config get userconfigВы можете увидеть путь хранения)

  • глобальный уровеньnpmrcдокумент

    macАдрес ниже$PREFIX/etc/npmrc. (npm config get globalconfigВы можете увидеть путь хранения)

  • npmВстроенныйnpmrcдокумент

    Это неизменяемый встроенный файл конфигурации, позволяющий сопровождающим переопределять конфигурацию по умолчанию стандартным и согласованным образом.macАдрес ниже/path/to/npm/npmrc.

ссылка на .npmrcnpm/iniнаписание формата.

распределение по умолчанию

пройти черезnpm config ls -lПроверитьnpmВнутренние параметры конфигурации по умолчанию. При отсутствии параметров конфигурации в командной строке, переменных среды или всех файлах конфигурации используются значения параметров по умолчанию.

директива конфигурации npm

npmпредоставляет несколькоnpm configДирективы для конфигурации на уровне пользователя и на глобальном уровне:

set

npm config set <key> <value> [-g|--global]
npm config set registry <url>  # 指定下载 npm 包的来源,默认为 https://registry.npmjs.org/ ,可以指定私有源

npm config set prefix <path>  # prefix 参数指定全局安装的根目录
# 配置 prefix 参数后,当再对包进行全局安装时,包会被安装到如下位置:
# Mac 系统:{prefix}/lib/node_modules
# Windows 系统:{prefix}/node_modules
# 把可执行文件链接到如下位置:
# Mac 系统:{prefix}/bin
# Windows 系统:{prefix}

использовать-g|--globalОтметьте, чтобы изменить или добавить конфигурацию глобального уровня, если она не используется, измените или добавьте конфигурацию пользовательского уровня (соответствующий уровень.npmrcфайл будет обновлен).

еслиkeyЕсли его нет, он будет добавлен в конфигурацию. если опущеноvalue,ноkeyбудет установлен наtrue.

также может охватыватьpackage.jsonсерединаconfigЗначение поля:

// package.json
{
  "name" : "foo",
  "config" : { "port" : "8080" },
  "scripts" : { "start" : "node server.js" }
}
// server.js
console.log(process.env.npm_package_config_port)  // 打印8080

Выполните команду:

npm config set foo:port 8000
// server.js
console.log(process.env.npm_package_config_port)  // 打印8000

get

npm config get <key>
npm config get prefix  # 获取 npm 的全局安装路径

Получить значение указанного элемента конфигурации в соответствии с приоритетом конфигурации.

delete

npm config delete <key>

npmНа официальном сайте написано, что элементы конфигурации, указанные во всех конфигурационных файлах, можно удалить, а элементы уровня проекта удалить после экспериментов нельзя..npmrcЭлементы конфигурации, указанные в файле.

list

npm config list [-l] [--json]

плюс-lили--jsonПросмотрите все элементы конфигурации, включая элементы конфигурации по умолчанию. Если вы не добавите его, вы не сможете просмотреть элементы конфигурации по умолчанию.

edit

npm config edit [-g|--global]

Откройте файл конфигурации в редакторе. использовать-g|--globalОтметьте, чтобы изменить конфигурацию глобального уровня и конфигурацию по умолчанию, если она не используется, отредактируйте конфигурацию пользовательского уровня и конфигурацию по умолчанию.

Ссылаться наnpm configдля получения дополнительных конфигураций по умолчанию.

5. Инженерное управление НПМ

Пересмотр управления проектами

package.jsonсерединаversionПоле представляет собой номер версии проекта. Всякий раз, когда проект выпускает новую версию, он долженversionПоля обновляются соответствующим образом для последующего обслуживания. Хотя его можно изменить вручнуюvsersionполе, но для того, чтобы автоматизировать весь процесс публикации, попробуйте использоватьnpm versionкоманда для автоматического обновленияversion:

npm version (v)1.2.3  # 显示设置版本号为 1.2.3 
npm version major  # 大版本号加 1,其余版本号归 0
npm version minor  # 小版本号加 1,修订号归 0
npm version patch  # 修订号加 1

При установке отображаемого номера версии номер версии должен соответствоватьsemverСпецификация, позволяющая добавлять к номеру версии префиксvлоготип.

Если вы не хотите, чтобы это обновление было запущено, вы также можете создать предварительную версию:

# 当前版本号为 1.2.3
npm version prepatch  # 版本号变为 1.2.4-0,也就是 1.2.4 版本的第一个预发布版本
npm version preminor  # 版本号变为 1.3.0-0,也就是 1.3.0 版本的第一个预发布版本
npm version premajor  # 版本号变为 2.0.0-0,也就是 2.0.0 版本的第一个预发布版本
npm version prerelease  # 版本号变为 2.0.0-1,也就是使预发布版本号加一

существуетgitсреда, выполнитьnpm versionПосле изменения номера версии он будет выполняться по умолчанию.git add->git commit->git tagдействовать:

вcommit messageПо умолчанию используется автоматически измененный номер версии, который можно добавить, добавив-m/--messageпараметры для настройкиcommit message:

npm version xxx -m "upgrade to %s for reasons"  # %s 会自动替换为新版本号

такие как выполнениеnpm version minor -m "feat(version): upgrade to %s for reasons"назад:

еслиgitВ рабочей области все еще есть незафиксированные изменения,npm versionне удастся выполнить, вы можете добавить-f/--forceсуффикс для принудительного исполнения.

Если вы не хотите, чтобыnpm versionДирективы влияют на вашеgitрепозиторий, который можно использовать в директивах--no-git-tag-versionпараметр:

npm --no-git-tag-version version xxx

Если вы хотите, чтобы значение по умолчанию не влияло на вашgitсклад, доступный по адресуnpmЗапрещено в настройках:

npm config set git-tag-version false  # 不自动打 tag
npm config set commit-hooks false     # 不自动 commit

Управление тегами модуля

Студенты, которые редко публикуют пакеты, могут быть заинтересованы в модулях.tagКонцепция не очень ясна. кvueНапример, сначала выполнитеnpm dist-tag ls vueПроверитьvueупаковкаtag:

beta: 2.6.0-beta.3
csp: 1.0.28-csp
latest: 2.6.10

вышеперечисленноеbeta,csp,latestто естьtag. каждыйtagсоответствует версии.

ЭтоtagКакая польза?tagпохожий наgitВнутри концепции ветвления издатель может указатьtag, и пользователи могут указатьtagдля установки пакета. Версии под разными лейблами не влияют друг на друга. Это не влияет на официальную версию, когда издатель выпускает пакет предварительной версии, а пользователь пробует пакет предварительной версии..

Выполняется при публикации пакетаnpm publishбудет отмечен по умолчаниюlatestэтоtag, который фактически выполняетnpm publish --tag latest. И когда пакет установлен, он выполняетсяnpm install xxxбудет загружен по умолчаниюlatestэтоtagПоследняя версия ниже фактически выполняетnpm install xxx@latest. Конечно, мы также можем настроитьtag:

# 当前版本为1.0.1
npm version prerelease  # 1.0.2-0
npm publish --tag beta
npm dist-tag ls xxx  # # beta: 1.0.2-0
npm install xxx@beta  # 下载beta版本 1.0.2-0

когдаprereleaseВерсия стабильная, можноprereleaseВерсия установлена ​​на стабильную версию:

npm dist-tag add xxx@1.0.2-0 latest
npm dist-tag ls xxx  # latest: 1.0.2-0

Управление пакетами на уровне домена

Внимательные студенты увидят, что вpackage.jsonСуществует две формы зависимостей в :

"devDependencies": {
  "@commitlint/cli": "^7.2.1",
  "commitizen": "^3.0.4"
}

из которых@Имя пакета, начинающееся с, является пакетом уровня домена (scoped package), роль этого пакета уровня домена заключается в преобразовании некоторыхpackagesСконцентрированный в одном пространстве имен, с одной стороны, он может управляться централизованно, а с другой стороны, может предотвратить конфликты имен с другими пакетами.

Чтобы опубликовать пакет на уровне домена, сначалаpackage.jsonизnameсвойство добавленоscopeСоответствующие объявления могут быть добавлены с помощью директив:

npm init --scope=scopeName -y

package.jsonстановится:

{
  "name": "@scopeName/package"
}

Вы можете использовать имя пользователя в качестве доменного имени или название организации в качестве доменного имени.

из-за использования@объявляет пакет,npmЭтот пакет будет идентифицирован как частный пакет по умолчанию, и вnpmЗа размещение приватных пакетов взимается плата, поэтому, чтобы не публиковать приватные пакеты, вы можете добавить--accss=publicуведомление о параметрахnpmЭто не частный пакет:

npm publish --access=public

Пакет уровня домена не обязательно является частным пакетом, но частный пакет должен быть пакетом уровня домена.

В то же время, при установке пакета уровня домена, вам необходимо установить его в соответствии с полным именем пакета уровня домена:

npm install @scopeName/package

6. Несколько практических навыков NPM

npx

ПредставляемbinВ поле было упомянуто, если локальная установка@vue/cli, вызовvueДирективы можно использовать только в сценариях проекта иpackage.jsonизscriptsВ поле, если вы хотите вызвать его в командной строке, нужно ввести:

## 项目根目录
`./node_modules/.bin/vue`

Чтобы облегчить вызов пакетов, установленных внутри проекта, мы можем использоватьnpxкоманду вместо выполнения:

npx vue

npxПринцип очень простой, то есть когда побежит, то и прилетит./node_modules/.binПути и переменные среды$PATHВнутри проверьте, существует ли команда.

из-заnpxБудут проверять переменные окружения$PATHТакже могут быть вызваны системные команды.

# 等同于ls
npx ls

Уведомление,Bashвстроенная команда отсутствует$PATHвнутри, так что он не может быть использован. Например,cdдаBashкоманда, поэтому ее нельзя использоватьnpx cd.

Помимо вызова внутренних пакетов проекта,npxТакже доступно изnpmХранилище загружает пакет в локальный глобальный и удаляет его после выполнения команды. То есть вы можете использоватьnpxДля использования вы не установили локально, но существуетеnpmпакет на складе.

npxКоманда на загрузку пакета будет выполнена по следующим правилам:

  • еслиpackage.jsonсерединаbinВ поле есть запись, или если все записи являются псевдонимами одной и той же команды, эта команда будет использоваться.
  • еслиpackage.jsonсерединаbinЕсть несколько полейbinвход и один изnameсоответствует части поля без области действия, будет использована команда.
  • еслиpackage.jsonНет вbinвход, илиbinНи одна из записей в пакете не соответствует имени пакета, тогдаnpxВыполнение завершится с ошибкой.

Так что он не установлен локально@vue/cliВ случае строительных лесов мы также можем использовать следующие команды для создания вашего проекта:

## 自动安装,使用完后删除,再次执行则会再次安装
npx @vue/cli create vue-project

## 等同于
npm i @vue/cli -g
vue create vue-project

npm init

использоватьnpm initПри инициализации нового проекта вам будет предложено ввести некоторую информацию описания проекта. Если вам сложно заполнить эту информацию, вы можете использовать-yотметьте, чтобы принятьpackage.jsonНекоторые значения по умолчанию в:

npm init -y

Также возможно установить значения по умолчанию для инициализации:

npm config set init-author-name <name> -g
npm config set init-author-email <email> -g

Вышеуказанные две инструкции для васnpmИмя автора и адрес электронной почты по умолчанию устанавливаются при выполненииnpm init -yкогда,package.jsonПоля имени автора и адреса электронной почты в файле автоматически записываются предустановленными значениями.

выше нашnpm initСамое знакомое познание, на самом делеnpm initТакже есть скрытая, но очень полезная функция:

npm init <initializer>Обычно используется для создания нового или существующегоnpmМешок.

initializerВот имяcreate-<initializer>изnpmпакет, который будет состоять изnpxустановить, а затем выполнить егоpackage.jsonсерединаbinСкрипт, соответствующий свойству, который будет создавать или обновлятьpackage.jsonи запустите некоторые операции, связанные с инициализацией.

npm init <initializer>конвертировано вnpxПравила команды таковы:

  • npm init foo -> npx create-foo
  • npm init @usr/foo -> npx @usr/create-foo
  • npm init @usr -> npx @usr/create

ViteScaffolding рекомендует нам использоватьnpm initдля инициализации:

npm init vite@latest -> npx create-vite@latest

Фактически, черезnpxиди скачивайcreate-viteпоследний пакет.

Посмотреть команды скрипта

Посмотреть все текущие проектыnpmСамый прямой путь к скриптовым командам — это открытьpackage.jsonфайл и проверитьscriptsполе. Мы также можем использовать без каких-либо параметровnpm runКоманда для просмотра:

npm run

Просмотр переменных среды

пройти черезenvЧтобы просмотреть все текущие переменные среды и просмотреть все переменные среды во время выполнения, выполните:

npm run env

Проверьте окружающую среду

в состоянии пройтиnpm doctorКоманда запускает несколько проверок в нашей среде. Например, проверьте, может ли наша текущая среда подключиться кnpmобслуживание, проверкаnodeа такжеnpmверсия, проверьтеnpmисточник, проверьте права доступа к файлам кеша и т.д.:

npm doctor

image.png

Управление модулями

Отметьте все модули, от которых зависит текущий проект, включая подмодули и подмодули подмодулей:

npm list/ls

Если вы также хотите просмотреть некоторую информацию описания модуля (package.jsonсерединаdescriptionв):

npm la/ll // 相当于npm ls --long

Часто есть много модулей, от которых зависит проект.Вы можете ограничить уровень выходных модулей для просмотра:

npm list/ls --depth=0 // 只列出父包依赖的模块

Проверьте информацию о текущей версии модуля, который зависит от проекта:

npm list/ls <packageName>

Просмотр информации о версии пакета модуля:

npm view/info <packageName> version // 模块已经发布的最新的版本信息(不包括预发布版本)
npm view/info <packageName> versions // 模块所有的历史版本信息(包括预发布版本)
npm view/info <packageName> <package.json中的key值> // 还能查看package.json中字段对应的值

Посмотрите, кто установил модуль из-за кого он есть.Если он пуст, это означает, что модуль является встроенным модулем или не существует:

npm ll <packageName>

Просмотрите всю информацию о модуле, включая его зависимости, ключевые слова, дату обновления, участников, адрес репозитория и лицензию и т. д.:

npm view/info <packageName>

Ознакомьтесь с обновляемыми модулями в текущем проекте:

npm outdated

Организуйте неактуальные модули в проекте:

npm prune

Посмотреть документацию модуля

Откройте домашнюю страницу модуля:

npm home <packageName> 

Откройте репозиторий кода модуля:

npm repo <packageName> 

Откройте адрес документации модуля:

npm docs <packageName>

Откройте адрес выпуска модуля:

npm bugs <packageName>

Запустите скрипт в другом каталоге

В вашей папке должно быть много приложений, и когда вы хотите запустить приложение, оно должно быть черезcdКоманда шаг за шагом входит в каталог приложения, которое вы хотите запустить, а затем выполняет команду запуска.npmпри условии--prefixКаталог запуска может быть указан:

npm run dev --prefix /path/to/your/folder

локальная отладка пакетов

  1. Предположим, вы разрабатываете глобальный пакет командной строкиA, в это время вам нужно отладить его локально, и не хотите отлаживать его каждый разnpm publishПосле установки и отладки. На этом этапе вы можете выполнить в каталоге модуля:
npm link

Вышеупомянутая команда достигает произвольного местоположения, связывая каталоги и исполняемые файлы.npmГлобальный исполняемый файл для команд модуля. После выполнения вышеуказанной команды вы можете вызвать ее глобальноAзаказ.

npm linkДелайте в основном две вещи:

  1. цельnpmМодуль создает программную ссылку, связывая ее с глобальнымnodeПуть установки модуля/usr/local/lib/node_modules/.
  2. цельnpmисполняемый модульbinфайл создает мягкую ссылку, связывая его с глобальнымnodeпуть установки команды/usr/local/bin/.
  1. Предположим, вы разрабатываете пакет функцийBи тогда вам нужно добавить в проектCОтладьте его, вы можете напрямую перебрать пакет функцийBскопируйте код в нужный проектCОтладка, но это не очень хороший способ. Мы можем сделать что-то вроде этого:
# 功能包 B 中,把 B link 到全局
npm link

# 项目 C 中,link 功能包 B
npm link B

Приведенная выше команда представляет собой пакет функцийBСоздайте программную ссылку глобально, а затем свяжите ее с проектомCПуть установки модуля./node_modules/, что эквивалентно созданию символической ссылки на локальный модуль.

Мы также можем напрямую передать пакет функцийBпуть как обычныйnpmМешокlinkк проектуCсередина:

cd /path/C
npm link /path/B

Используя этот способ,npmтакже для пакетов функцийBСоздавайте программные ссылки глобально.

Тогда мы можем в проектеCЗагрузите модуль в:

// 项目 C 中
const B = require('B')

Все пары пакетов функцийBИзменения будут напрямую отражены в проектеCсередина. Когда ваш проект больше не нуждается в модуле, вам нужно освободить софтлинк, в противном случае, когда вы установите его в проектnpmОшибка возникает, когда пакет на:

# 项目 C 中
npm unlink B

# 功能包 B 中
npm unlink

Проверка уязвимостей безопасности

Проверьте свой проект на наличие зависимостей с уязвимостями безопасности, если он существует, будет сгенерирован его отчет об уязвимости и отображен в консоли:

npm audit [--json]  # 加上--json,以 JSON 格式生成漏洞报告

npmобновитесь до6.xПосле версии он будет автоматически выполняться после обновления или загрузки нового пакета зависимостей в проекте.npm auditкоманда для проверки безопасности зависимостей проекта, и если есть уязвимости безопасности, отчет об уязвимости будет создан и отображен в консоли.

Исправление зависимостей с уязвимостями безопасности (автоматическое обновление до совместимых версий безопасности):

npm audit fix

воплощать в жизньnpm audit fixОн может исправить большинство пакетов зависимостей с уязвимостями безопасности.Для некоторых пакетов зависимостей, которые не могут автоматически исправить уязвимости, это означает, что естьSERVER WARNINGТакие предупреждения, как (в основном возникают, когда пакет зависимостей изменяется несовместимымapiИли если основная версия была обновлена), это означает, что рекомендуемая версия для восстановления может по-прежнему иметь проблемы. В этом случае вы можете выполнить следующую команду для восстановления этих зависимых пакетов:

npm audit fix --force

--forceОбновит номер версии пакета зависимостей до последней основной версии вместо совместимой версии безопасности. В обновлениях основных версий могут быть некоторые несовместимые способы использования, поэтому старайтесь избегать их использования.--force.

Если вы выполнитеnpm audit fix --forceПосле этого остаются пакеты зависимостей с уязвимостями безопасности, и их нужно выполнять вручную.npm auditРаспечатайте конкретную информацию о пакетах зависимостей, которые все еще имеют уязвимости безопасности, среди которыхMore infoРешение можно найти по соответствующей ссылке.

Если вы хотите знатьaudit fixКак быть с зависимыми пакетами в проекте, можно проверить заранее:

npm audit fix --dry-run --json

Если вы хотите исправить только зависимости рабочей среды (обновить толькоdependenciesПакеты зависимостей в , не обновлятьdevDependenciesзависимости в пакете):

npm audit --only=prod

Если вы не хотите исправлять зависимости, просто изменитеpackage-lock.jsonдокумент:

npm audit fix --package-lock-only

Если вы хотите установить пакет без проверки уязвимостей безопасности:

npm install packageName --no-audit

Чтобы установить все пакеты без проверки уязвимостей безопасности, вы можете изменитьnpmКонфигурация:

npm config set audit false

блокировка зависимости

npmКогда модуль установлен по умолчанию, он пройдет мимо курсора^для уточнения основного номера версии установленного модуля. можно настроитьnpmТильда~Чтобы ограничить номер версии установленного модуля:

npm config set save-prefix="~"

Конечно, вы также можете настроитьnpmУстанавливайте только модули с точными номерами версий:

npm config set save-exact true

Установка пакетов в среде непрерывной интеграции

Рекомендуется в среде непрерывной интеграцииnpm ciзаменитьnpm install:

npm ci

это сnpm installОсновные различия между ними:

  • Требуется, чтобы проект имелpackage-lock.jsonили npm-shrinkwrap.json, иначе выполнитьnpm ciсообщит об ошибке.
  • если обнаруженоpackage.jsonа такжеpackage-lock.jsonЕсли зависимости в файле не совпадают,npm ciзавершится с ошибкой вместо обновления номеров версий в обоих файлах.
  • npm ciтолько согласноpackage-lock.jsonЧтобы установить пакет,npm installОн будет включен в процесс установкиpackage.jsonа такжеpackage-lock.jsonЧтобы вычислить разницу версии пакета зависимостей. Так что сравнитеnpm install,npm ciЭто может не только повысить скорость установки пакета, но и избежать проблемы несовместимости версий пакетов в производственной среде.
  • Если проект уже существуетnode_modules,npm ciОн будет удален перед установкой.
  • npm ciВы можете установить зависимости только для всего проекта сразу, а не одну зависимость для проекта.

7. выпуск пакета npm

Готов к работе

После того, как вы настроили среду разработки для своего пакета (здесь это не подробно), обратите внимание на две вещи:

  1. существуетpackage.jsonдокументmainВ поле настраивается входной файл импортируемого пакета, и обычно настраивается путь к упакованному файлу.
{
    "main": "./lib/index.js",
}
  1. Создайте новый в корневом каталоге пакета.npmignoreфайл, чтобы указать, какие папки пакета не нужно публиковать.
.idea
node_modules
src
test
.eslintignore
.eslintrc

Процесс публикации

  1. если нетnpmсчет, первыйрегистручетная запись;
  2. Перейдите в корневой каталог проекта и выполнитеnpm login, а затем введите имя пользователя и пароль по запросу;
  3. воплощать в жизньnpm publishОпубликуйте, после успешной публикации, вашnpmпакет может бытьnpmнайти на официальном сайте;
  4. Отозвав опубликованную версию, вы можете выполнитьnpm unpublish packageName@x.x.x.

Публиковать распространенные ошибки

  • 400: проблема с версией, изменитьpackage.jsonизversionТы сможешь;
  • 401:npmЭто происходит, когда в качестве источника выбран сторонний источник, например, мы часто устанавливаем источник зеркала на источник Taobao. Просто измените источник зеркала обратно на значение по умолчанию;
  • 403: Имя пакета дублируется, вы можете изменить имя пакета и опубликовать его повторно.

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

tree shakingзависитES Moduleфункция модуля для работы, потому чтоES ModuleЗависимости модуля определяются во время компиляции (независимо от времени выполнения) и не могут быть изменены позже, поэтому на основе этой функции возможен надежный статический анализ.

И обычно мы разрабатываемnpmДля лучшей совместимости с браузерами пакет будет использоватьbabelПереведите код для совместимости и наиболее часто используемых@babel/preset-envвходит в пресетES2015 modules to CommonJS transformПлагин, функция этого плагина будетES Moduleсинтаксис вCommonJSсинтаксис так потерялсяES Moduleхарактеристики, что делает невозможнымtree shaking.

Тогда мы непосредственноpackage.jsonсерединаmainполе указывает наES6Файл грамматики не подходит? Это приносит две проблемы:

  1. babelИгнорируется по умолчаниюnode_modulesфайл для повышения скорости компиляции, если вы хотите поместить свойES6Пакеты синтаксиса обратно совместимы, вам нужно указатьbabelНастройте сложные правила блокировки, чтобы внести пакеты в белый список.
  2. если вnodejsсреда, которая использует ваш пакет и оказываетсяnodejsсреда не поддерживаетсяES Moduleспецификации, то это приведет к тому, что код сообщит об ошибке.

Для решения вышеуказанных задач нам необходимоpackage.jsonДобавлены два элемента конфигурации.

module

Это поле указывает наоба встречаютсяES Moduleспецификация модуля, но затем используйтеES5грамматикаисходный файл. Цель этого состоит в том, чтобы начатьtree shakingВ то же время это позволяет избежать проблемы совместимости кода.

{
    "main": "./lib/index.js", // 指向 CommonJS 模块规范的代码入口文件
    "module": "./lib/index.es.js" // 指向 ES Module 模块规范的代码入口文件
}

Приведенная выше конфигурация требует, чтобы обе версии спецификации модуля были опубликованы в вашем пакете. если вашnpmЭкологическая поддержкаmoduleполе, оно будет иметь приоритетES ModuleВходной файл для спецификации модуля, если он не поддерживается, он будет использоватьсяCommonJSВходной файл для спецификации модуля.

sideEffects

В этом поле указывается вашnpmИмеет ли пакет побочные эффекты. В частности, когда поле установлено вfalse, что указывает на то, что этот пакет не имеет побочных эффектов и может применятьсяtree shaking; если это массив, каждый элемент массива представляет файлы с побочными эффектами, эти файлы не будут применятьсяtree shaking.

{
  "sideEffects": [
    "dist/*",
    "es/components/**/style/*",
    "lib/components/**/style/*",
    "*.less"
  ]
}

На самом деле, чтобы освободить поддержкуtree shakingПакет механизмов, самое главное построитьmoduleИсходный файл, требуемый полем, т. е. исходный файл, который соответствует обоимES Moduleспецификация модуля, но с использованиемES5Синтаксис исходного файла.

rollupмогут быть построены непосредственно для удовлетворенияES Moduleфайл спецификации модуля, ноwebpackне можем. Так что нам просто нужно использоватьrollupПредоставляет возможность сборки, помещенной в файл конфигурацииoutputформатируется какesТолько что:

// rollup.config.js
export default {
  ...,
  output: {
    file: 'bundle.es.js',
    format: 'es'
  }
}

для лучшего использованияES Moduleспецификация модуля для включенияtree shakingфункция, желательноrollupразвиватьnpmМешок.

8. Наконец

оnpmЗдесь временно собраны точки знаний. Может быть много аспектов, которые не были обобщены на месте. Если в будущем появятся новые точки знаний, они будут обновлены в любое время. Вы также можете добавить их в любое время и развивайтесь вместе!