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

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

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

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

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

Зависимости

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

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

hexlet-js$ 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 ci.

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

Связь с GIT

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

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

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

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

Эта команда ничего не меняет в проекте. Она только лишь скачивает зависимости в директорию node_modules базируясь на содержимом package.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 была исключен из отслеживания
  6. Изучите структуру директории node_modules
  7. Найдите исходники пакета lodash на гитхабе и сравните с содержимым node_modules

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

  1. Поиск пакетов
  2. Библиотека или свое решение

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

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

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

Зарегистрироваться

или войти в аккаунт

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

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Нажимая кнопку «Зарегистрироваться», вы даёте своё согласие на обработку персональных данных в соответствии с «Политикой конфиденциальности» и соглашаетесь с «Условиями оказания услуг». Защита от спама reCAPTCHA «Конфиденциальность» и «Условия использования».

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

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

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

Нажимая кнопку «Зарегистрироваться», вы даёте своё согласие на обработку персональных данных в соответствии с «Политикой конфиденциальности» и соглашаетесь с «Условиями оказания услуг». Защита от спама reCAPTCHA «Конфиденциальность» и «Условия использования».