Как установить зависимости в node js
Перейти к содержимому

Как установить зависимости в node js

  • автор:

Как установить зависимости с прошлого проекта в новый package.json?

Aetae

Команды —save нет, есть —save-prod (которая не нужна, т.к. по умолчанию).
—save-dev — очевидно, устанавливает devDependencies.

Зависимости для разработки идут в devDependencies, зависимости для самого приложения в dependencies(по умолчанию). Для локальной разработки разницы никакой(кроме организации) — все они летят кучей в node_modules, однако если вы делаете свой готовый модуль для npm, то при установке такого модуля будут установлены только обычные dependencies.

Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать

bingo347

Дмитрий Беляев @bingo347 Куратор тега Node.js
Crazy on performance.

npm i это короткий вариант npm install
Без параметров он устанавливает зависимости из package.json и если есть файл package-lock.json, то нормализует папку node_modules по нему.
npm i name установит пакет name версии отмеченной тегом latest (тэг по умолчанию)
npm i name@tag установит пакет name версии отмеченной тегом tag
npm i name@5 установит пакет name версии 5.x.x где x.x — последний из 5
npm i name@5.3 установит пакет name версии 5.3.x где x — последний из 5.3
npm i name@5.3.1 установит пакет name версии 5.3.1
параметр —save или его короткий вариант -S сохранит зависимость в package.json в секции dependencies, с некоторых пор это поведение по умолчанию при наличии package.json
параметр —save-dev или его короткий вариант -D сохранит зависимость в package.json в секции devDependencies

А как устанавливать в Вашем конкретном случае можете решить только Вы.

Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

node.js

  • Node.js
  • +3 ещё

Почему сервер не ждет ответа от БД (монго) и идет до последнего обработчика и дает 404?

  • 2 подписчика
  • вчера
  • 150 просмотров

# Особенности работы Node Package Manager и файл package.json в Node.js

Node.js — среда выполнения JavaScript, работающая на движке V8 (транслирует Java в машинный код). Она позволяет создавать и использовать серверные приложения на JavcaScript, работает быстро и имеет привычный разработчикам синтаксис.

Одна из особенностей Node.js — это использование модулей — готовых приложений или частей кода, которые можно использовать при написании более сложных программ. Один или несколько модулей в Node.js называются пакетами. Для удобной работы с ними Node.js использует встроенный менеджер Node Package Manager (npm).

С помощью npm можно полноценно управлять всеми подключёнными к проекту пакетами. Он не только позволяет искать и устанавливать новые пакеты, но и следит за их версиями, прописывает в файле package.json все зависимости и может разворачивать проект с нуля, используя только записи в packasge.json.

В этой инструкции мы познакомимся с работой npm, изучим его взаимодействие с файлом package.json и в качестве примера установим на наш сервер блоговый движок Hexo.

# Начало проекта

Каждый новый проект Node.js лучше всего помещать в отдельную директорию — в этом случае устанавливаемые модули и используемые файлы не будут дублировать друг друга, так что не возникнет путаницы и непредвиденных ошибок. Создадим новую директорию для нашего проекта и перейдём в неё:

mkdir hexo cd hexo 

Создадим файл package.json, в котором будут содержаться все основные сведения о нашем проекте (от метаданных до номеров версий используемых пакетов):

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

npm init 

Она запустит автоматическое создание файла package.json, в процессе которого мы вручную введём метаданные нашего проекта. После запуска команды на экране появится сообщение:

 This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help init` for definitive documentation on these fields and exactly what they do. Use `npm install pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (hexo1) 

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

  • package name — название проекта.
  • version — номер версии.
  • description — описание нашего проекта.
  • entry point — «точка входа» — первая часть вашего модуля, которую будут загружать другие пользователи, если захотят скачать его. Мы оставим это значение заполненным по умолчанию (index.js).
  • test command — указание на фреймворк, который будет использован для тестирования нашего приложения. Поскольку мы не описываем здесь тестирование проекта, оставим эту часть незаполненной.
  • git repository — указание на репозиторий, в котором мы будем хранить наш проект. В нашем случае оставляем это поле незаполненным.
  • keywords — ключевые слова, по которым можно будет найти ваш модуль в поиске npm.
  • author — ваше имя и контактный e-mail, чтобы пользователи смогли связаться с вами в случае возникновения ошибок в работе модуля.
  • license — тип лицензии. Если вы работаете самостоятельно, можно указать Unlicensed.

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

Теперь посмотрим на содержимое файла package.json:

vim package.json 

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

 "name": "hexo", "version": "1.0.0", "description": "Blog for test", "main": "index.js", "scripts":  "test": "echo \"Error: no test specified\" && exit 1" >, "author": "Author / Author’s e-mail", "license": "UNLICENSED" > 

Теперь у нас есть первый файл нашего проекта, можно переходить к установке дополнительных модулей (пакетов).

# Установка модулей. Node Package Manager

Для добавления в проект дополнительных модулей (пакетов) Node.js использует пакетный менеджер npm. Можно использовать команду install или её более короткую версию i .

Установим наш выбранный блоговый движок:

npm i hexo-cli@4.1.0 

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

Во время установки npm не только устанавливает выбранный модуль, но и добавляет сведения о нём в файл package.json, указывая его в разделе зависимостей. Теперь, если снова открыть package.json, можно увидеть, что в конце добавились новые строчки:

... "dependencies":  "hexo-cli": "^4.1.0" > 

При добавлении следующих модулей они появятся в package.json следующими строками. Список всех добавленных к проекту модулей можно посмотреть командой ls :

npm ls 

Если к команде ls добавить директиву depth № , где вместо «№» указать число от 0 до 3, то помимо списка всех модулей на экране будут отображены все зависимости для данного модуля.

# Обновление модулей

С помощью npm можно отслеживать версии установленных модулей и рекомендовать к установке более поздние. Вводим команду:

npm outdated 

Она выведет на экран список установленных модулей с номерами текущих и доступных для установки версий:

 npm outdated Package Current Wanted Latest Location Depended by hexo-cli 4.1.0 4.3.0 4.3.0 node_modules/hexo-cli hexo1 

Как видим, для модуля hexo-cli доступна более новая версия. Обновим его:

npm up hexo-cli 

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

hexo -v 

Мы увидим на экране примерно такую информацию:

hexo-cli: 4.3.0 os: linux 5.4.0 Ubuntu 20.04.3 LTS (Focal Fossa) node: 17.2.0 v8: 9.6.180.14-node.12 uv: 1.42.0 zlib: 1.2.11 brotli: 1.0.9 ares: 1.18.1 modules: 102 nghttp2: 1.45.1 napi: 8 llhttp: 6.0.4 openssl: 3.0.0+quic cldr: 40.0 icu: 70.1 tz: 2021a3 unicode: 14.0 ngtcp2: 0.1.0-DEV nghttp3: 0.1.0-DEV 

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

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

npm audit 

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

Прежде чем переходить к запуску Hexo, обратимся к файлу с зависимостями package.json.

# package.json

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

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

npm install 

Без указания конкретного пакета для установки npm просканирует package.json и установит оттуда все необходимые модули.

# Запуск Hexo

Для запуска Hexo создадим новую директорию и перейдём в неё:

mkdir blog cd blog 

Инициализируем эту директорию как домашнюю директорию нашего блога:

hexo init 

Клиент Hexo создаст необходимые файлы, в том числе package.json для блога, в котором пропишет необходимые для установки дополнительные модули. После завершения инициализации папки установим дополнительные модули, указанные Hexo:

npm install 

Менеджер npm обратится к файлу с зависимостями package.json и установит недостающие модули.

Теперь нужно изменить конфигурационный файл Hexo, чтобы запустить его на нашем хосте. Откроем для этого конфигурационный файл _config.yml:

vim config.yml 

Здесь в строке URL укажем наш хост. Если ваш VPS расположен на Джино, но вы ещё не привязали к нему домен, можете указать технический адрес своего сервера.

Также нужно изменить параметр default_layout на draft и post_asset_folder на true.

Сохраним изменения в файле конфигурации и запустим Hexo для проверки его работы:

hexo server 

По умолчанию Hexo использует для работы порт 4000. Чтобы проверить работу Hexo, откройте браузер и в адресной строке укажите http://your_domain.name:4000 .

Если ваш VPS расположен на Джино, но вы не используете Выделенный IP, то для подключения к Hexo нужно будет воспользоваться Перенаправлением портов. В разделе Управление

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

Если всё указано правильно, вы увидите стартовую страницу Hexo.

В дальнейшем использование готовых модулей и управление ими при помощи npm значительно упростит и ускорит вашу работу с Node.js.

© Джино, 2003–2022. «Джино» является зарегистрированным товарным знаком.
Лицензия на телематические услуги связи №150549 от 09.03.2017.

Добро пожаловать в ад…зависимостей JavaScript

Начало любого JavaScript проекта сопровождается амбициозным намерением— использовать как можно меньше npm пакетов в процессе разработки. Но сколько бы усилий мы не предпринимали, рано или поздно пакеты начинают накапливаться. Со временем строк в package.json становится всё больше, а благодаря package-lock.json пул реквесты приобретают все более устрашающий вид со всеми своими дополнениями или удалениями в процессе добавления зависимостей.

“И нормально”, — скажет лидер команды разработчиков, а все остальные только кивнут в ответ. А что еще остается делать в такой ситуации? Ведь у нас есть счастливая возможность наблюдать, как оживает и процветает экосистема JavaScript. Нам не нужно каждый раз изобретать колесо и ломать голову над вопросами, которые уже давно решены сообществом открытого ПО.

Хорошая новость: вышла первая версия AppSignal для Node.js. Это приложение предполагает интеграцию с Express и включает интерфейс для автоматических модулей Node.js.

Предположим, вы захотели создать блог и выбрали для этого Gatsby.js. Попробуйте установить и сохранить его в число ваших зависимостей. Поздравляю! Вместе с этим фреймворком вы только что получили 19000 дополнительных зависимостей. Как вам такой подарок? До какой же степени может разрастаться дерево зависимостей JavaScript? Как же мы оказываемся в аду зависимостей? Давайте копнем поглубже и выясним.

Что же такое пакет JavaScript?

npm, менеджер пакетов, входящий в состав Node.js, содержит самый полный реестр пакетов JavaScript в мире! Он больше, чем RubyGems, PyPi и Maven вместе взятые! Данные приведены согласно исследованиям веб-сайта Module Counts, который отслеживает количество пакетов самых популярных реестров.

“Ничего себе сколько кода”, — подумали вы. Так и есть. Чтобы фрагмент вашего кода стал npm пакетом, в проекте нужно использовать package.json . Именно так код становится пакетом, который вы можете отправить в npm реестр.

Что такое package.json?

Согласно определению package.json:

  • выводит список пакетов, от которых зависит ваш проект (перечисляет зависимости);
  • определяет версии пакета, которые могут использоваться в проекте, руководствуясь правилами семантического управления версиями;
  • обеспечивает воспроизводимость сборки, и таким образом облегчает ее совместное использование с другими разработчиками.

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

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

Типы зависимостей в package.json

Чтобы прояснить вопрос накопления зависимостей с течением времени, рассмотрим разные типы зависимостей проекта. В пакете package.json встречаются несколько из них:

  • dependencies — основные зависимости, которые вы можете использовать и вызывать в коде проекта.
  • devDependencies — зависимости разработки, например библиотека Prettier для форматирования кода.
  • peerDependencies — равноправные зависимости, при включении которых в package.json, вы сообщаете человеку, устанавливающему ваш пакет, что ему нужна та же зависимость с указанной версией.
  • optionalDependencies — это необязательные зависимости. Если во время установки с ними возникнут какие-то проблемы, то это не повлияет на удачное завершение всего установочного процесса.
  • bundledDependencies — это массив пакетов, которые объединяются с вашим пакетом. Они пригодятся, если вы захотите использовать стороннюю библиотеку, не входящую в npm, или включить некоторые проекты в качестве модулей.

Назначение package-lock.json

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

Рассмотрим проект, имеющий среди своих зависимостей React. Если вы перейдете в package-lock.json , то увидите:

"react": "version": "16.13.0", 
"resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz",
"integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==",
"requires": "loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
>
>

package-lock.json является длинным списком зависимостей в проекте. Он указывает их версию, положение модуля (URI), хэш, отображающий взаимодействие модулей и необходимых для них пакетов. Продолжив чтение списка, вы найдете каждую запись для каждого пакета, необходимого для React и т.д. Вот тут-то и находится настоящий ад зависимостей. Он определяет все, что нужно проекту.

Разбираемся с зависимостями Gatsby.js

Итак, как же нам выйти из ситуации, в которой при установке одной зависимости мы получили в нагрузку 19 000? Ответ — зависимости зависимостей. Вот что происходит при установке Gatsby.js:

$ npm install --save gatsby. + gatsby@2.19.28
added 1 package from 1 contributor, removed 9 packages, updated 10 packages and audited 19001 packages in 40.382s

В package.json можно увидеть только одну зависимость. Но присмотревшись к package-lock.json, нельзя не заметить новорожденного монстра, раскинувшего свои 14 тысяч строк. Более детальную информацию можно получить в package.json, расположенном в GitHub репозитории Gatbsy.js. По подсчетам npm число прямых зависимостей составляет 136. А теперь представьте, что каждая из этих зависимостей имеет еще одну зависимость, и в итоге вы получаете 272 зависимости. И это я еще преуменьшил! В действительности у каждой зависимости может быть больше одной зависимости, так что их список продолжит пополняться.

Например, посмотрим, сколько библиотек требует lodash .

$ npm ls lodash
example-js-package@1.0.0
└─┬ gatsby@2.19.28
├─┬ @babel/core@7.8.6
│ ├─┬ @babel/generator@7.8.6
│ │ └── lodash@4.17.15 deduped
│ ├─┬ @babel/types@7.8.6
│ │ └── lodash@4.17.15 deduped
│ └── lodash@4.17.15 deduped
├─┬ @babel/traverse@7.8.6
│ └── lodash@4.17.15 deduped
├─┬ @typescript-eslint/parser@2.22.0
│ └─┬ @typescript-eslint/typescript-estree@2.22.0
│ └── lodash@4.17.15 deduped
├─┬ babel-preset-gatsby@0.2.29
│ └─┬ @babel/preset-env@7.8.6
│ ├─┬ @babel/plugin-transform-block-scoping@7.8.3
│ │ └── lodash@4.17.15 deduped
│ ├─┬ @babel/plugin-transform-classes@7.8.6
│ │ └─┬ @babel/helper-define-map@7.8.3
│ │ └── lodash@4.17.15 deduped
│ ├─┬ @babel/plugin-transform-modules-amd@7.8.3
│ │ └─┬ @babel/helper-module-transforms@7.8.6
│ │ └── lodash@4.17.15 deduped
│ └─┬ @babel/plugin-transform-sticky-regex@7.8.3
│ └─┬ @babel/helper-regex@7.8.3
│ └── lodash@4.17.15 deduped
.

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

$ du -sh node_modules
200M node_modules

200 мегабайт, как я уже говорил, совсем неплохой результат. Бывали случаи, когда размер директории мог легко перевалить за 700 мегабайт. Если вам интересно, какие модули занимают большую часть памяти, можете выполнить следующую команду:

$ du -sh ./node_modules/* | sort -nr | grep '\dM.*' 
17M ./node_modules/rxjs
8.4M ./node_modules/@types
7.4M ./node_modules/core-js
6.8M ./node_modules/@babel
5.4M ./node_modules/gatsby
5.2M ./node_modules/eslint
4.8M ./node_modules/lodash
3.6M ./node_modules/graphql-compose
3.6M ./node_modules/@typescript-eslint
3.5M ./node_modules/webpack
3.4M ./node_modules/moment
3.3M ./node_modules/webpack-dev-server
3.2M ./node_modules/caniuse-lite
3.1M ./node_modules/graphql
.

Ага, rxjs, ну и хитрая же ты штучка. Есть одна простая команда, которая поможет вам с размером node_modules и уменьшением дублирования зависимостей — npm dedup :

$ npm dedup
moved 1 package and audited 18701 packages in 4.622s
51 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities

Действие дедупликации призвано упростить структуру дерева зависимостей путем поиска общих пакетов между ними и их перемещением для последующего переиспользования. Как раз то, что происходит в нашем примере с lodash . Большинство пакетов останавливаются на lodash@4.17.15 , поэтому нет других версий lodash для установки. Мы добились этого результата в самом начале, так как только что установили наши зависимости, но если вы в течение какого-то времени добавляли зависимости в package.json , то лучше выполнить npm dedup . В случае использования yarn можете запустить yarn dedupe , хотя в этом нет необходимости, так как этот процесс уже запускается при yarn install .

Визуализация зависимостей

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

npm.anvaka.com

На изображении можно увидеть взаимодействие пакетов друг с другом, и в целом оно напоминает гигантскую паутину. Такое большое количество зависимостей Gatsby.js почти обрушило мой браузер. Здесь вы увидите, как взаимодействуют зависимости Gatsby.js. Там же можно увидеть их в 3D режиме.

npm.broofa.com

Данный способ изображения зависимостей напоминает блок-схему. В случае с Gatsby.js он быстро оказался довольно замысловатым, но если любопытно, то смотрите здесь. На npms.io можно поставить оценку каждой зависимости по нескольким критериям, и, согласно полученным результатам, они будут выделены разными цветами. Вы можете также загрузить туда свой package.json и получить его визуальное отображение.

Package Phobia

Это превосходный инструмент для предварительной проверки размера пакета перед запуском npm install . Он показывает размер публикации в реестре npm и размер на диске после его установки в проекте.

Чем больше сила, тем больше ответственность

Подводя итоги, без преувеличения скажу, что JavaScript и npm просто супер, а возможность гибкого подхода при выборе из океана зависимостей — еще лучше. Сущий пустяк — выполнить npm install для сохранения пары строк кода, но иногда мы почему-то забываем, что скрывается за этим действием.

Теперь, прочитав всю статью, вы сможете лучше разбираться в дереве зависимостей JavaScript. Устанавливаете ли вы слишком большую библиотеку или просто выясняете насколько сложные зависимости у проекта, моя статья станет вашим руководством по анализу зависимостей разной степени сложности.

  • Как улучшить производительность сайта с помощью мониторинга реальных пользователей
  • Движок JavaScript: что внутри
  • Как работает новый await верхнего уровня в JavaScript

Установка и обновление зависимостей в JavaScript

Установка и обновление зависимостей JavaScript

И снова привет! В прошлом посте мы начали рассматривать процесс управления зависимостями в JavaScript, разобрали основы: что такое npm-пакет, как выглядит манифест пакета, в каких полях прописываются зависимости и в принципе что такое дерево зависимостей, а также основы семантического версионирования (semver). Если вы пропустили предыдущий пост, то рекомендую начать с него.

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

npm shell autocomplete

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

Сделать это достаточно легко, достаточно выполнить следующие команды:

npm completion >> ~/.bashrc source ~/.bashrc
npm completion >> ~/.zshrc source ~/.zshrc

Это добавит в конфигурационный файл shell-а необходимый скрипт. После этого, если вы напишите: npm smth… а затем нажмете [TAB] , то shell автоматически дополнит вашу команду или предложит варианты дополнения.

Инициализация проекта

Как мы уже успели обсудить, проектом в npm является любая директория в которой находится манифест (файл package.json). Вы можете создать манифест вручную в любом редакторе кода, либо выполнить команду npm init. По умолчанию данная команда задаст вам серию вопросов в интерактивном режиме и сгенерирует простейший манифест в текущей директории на основе ваших ответов.

Однако я предпочитаю вызывать команду следующим образом: npm init -y , а затем править манифест в редакторе. При таком вызове npm не будет задавать вопросов, а просто сгенерирует минимальный манифест со значениями по умолчанию.

Использование инициализаторов

Говоря про npm init, нельзя не упомянуть про возможность использования специальных пакетов инициализаторов (npm initializers). Данные пакеты облегчают создание новых проектов генерируя необходимый boilerplate-код.

Используется это следующим образом: npm init , где — это название инициализатора (например: esm или react-app ).

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

Например так можно создать React-приложение используя инициализатор create-react-app: npm init react-app — my-react-app . Два минуса позволяют разделить аргументы CLI, которые передаются в команду npm init от тех, что передаются в сам инициализатор. Особенность инициализатора React, например, в том, что проект будет создан не в текущей директории, а в поддиректории с названием, которое вы укажете при вызове (в примере: my-react-app) .

Вы можете и сами написать свой инициализатор и опубликовать его в registry. Это может быть особенно удобно в корпоративной среде, где существует множество стандартов и соглашений — вы можете оформить их все в виде инициализатора и опубликовать его в закрытом npm registry. Таким образом разработчики внутри компании смогут быстро создавать новые проекты.

Добавление зависимостей в проект

Как мы выяснили ранее, зависимости прописываются в манифесте проекта в полях: dependencies, devDependencies, peerDependencies или optionalDependencies. Чтобы добавить новую зависимость в проект необходимо использовать команду: npm install или сокращенно: npm i .

Пример: npm i lodash .

Данная команда установит lodash самой свежей стабильной версии и добавит эту зависимость в поле dependencies манифеста проекта.

Аналогично можно устанавливать сразу несколько зависимостей одновременно: npm i lodash express passport .

Команда install также позволяет выбрать в какое поле будет добавлена зависимость используя флаги:

  • -P, —save-prod
    установка в dependencies (работает по умолчанию)
  • -D, —save-dev
    установка в devDependencies
  • -O, —save-optional
    установка в optionalDependencies

Если вам нужно установить зависимость в peerDependencies, то придётся сделать это вручную т. к. npm не предусматривает для этого специальной команды. Как вариант, можно сначала установить зависимость в dependencies при помощи команды npm install, а потом перенести ее вручную в peerDependencies, в этом случае вам не придется угадывать свежую версию пакета (если вдруг ваш IDE не поддерживает автоматическую интеграцию с npm).

Конечно, зависимость можно добавить в список и самостоятельно в редакторе кода, но я всегда рекомендую использовать команды npm для добавления зависимостей, т. к. это дает более надежный результат: вы гарантированно получаете последнюю версию нужного пакета и список зависимостей будет корректно отсортирован в лексикографическом порядке (что позволит избежать конфликтов при мерже в Git).

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

Добавление зависимости старой версии

Если по какой-то причине вы хотите добавить зависимость не самой свежей версии, то вы можете указать нужную версию через символ «@»:

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

Установка зависимостей

Выше мы рассмотрели варианты добавления зависимостей в проект, но как установить зависимости, которые уже прописаны в манифесте, если вы к примеру только сделали git clone?

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

Существует возможность установить только одну категорию зависимостей:

  • —only=prod[uction]
  • —only=dev[elopment]

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

Просмотр установленных зависимостей

Прежде чем мы поговорим про обновление зависимостей было бы полезно научиться просматривать их. Для этой цели в npm также предусмотрена специальная команда: npm ls.

Синтаксис команды выглядит следующим образом: npm ls [] , где это опциональное название пакета, который вы хотите найти в дереве зависимостей.

Если вызвать команду без аргументов, то она выведет полное дерево зависимостей (не ослепните, дерево может быть огромным):

Крошечная порция результата выдачи команды npm ls в большом проекте.

Иногда бывает необходимо найти ту или иную транзитивную зависимость в дереве проекта, чтобы понять какие пакеты «тянут» ее, для этого можно передать название пакета в команду: npm ls lodash .

Результат поиска пакета lodash в дереве зависимостей крупного проекта при помощи команды npm ls lodash.

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

npm ls --depth=0

Как вы уже догадались, по умолчанию команда работает со всем деревом целиком.

Также вы можете использовать опции dev или prod для того, чтобы вывести только зависимости из полей dependencies или devDependencies:

  • npm ls —dev[elopment]
  • npm ls —prod[uction]

Использование же опции json позволяет получить дерево зависимостей в формате пригодном для машинной обработки, в этом режиме npm выводит более подробную информацию о пакетах, а не только название и версию. Данный режим может быть также полезен для отладки и сравнения двух деревьев (например в разных ветках проекта):

npm ls --json

Обновление зависимостей

Как мы уже рассмотрели в предыдущем посте в npm для управления зависимостями используется система семантического версионирования (semver). Благодаря ей вы можете обновлять зависимости в своем проекте с предсказуемыми результатами: к примеру, если зависимость обновилась с версии 1.2.3 до версии 1.2.4 (patch update) или 1.3.0 (minor update), то это не сломает ваш проект, т. к. по правилам semver такие обновления не должны нарушать обратной совместимости. А если обновление производится с версии 1.2.3 до версии 2.0.0 или выше, то здесь вам следует обязательно заглянуть в журнал изменений (changelog) данного пакета, чтобы убедиться, что обновление ничего не сломает, возможно вам придется внести изменения в свой код, чтобы восстановить совместимость.

Несмотря на то, что semver гарантирует достаточно высокий уровень безопасности при обновлении, к сожалению, бывают случаи когда разработчики какого-то пакета могут нарушать правила и вносить критические изменения в patch или minor обновлениях (в первую очередь это касается непопулярных пакетов, которыми управляют менее опытные разработчики).

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

Версии зависимостей

Давайте теперь рассмотрим как именно прописываются версии зависимостей в манифесте проекта и какие механизмы дает нам semver для управления процессом обновления. Как я уже упомянул выше, при установке зависимости npm автоматически устанавливает самую свежую версию и включает наиболее свободный режим обновления для данной зависимости: разрешает как patch, так и minor обновления.

В package.json это выглядит следующим образом:

Символ «^» (caret, hat или «крышечка») указывается перед номером версии и имеет специальный смысл в semver. В данном случае это означает, что версия зависимости lodash должна обновляться до максимально доступной, но не выше 5.0.0 , т. е. разрешает patch и minor обновления, но запрещает обновления нарушающие обратную совместимость.

Помимо крышечки существует еще довольно много способов задать диапазон версии, все их можно посмотреть в описании пакета semver, который и реализует данный функционал в npm, однако в 99% случаев зависимости стоит указывать именно через крышечку (как делает npm по умолчанию), т. к. это дает наибольшую гибкость при обновлении зависимостей и в то же время защищает вас от критических изменений.

Фиксация версий зависимостей

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

Это гарантирует, что lodash будет установлен в ваш проект именно версии 4.17.17 , ни больше, ни меньше.

Однако фиксация версий зависимостей вызывает ряд существенных недостатков:

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

По этим причинам использовать фиксацию зависимостей нужно в очень редких исключительных случаях и только в качестве временной меры.

Одним из случаев, когда фиксирование зависимости является оправданным — это при использовании нестабильных версий (начинающихся с нуля). Такие зависимости я бы всегда рекомендовал прописывать фиксированно, т. к. семантика обновления для нестабильных зависимостей не столь понятна, а ответственность авторов значительно ниже.

Просмотр устаревших зависимостей

Новые версии пакетов регулярно выходят, по этой причине, пакеты, установленные в вашем проекте могут устаревать и их необходимо регулярно обновлять. Команда npm outdated позволяет вам вывести список устаревших пакетов.

Результат команды npm outdated в проекте, где установлены две устаревшие зависимости.

Данная команды выводит таблицу со следующими колонками:

Колонка Описание
Package Название пакета
Current Текущая установленная версия
Wanted Максимальная версия, которая удовлетворяет диапазону semver прописанному в манифесте проекта
Latest Версия пакета, которую автор указал в качестве самой свежей (как правило максимально доступная версия пакета)
Location Место расположения зависимости в дереве

По умолчанию команда npm outdated выводит список прямых зависимостей вашего пакета, однако, если использовать аргумент depth с указанием глубины просмотра, то npm покажет устаревшие зависимости, в том числе и на заданной глубине дерева зависимости:

npm outdated --depth=10

Чтобы просмотреть полный список всех устаревших зависимостей можно использовать следующую команду:

npm outdated --depth=9999

Обновление устаревших зависимостей

Фактическое обновление устаревших зависимостей в npm производится при помощи команды npm update.

Данная команда проверяет версии установленных зависимостей по отношению к версиям доступным в npm registry учитывая диапазоны версий semver указанных в манифесте вашего проекта. Если установленная версия того или иного пакета в вашем проекте отличается от максимальной версии доступной в registry (учитывая ограничение semver), то более свежая версия будет загружена и установлена, а манифест будет обновлен, чтобы минимальная версия в диапазоне соответствовала установленной. Важно заметить, что весь этот процесс протекает без нарушения semver, т. е. вызов npm update никогда не приведет к нарушению диапазонов версий, указанных в вашем манифесте.

Приведем пример: допустим в вашем проекте указан следующий диапазон версий пакета lodash: ^4.16.4 . Вызов npm update приведет к тому, что пакет будет обновлен до версии 4.17.19 , а манифест будет автоматически изменен чтобы содержать следующий диапазон: ^4.17.19 .

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

npm update --depth=9999

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

npm-check

В качестве альтернативы командам npm outdated и npm update хочу предложить интересный инструмент под названием npm-check.

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

npm i -g npm-check

Данный инструмент поддерживает интерактивный режим, позволяя вам выбрать галочками те пакеты, которые вы хотите обновить. Кроме того, он позволяет обновлять пакеты не только в рамках ограничений semver, но и игнорируя их, перепрыгивая с одной мажорной версии зависимости на другую. Разумеется делать это нужно осмысленно: тщательно изучая журнал изменений каждого мажорно-обновляемого пакета на наличие нарушений обратной совместимости. И никогда не забывайте тестировать ваш код после любых обновлений!

Результат вызова npm-check в проекте: доступно два обновления, одно мажорное и одно минорное.

Также результат вызова npm-check, но уже в интерактивном режиме: галочками можно выбрать зависимости, которые вы хотите обновить.

В качестве очень полезного бонуса — npm-check позволяет обнаружить, если какая-то из зависимостей не используется в проекте:

npm-check сообщает о том, что пакет lodash возможно не используется в проекте.

Рекомендую всегда держать этот незаменимый инструмент (или аналогичный) в своем арсенале.

Удаление зависимостей

Ну и наконец, давайте рассмотрим как мы можем удалять ранее добавленные в проект зависимости. Для этого существует команда npm uninstall или сокращенно: rm , r или un . Чтобы удалить один или несколько пакетов, мы можем вызвать команду следующим образом:

npm rm lodash express

Данная команда удалит указанные пакеты как из файловой системы проекта, так и из его манифеста.

Workflow работы с npm-проектом

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

  • Инициализация проекта:
    • npm init
      (интерактивно)
    • npm init -y
      (с последующим редактированием в IDE)
    • npm install
    • npm install …
    • npm install -D …
    • npm outdated
      (просмотр прямых устаревших зависимостей)
    • npm outdated —depth=9999
      (просмотр всех устаревших зависимостей)
    • npm update
      (обновление прямых устаревших зависимостей с учетом semver)
    • npm update —depth=9999
      (обновление всех устаревших зависимостей с учетом semver)
    • npm-check
      (просмотр прямых устаревших зависимостей)
    • npm-check -u
      (интерактивное обновление прямых устаревших зависимостей)
    • npm rm

    Продолжение следует

    В данном посте мы более подробно рассмотрели процесс инициализации проекта, добавления, установки и обновления зависимостей. Рассмотрели как semver работает на практике при обновлении зависимостей.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *