Що насправді робить npm install: реєстр, package.json та файли Lockfile
Практичний огляд npm: реєстр та CLI, як npm install завантажує пакети, що записується у file package.json та package-lock.json, та як публікувати пакети.
Майже кожний проект на JavaScript, незалежно від того, чи працює він на Node.js, React чи Next.js, починається з однакової команди, і багато розробників виконують її щодня, не розуміючи точно, що вона робить. Знання того, звідки беруться пакети, як npm вирішує, що інсталювати, та для чого саме призначені файли package.json, package-lock.json та node_modules, допомагає легше відловлювати проблеми під час інсталяції. Цей посібник охоплює кожен етап — від першої інсталяції до публікації власного пакету.
Команди, які вводить кожен
Найпоширенішим способом є інсталяція всього, що вже оголошено у проекті:
npm install
Не менш поширеним є додавання бібліотеки за назвою, наприклад веб-фреймворку Express:
npm install express
або HTTP-клієнта Axios:
npm install axios
За цими однорядковими командами криється кілька запитань. Звідки завантажується код? Як npm дізнається, від чого залежить проект? Для чого існує package.json? І чому папка node_modules стає такою великою?
Що таке npm
npm — це стандартний менеджер пакетів для Node.js, який постачається разом із ним. Він дає вам доступ до величезного каталогу повторно використовуваних пакетів, опублікованих іншими розробниками, що дозволяє використовувати перевірений код у вашому проекті замість того, щоб писати його самостійно.
Уявіть собі це як публічну бібліотеку коду. Припустимо, що бекенд на Node.js потребує HTTP-сервера. Замість того, щоб створювати маршрутизацію та проміжні компоненти з нуля, ви додаєте Express:
npm install express
Потрібно викликати інші API? Додайте HTTP-клієнта:
npm install axios
Перевірку надходящих даних за схемою здійснює Zod:
npm install zod
А bcrypt займається хешируванням паролів:
npm install bcrypt
Це найбільша перевага екосистеми: коли існує добре протестоване рішення, рідко буває причина писати власне. З іншого боку, кожен встановлений пакет — це код, якому ви довіряєте, тож краще використовувати підтримувані, широко поширені бібліотеки та тримати список мінімальним. Дізнайтеся як працюють атаки на ланцюг постачання npm, щоб зрозуміти, чому це важливо.
Екосистема, а не просто команда
Початківці часто сприймають npm як просто слово, введене в термінал. Насправді ця назва охоплює кілька взаємодіючих компонентів:
- Реєстр npm: публічна служба, де пакети публікуються та завантажуються.
- CLI npm: інструмент командного рядка, який взаємодіє з реєстром та керує залежностями.
package.json: маніфест, який описує ваш проект та залежності від нього.Публічні пакети є безкоштовними: ви можете встановити будь-який публічний пакет без облікового запису. Ця низька бар’єрна стінка допомогла JavaScript з відкритим кодом поширитися по всьому світу. Обліковий запис потрібен лише для публікації.
Що відбувається, коли ви запускаєте npm install
Візьмемо проект, який додає Express:
npm install express
На високому рівні:
- npm шукає пакет у реєстрі та обирає версію, яка відповідає запитаному діапазону (найновішу, якщо жоден не вказаний).
- Він розв’язує залежності самого пакета та його залежностей, утворюючи повну ієрархію.
- Він завантажує все, що ще не зберігається в кеші, та розміщує його у
node_modules.
package.json та точну структуру, яка була вирішена, у package-lock.json.Саме так один короткий командний запит дозволяє отримати цілу структуру функціональностей.
package.json: маніфест проекту
У центрі кожного проекту Node.js знаходиться один файл:
package.json
Він виконує роль посвідчення особи та конфігурації проекту в одному, містячи назву, версію, опис, скрипти, залежності для роботи та розробки, а також дані автора. Мінімальний приклад вказує файл-вхід у main, один скрипт та одну залежність:
{
"name": "my-project",
"version": "1.0.0",
"description": "My Node.js application",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^5.1.0"
}
}
name
name ідентифікує проект чи пакет. Якщо ви його публікуєте, саме цей текст люди вводять для його встановлення, тому він має бути унікальним у реєстрі.
"name": "my-project"
version
version містить поточну версію пакета.
"version": "1.0.0"
Це має найбільше значення під час публікації. npm використовує семантичне версіонування (MAJOR.MINOR.PATCH): кардинальні зміни підвищують номер мажорної версії, сумісні функції — номер мінорної, а виправлення — номер патч-версії.
Опис
description — це однорядковий огляд того, що робить проект, який відображається у результатах пошуку в реєстрі.
"description": "My Node.js application"
Скрипти
scripts визначає іменовані скорочення для часто використовуваних команд. Тут start запускає основний файл:
"scripts": {
"start": "node index.js"
}
Без нього доводилося б вводити повну команду:
node index.js
З ним це робить те саме:
npm start
Ключова риса — це послідовність: кожен учасник та кожна робота CI виконують однакову іменовану команду. Власні назви, такі як build, виконуються за допомогою npm run build.
Залежності: від чого залежить ваш проект
Уявіть собі платформу для доставки їжі. Її бекенд може використовувати:
- Express для API
- Zod для перевірки даних
- bcrypt для хеширування паролів
- бібліотеку JSON Web Token для автентифікації
- Mongoose для роботи з MongoDB
Кожен з цих елементів є залежністю. Коли ви встановлюєте одну з них:
npm install express
npm додає запис до package.json:
"dependencies": {
"express": "^5.1.0"
}
Знак „^“ у ^5.1.0 позначає діапазон: приймаються всі наступні версії 5.x, але не 6.0.0. Цей запис повідомляє всім, хто читає проект, що для його роботи потрібен Express. Инструменти, необхідні лише під час розробки, такі як тест-запускачі, додаються до devDependencies за допомогою команди npm install --save-dev.
Чому одна команда може працювати для цілої команди
Припустимо, ви приєднуєтесь до команди та клонуєте її репозиторій. Ніхто не очікує, що ви вручну завантажите п’ятдесят бібліотек. Ви виконуєте:
npm install
npm читає вказані залежності та встановлює їх усі. Саме завдяки можливості відтворення робочого середовища на основі опису менеджери пакетів є незамінними.
node_modules: де знаходиться встановлений код
Після встановлення з’являється нова папка:
node_modules/
У ній знаходяться пакети, які ви запитали, а також усе, від чого вони залежать, через що ця папка стає великою. Типова структура:
my-project/
│
├── node_modules/
├── package.json
├── package-lock.json
└── index.js
Не керуйте node_modules у Git. Він є великим, може містити версії коду для конкретних платформ, і його завжди можна відтворити. Додайте його до .gitignore та керуйте цими файлами замість нього:
package.json
package-lock.json
Інші користувачі можуть потім запустити:
npm install
та отримати ті самі залежності.
package-lock.json: точний запис
Поруч із основним файлом знаходиться ще один файл:
package-lock.json
Чому обидва? Коротка версія:
package.jsonвказує, що потрібно проекту, зазвичай у вигляді діапазонів.package-lock.jsonфіксує саме те, що було встановлено: кожну версію пакета в усій структурі, а також хеші цілісності.
npm ci у системах CI, який встановлює програми строго згідно з файлом lockfile.
Команди npm, які варто знати
Додати пакет:
npm install express
Встановити все, що оголошено у проекті:
npm install
Видалити пакет з node_modules та package.json:
npm uninstall express
Оновити пакети до найновіших версій, дозволених діапазонами (це не призведе до переходу на нову мажорну версію):
npm update
Виведіть версію npm:
npm -v
Виведіть версію Node.js:
node -v
Покажіть обліковий запис npm, під яким ви увійшли:
npm whoami
Ви також можете внести вклад у створення пакетів. Опублікуйте корисну бібліотеку, і інші зможуть встановити її як будь-яку іншу:
npm install your-package
Цей цикл підтримує життя відкритого коду: ви будуєте на роботі інших, створюєте власні рішення та ділитеся ними.
Кроки публікації
Вам потрібен обліковий запис npm. Увійдіть через термінал:
npm login
Підтвердіть, який обліковий запис є активним:
npm whoami
Перейдіть у проект:
cd myproject
Переконайтеся, що в ньому є дійсний маніфест із унікальним name та version:
package.json
Потім опублікуйте:
npm publish
Тепер цей пакет доступний усім. Два поради: спочатку виконайте npm pack --dry-run, щоб побачити, які файли будуть включені, та завжди збільшуйте version після кожного випуску, адже опублікована версія не може бути використана знову. Ознайомтесь із поточною документацією npm щодо вимог до безпеки облікових записів, таких як двофакторна автентифікація.
Як усе взаємопов’язано
Весь процес виглядає так:
Developer
↓
npm install
↓
npm Registry
↓
Package + Dependencies
↓
node_modules
↓
package.json
↓
Your Application
Ви виконуєте команду, CLI отримує пакети з реєстру, код потрапляє до node_modules, маніфест та файл lockfile фіксують це, а ваше застосунок імпортує його. Саме ця ланцюгова структура дозволяє розробникам ефективно використовувати, керувати, ділитися та публікувати код.
Основні висновки
NPM може здаватися набором команд терміналу, але як тільки ви зрозумієте, що відбувається за кожною з них:
npm install
Система стає простою для розуміння. JavaScript забезпечує мову, Node.js — середовище виконання, а npm — екосистему для обміну кодом. На практиці:
package.jsonописує наміри;package-lock.jsonфіксує факти. Зберігайте обидва файли.- Ніколи не зберігайте
node_modules. - Діапазон кершнів дозволяє виконувати незначні та коригувальні оновлення, причому
npm updateзалишається в межах цього діапазону. - Для автоматизованих встановлень використовуйте
npm ci. - Додавайте залежності усвідомлено; кожна з них — це код, якому ви довіряєте.
Тож наступного разу, коли ви будете писати:
npm install
пам’ятайте, що ви підключаєте свій проект до екосистеми, створеної розробниками з усього світу.
Пов’язана література
- Що JSON.stringify мовчки видаляє, перетворює та відмовляється серіалізувати — Дізнайтеся, які значення JavaScript JSON.stringify ігнорує або змінює, як toJSON, замінники та функції відновлення це виправляють, та коли structuredClone є кращим інструментом.
- Що насправді гарантує async/await та що залишає для вас — Зрозумійте, що насправді призупиняє await, як уникнути серіалізованих запитів, та чому для обробки помилок, скасувань, порядку виконання та повторних спроб потрібні рішення, що виходять за межі async/await.