Руководство по Node.js, часть 5: npm и npx

в 9:00, , рубрики: javascript, node.js, Блог компании RUVDS.com, обучение, разработка, Разработка веб-сайтов

Сегодня, в пятой части перевода руководства по Node.js, мы завершим разбор возможностей npm, в частности, коснёмся таких вопросов, как выяснение установленных версий npm-пакетов, установка старых версий пакетов, обновление зависимостей, локальная и глобальная деинсталляция пакетов. Здесь же мы поговорим и об npx.

Руководство по Node.js, часть 5: npm и npx - 1

Выяснение версий установленных npm-пакетов

Для того чтобы узнать версии всех установленных в папке проекта npm-пакетов, включая их зависимости, выполните следующую команду:

npm list

В результате, например, может получиться следующее:

> npm list
/Users/flavio/dev/node/cowsay
└─┬ cowsay@1.3.1
  ├── get-stdin@5.0.1
  ├─┬ optimist@0.6.1
  │ ├── minimist@0.0.10
  │ └── wordwrap@0.0.3
  ├─┬ string-width@2.1.1
  │ ├── is-fullwidth-code-point@2.0.0
  │ └─┬ strip-ansi@4.0.0
  │   └── ansi-regex@3.0.0
  └── strip-eof@1.0.0

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

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

npm list -g

Вывести только сведения о локальных пакетах верхнего уровня (то есть, тех, которые вы устанавливали самостоятельно и которые перечислены в package.json) можно так:

npm list --depth=0

В результате, если, например, устанавливали вы только пакет cowsay, выведено будет следующее:

> npm list --depth=0
/Users/flavio/dev/node/cowsay
└── cowsay@1.3.1

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

npm list cowsay

В результате её выполнения получится примерно следующее:

> npm list cowsay
/Users/flavio/dev/node/cowsay
└── cowsay@1.3.1

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

> npm list minimist
/Users/flavio/dev/node/cowsay
└─┬ cowsay@1.3.1
  └─┬ optimist@0.6.1
    └── minimist@0.0.10

Запись о пакете-зависимости в этой структуре будет выделена.

Если вы хотите узнать о том, каков номер самой свежей версии некоего пакета, доступного в npm-репозитории, вам понадобится команда следующего вида:

npm view [package_name] version

В ответ она выдаёт номер версии пакета:

> npm view cowsay version
1.3.1

Установка старых версий npm-пакетов

Установка старой версии npm-пакета может понадобиться для решения проблем совместимости. Установить нужную версию пакета из npm можно, воспользовавшись следующей конструкцией:

npm install <package>@<version>

В случае с используемым нами в качестве примера пакетом cowsay, команда npm install cowsay установит его самую свежую версию (1.3.1 на момент написания этого материала). Если же надо установить его версию 1.2.0, воспользуемся такой командой:

npm install cowsay@1.2.0

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

npm install -g webpack@4.16.4

Если вам понадобится узнать о том, какие версии некоего пакета имеются в npm, сделать это можно с помощью такой конструкции:

npm view <package> versions

Вот пример результата её работы:

> npm view cowsay versions
[ '1.0.0',
  '1.0.1',
  '1.0.2',
  '1.0.3',
  '1.1.0',
  '1.1.1',
  '1.1.2',
  '1.1.3',
  '1.1.4',
  '1.1.5',
  '1.1.6',
  '1.1.7',
  '1.1.8',
  '1.1.9',
  '1.2.0',
  '1.2.1',
  '1.3.0',
  '1.3.1' ]

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

Когда вы устанавливаете пакет командой вида npm install <packagename>, из репозитория загружается самая свежая из доступных версий и помещается в папку node_modules. При этом соответствующие записи добавляются в файлы package.json и package-lock.json, находящиеся в папке проекта.

Кроме того, устанавливая некий пакет, npm находит и устанавливает его зависимости.

Предположим, мы устанавливаем уже знакомый вам пакет cowsay, выполняя команду npm install cowsay. Пакет будет установлен в папку node_modules проекта, а в файл package.json попадёт следующая запись:

{
  "dependencies": {
    "cowsay": "^1.3.1"
  }
}

В package-lock.json так же будут внесены сведения об этом пакете. Вот его фрагмент:

{
  "requires": true,
  "lockfileVersion": 1,
  "dependencies": {
    "cowsay": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz",
      "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkMAjufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==",
      "requires": {
        "get-stdin": "^5.0.1",
        "optimist": "~0.6.1",
        "string-width": "~2.1.1",
        "strip-eof": "^1.0.0"
      }
    }
  }
}

Из этих двух файлов можно узнать, что мы установили cowsay версии 1.3.1, и то, что правило обновления пакета указано в виде ^1.3.1. В четвёртой части этой серии материалов мы уже говорили о правилах семантического версионирования. Напомним, что такая запись означает, что npm может обновлять пакет при выходе его минорных и патч-версий.

Если, например, выходит новая минорная версия пакета и мы выполняем команду npm update, то обновляется установленная версия пакета и при этом сведения об установленном пакете обновляются в файле package-lock.json, а файл package.json остаётся неизменным.

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

npm outdated

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

Руководство по Node.js, часть 5: npm и npx - 2

Анализ устаревших зависимостей проекта

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

Для того чтобы обновиться до новых мажорных версий всех используемых пакетов, глобально установите пакет npm-check-updates:

npm install -g npm-check-updates

Затем запустите утилиту, предоставляемую им:

ncu -u

Эта команда обновит файл package.json, внеся изменения в указания о подходящих версиях пакетов в разделы dependencies и devDependencies. Это позволит npm обновить пакеты, используемые в проекте, до новых мажорных версий после запуска команды npm update.

Если вы хотите установить самые свежие версии пакетов для только что только что загруженного проекта, в котором пока нет папки node_modules, то, вместо npm update, выполните команду npm install.

Локальная или глобальная деинсталляция пакетов

Для того чтобы деинсталлировать пакет, ранее установленный локально (с использованием команды install <package-name>), выполните команду следующего вида:

npm uninstall <package-name>

Если пакет установлен глобально, то для его удаления нужно будет воспользоваться флагом -g (--global). Например, подобная команда может выглядеть так:

npm uninstall -g webpack

При выполнении подобной команды текущая папка значения не имеет.

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

Когда и почему пакеты лучше всего устанавливать глобально? Для того чтобы ответить на этот вопрос, вспомним о том, чем различаются локальная и глобальная установка пакетов:

  • Локальные пакеты устанавливаются в директорию, в которой выполняют команду вида npm install <package-name>. Такие пакеты размещаются в папке node_modules, находящейся в этой директории.
  • Глобальные пакеты устанавливаются в особую папку (в какую точно — зависит от конкретных настроек вашей системы) вне зависимости от того, где именно выполняют команду вида npm install -g <package-name>.

Подключение локальных и глобальных пакетов в коде осуществляется одинаково:

require('package-name')

Итак, какой же способ установки пакетов лучше всего использовать?

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

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

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

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

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

  • npm
  • create-react-app
  • vue-cli
  • grunt-cli
  • mocha
  • react-native-cli
  • gatsby-cli
  • forever
  • nodemon

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

npm list -g --depth 0

О зависимостях проектов

Когда пакет следует рассматривать как обычную зависимость проекта, необходимую для обеспечения его функционирования, а когда — как зависимость разработки?

При установке пакета с помощью команды вида npm install <package-name> он устанавливается как обычная зависимость. Запись о таком пакете делается в разделе dependencies файла package.json (до выхода npm 5 такая запись делалась только при использовании флага --save, теперь использовать его для этого необязательно).

Использование флага --save-dev позволяет установить пакет как зависимость разработки. Запись о нём при этом делается в разделе devDependencies файла package.json.

Зависимости разработки — это пакеты, которые нужны в процессе разработки проекта, в ходе его обычного функционирования они не требуются. К таким пакетам относятся, например инструменты тестирования, Webpack, Babel.

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

Поэтому, если пакет требуется развернуть в продакшне, то, при его развёртывании, нужно использовать команду npm install --production. Благодаря флагу --production зависимости разработки устанавливаться не будут.

Утилита npx

Сейчас мы поговорим об одной весьма мощной команде, npx, которая появилась в npm 5.2. Одной из её возможностей является запуск исполняемых файлов, входящих в состав npm-пакетов. Мы уже рассматривали использование npx для запуска подобного файла из пакета cowsay. Теперь поговорим об этом подробнее.

▍Использование npx для упрощения запуска локальных команд

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

Применение команды вида npx commandname приводит к автоматическому поиску нужного файла в папке проекта node_modules. Это избавляет от необходимости знания точного пути к подобному файлу. Так же это делает ненужной глобальную установку пакета с обеспечением доступа к нему из любого места файловой системы благодаря использованию системной переменной PATH.

▍Выполнение утилит без необходимости их установки

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

  • Не требуется установка утилит.
  • Можно запускать разные версии одних и тех же утилит, указывая нужную версию с помощью конструкции @version.

Посмотрим на то, как пользоваться этим механизмом, на примере уже известной вам утилиты cowsay. Так, если пакет cowsay установлен глобально, выполнение в командной строке команды cowsay "Hello" приведёт к выводу в консоль «говорящей» коровы:

_______
< Hello >
 -------
           ^__^
           (oo)_______
            (__)       )/
                ||----w |
                ||     ||

Если же пакет cowsay не будет установлен глобально, подобная команда выдаст ошибку.

Утилита npx позволяет выполнять подобные команды без их установки. Выглядит это, в рамках нашего примера, так:

npx cowsay "Hello"

Такая команда сработает, но, хотя «говорящая» корова, по большому счёту, особой пользы не приносит, тот же самый подход можно использовать и для выполнения куда более полезных команд. Вот несколько примеров:

  • Существует инструмент командной строки, предназначенный для создания и запуска Vue-приложений. С использованием npx его можно вызвать так: npx vue create my-vue-app.
  • Для создания React-приложений можно пользоваться утилитой create-react-app. Её вызов через npx выглядит так: npx create-react-app my-react-app.

После загрузки и использования соответствующего кода npx его удалит.

▍Запуск JavaScript-кода с использованием различных версий Node.js

Для того чтобы запускать некий код с использованием разных версий Node.js, можно, с использованием npx, обращаться к npm-пакету node, указывая его версию. Выглядит это так:

npx node@6 -v #v6.14.3
npx node@8 -v #v8.11.3

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

▍Запуск произвольных фрагментов кода, доступных по некоему адресу

Npx позволяет запускать не только код, опубликованный в npm. В частности, если у вас есть ссылка на некий фрагмент кода (скажем, опубликованного на GitHub gist), запустить его можно так:

npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32

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

▍Итоги

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

В следующий раз мы обсудим некоторые базовые механизмы Node.js, понимание которых необходимо для успешной разработки приложений для этой платформы.

Уважаемые читатели! Пользуетесь ли вы npx?

Руководство по Node.js, часть 5: npm и npx - 3

Автор: ru_vds

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js