Файл package.json и конфигурация проекта

Последнее обновление: 22.11.2023

Файл package.json

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

Так, возьмем ранее созданный файл package.json (или создадим заново с нуля) и определим в нем следующее содержимое:

{
  "name": "helloapp",
  "version": "1.0.0",
  "dependencies": {
    "lodash": "4.17.21",
    "express": "^4.18.2"
  }
}

Здесь определены три секции:

  • name: имя проекта. Оно может быть произвольным. В данном случае проект называется "helloapp".

  • version: версия проекта. Начнем с версии 1.0.0

  • dependencies: секция зависимостей - тех пакетов, которые мы собираемся использовать и которые будут установлены в проект. Зависимости задаются в виде объекта, где название каждого свойства представляет имя проекта, а значение - его версию. То есть в данном случае мы будем устанавливать два пакета: "lodash" версии "4.17.21" и "express" версии "4.18.2". Lodash представляет библиотеку для работы с данными, в частности, с массивами, а express представляет легковесный веб-фреймворк для упрощения создания веб-приложений.

    В качестве альтернативы зависимости можно помещать также в секцию "devDependencies". Однако обычно в секцию "devDependencies" помещаются пакеты, которые применяются при построении приложения, в в секцию "dependencies" - пакеты, которые применяются при выполнении приложения.

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

  • name: имя пакета

  • version: версия пакета.

  • description: описание пакета

  • main: главный файл, с которого начинается выполнение

  • keywords: массив ключевых слов. Эти ключевые слова могут использоваться при поиске по репозиторию npm.

  • homepage: адрес домашней страницы проекта

  • license: лицензия пакета

  • author: автор пакета. Если авторов несколько, то указывается главный. Сведения об авторе включают имя. Также дополнительно можно указать email и адрес домашней страницы в сети.

  • contributors: массив, который содержит дополнительных авторов (если их несколько).

  • repository: репозиторий исходного кода проекта

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

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

  • os: поддерживаемые операционные системы

Теперь установим пакеты. Для этого в консоли перейдем к папке проекта и выполним команду npm install

c:\app> npm install

added 63 packages, and audited 64 packages in 4s

11 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
c:\app> 

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

После этого в папку node_modules будут установлены оба пакета, а мы сможем использовать их функциональность в приложении. Для примера определим простейшее веб-приложение с помощью Express. (Для упрощения я не буду задействовать lodash, но, кому интересно, пример есть в прошлой статье). Для этого в папке проекта определим файл app.js со следующим кодом:

const express = require("express"); // получаем модуль express
// создаем приложение express
const app = express();

// устанавливаем обработчик для маршрута "/"
app.get("/", function(_, response){

	response.end("Hello METANIT.COM");
});
// начинаем прослушивание подключений на 3000 порту
app.listen(3000, function(){ console.log("Сервер начал принимать запросы по адресу http://localhost:3000")});

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

В Express мы можем связать обработку запросов с определенными маршрутами. Например, "/" - представляет главную страницу или корневой маршрут. Для обработки запроса вызывается функция app.get(). Первый параметр функции - маршрут, а второй - функция, которая будет обрабатывать запрос по этому маршруту. Таким образом, при получении запроса по корневому пути "/" приложение отправит в качестве ответа строку "Hello METANIT.COM".

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

Запустим приложение командой node app.js:

c:\app> node app.js
Сервер начал принимать запросы по адресу http://localhost:3000
c:\app> 

И в адресной строке браузера введем адрес http://localhost:3000/:

Запуск сервера Express на Node.js

Семантическое версионирование

При определении версии пакета применяется семантическое версионирование. Номер версии, как правило, задается в следующем формате "major.minor.patch". Если в приложении или пакете обнаружен какой-то баг и он исправляется, то увеличивается на единицу число "patch". Если в пакет добавляется какая-то новая функциональность, которая совместима с предыдущей версией пакета, то это небольшое изменение, и увеличивается число "minor". Если же в пакет вносятся какие-то большие изменения, которые несовместимы с предыдущей версией, то увеличивается число "major". То есть глядя на разные версии пакетов, мы можем предположить, насколько велики в них различия. Например, возьмем использованную выше версию lodash - "4.17.21":

  • major: 4

  • minor: 17

  • patch: 21

В примере с express версия пакета содержала, кроме того, дополнительный символ карет: "^4.18.2". Символ ^ позволяет выбрать один из патчей в рамках старшей. Так, при установке пакета в проект с помощью команды npm install будет устанавливаться последняя доступная версия от 4.18.2. Фактически это будет последняя доступная версия в промежутке от 4.18.2 до 5.0.0 (>=4.18.2 и <5.0.0). Если со временем последней будет версия 4.27.8, то эта версия будет использоваться (любая последняя до 5-й версии).

В качестве индикатора версии также можно использовать символ ~. Она позволяет выбрать один из патчей в рамках младшей версии. Например, запись "~4.18.2" означает любую последнюю версию в диапазоне от 4.18.2 до 4.19.0 (>=4.18.2 и <4.19.0)

Изменение и удаление пакетов

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

Если нам в принципе надо удалить пакет, то мы можем убрать его из секции "dependencies"/"devDependencies". Например, я решил, что пакет "lodash" мне больше не нужен, в этом случае я убрать определение этого пакета из package.json:

{
  "name": "helloapp",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18.2"
  }
}

И после этого выполнить в консоли команду npm install, а npm выведет сводку по удалению пакета:

c:\app> npm install

removed 1 package, and audited 63 packages in 2s

11 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
c:\app> 

Можно убрать все пакеты из package.json, тогда команда npm install удалит все пакеты. Можно одновременно добавлять одни пакеты и удалять другие.

Также можно сочетать с ручной установкой/удалением пакетов. Например, выполним в консоли команду

npm uninstall express

Будут удалены все пакеты, связанные с express, а файл package.json будет обновлен

{
  "name": "helloapp",
  "version": "1.0.0"
}

Автогенерация файла package.json

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

c:\app> npm init
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: (app) helloapp
version: (1.0.0) 
description: 
entry point: (app.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to c:\app\package.json:

{
  "name": "helloapp",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes) yes
c:\app> 

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

{
  "name": "helloapp",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Команды npm

NPM позволяет определять в файле package.json команды, которые выполняют определенные действия. Например, определим следующий файл app.js:

const name = process.argv[2];
const age = process.argv[3];

console.log("name:", name);
console.log("age:", age);

В данном случае мы получаем переданные при запуске приложению параметры.

И определим следующий файл package.json:

{
  "name": "helloapp",
  "version": "1.0.0",
  "scripts" : {
    "start" : "node app.js",
    "dev" : "node app.js Tom 26",
    "test" : "echo \"Hello METANIT.COM\" && exit 1"
  }
}

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

Первая команда называется start. Она по сути выполняет команду node app.js, которая выполняет код в файле app.js

Вторая команда называется dev. Она также выполняет тот же файл, но при этом также передает ему два параметра.

Третья команда называется test. Она выполняет внутреннюю команду echo, которая выводит строку "Hello METANIT.COM". С помощью символа && можно выполнить еще одну команду - в данном случае это встроенная команда exit, которая завершает выполнение.

Названия команд могут быть произвольными. Но здесь надо учитывать один момент. Есть зарезервированные названия для команд, например, start, test, run и ряд других. Их не очень много. И как раз первая команда из выше определенного файла package.json называется start. И для выполнения подобных команд в терминале/командной строке надо выполнить команду

npm [название_команды]

Например, для запуска команды start

npm start

Для запуска команды test

npm start

Команды с остальными названия, как например, "dev" в вышеопределенном файле, запускаются так:

npm run [название_команды]

Например, последовательно выполним все три команды:

c:\app> npm start  

>  helloapp@1.0.0 start
>  node app.js

name: undefined
age: undefined
c:\app> npm run dev

>  helloapp@1.0.0 dev
>  node app.js Tom 26

name: Tom
age: 26
c:\app> npm test

>  helloapp@1.0.0 test
>  echo "Hello METANIT.COM"

Hello METANIT.COM
c:\app>  
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850