Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Зависимости JS: Настройка окружения

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

// Пример встроенной функции
Math.round(5.34); // 5

// Встроенный в Node.js модуль для работы с файлами
import fs from "fs";

// Читает содержимое файла
const data = fs.readFileSync("path/to/file");

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

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

Какие задачи решают подобные пакеты? Совершенно разные. От небольших полезных функций для работы со строками или датами, до фреймворков, программных систем, формирующих архитектуру кода. Например, в JavaScript невероятно популярна библиотека lodash. Она предоставляет около сотни полезных функций, решающих типовые задачи по работе с массивами, строками и другими типами данных. Пара примеров:

// По общепринятому соглашению, lodash импортируется под именем _
import _ from "lodash";

// Пересечение массивов
_.intersection([2, 1], [2, 3]); // => [2]

// capitalize делает первую букву заглавной
_.capitalize("hello"); // Hello

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

Обратите внимание на то, как происходит импорт кода из внешних библиотек. В этом случае имя пакета указывается без указания пути ./. Так JavaScript понимает, что это именно пакет и не нужно искать файл с именем lodash.js.

// Так будет происходить поиск файла lodash.js в текущей директории
import _ from "./lodash";

// Так импортируется код из пакета
import _ from "lodash";

Установка

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

# Обязательно выполнять в корне проекта
# только тогда lodash будет лежать в правильном месте
npm install lodash

Эта команда выполняет три действия. Сначала она скачивает пакет из NPM-хранилища в директорию node_modules в корне проекта. Если этой директории не было, то она автоматически создается. Затем она добавляет запись в package.json о том, что пакет lodash стал зависимостью. И наконец, создает или обновляет файл package-lock.json.

tree -L 1
.
├── node_modules
├── package.json
├── package-lock.json
└── index.js

Зависимости в package.json добавляются под ключом dependencies. Здесь указаны все пакеты, используемые в проекте и не входящие в стандартную библиотеку.

"dependencies": {
  "lodash": "^4.17.15"
}

В качестве ключа в зависимостях указывается имя пакета. Именно это имя используется при импорте пакета. Значением является последняя доступная версия на момент скачивания.

Теперь, когда Node.js встречает подобный импорт:

import React from "react";

Происходит попытка импортировать модуль из node_modules/react/...

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

Если кратко, то у зависимостей нашего проекта есть свои зависимости, а у них, в свою очередь, свои зависимости (зависимости зависимостей называются транзитивными зависимостями). Подобная цепочка может быть довольно длинной и на разных её участках возможно появление одних и тех же пакетов, но разных версий. package-lock.json содержит описание всех пакетов, которые будут поставлены, включая все их зависимости с указанием конкретных версий. Это позволяет получать гарантированно одни и те же версии зависимостей для всех разработчиков проекта. Этот файл создаётся командой npm install и потом используется при установке зависимостей. При наличии package-lock.json в проекте, установку зависимостей рекомендуется выполнять командой npm ci

# Если мы хотим в точности те же версии всех пакетов,
# какие были у остальных разработчиков этого проекта
npm ci

Связь с GIT

Программисты не так часто делают проекты "с нуля". Чаще всего они работают с готовыми проектами. Проекты же, в свою очередь, хранятся в git-репозиториях. Что нужно хранить в репозитории, а что нет, когда мы говорим о зависимостях?

Код самих зависимостей не является частью исходного кода. Его всегда добавляют в .gitignore. А вот файлы package.json и package-lock.json являются частью исходного кода и именно через них Node.js узнает о том, какие пакеты нужно поставить в систему.

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

# Выполняется в корне проекта
# Устанавливает все указанные зависимости
npm ci

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

Предупреждения

Во время установки зависимостей npm выводит много разных сообщений. Среди них встречаются такие:

npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue

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


Самостоятельная работа

  1. Установите в проект hexlet-js пакет lodash
  2. Добавьте в файл index.js импорт функций из пакета lodash как в примерах выше
  3. Добавьте в файл index.js строчку console.log(_.last(['one', 'two']));
  4. Запустите код, убедитесь что выводится "two"
  5. Добавьте изменения на гитхаб. Проследите, чтобы node_modules была исключенa из отслеживания
  6. Изучите структуру директории node_modules
  7. Найдите исходники пакета lodash на гитхабе и сравните с содержимым node_modules

Дополнительные материалы

  1. Поиск пакетов
  2. Библиотека или свое решение
  3. Отличие npm ci от npm install

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

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

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

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

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
25 мая 10 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
25 мая 10 месяцев
Иконка программы Верстальщик
Профессия
Вёрстка с использованием последних стандартов CSS
в любое время 5 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
25 мая 16 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»