dependencies? devDependencies? peerDependencies?
npm install? npm i? npm ci?
--save? --save-dev? --save-prod? -g?
package.json? package-lock.json? .npmrc?
"module": "^1.0.0"?
"module": "~1.0.0"?
"module": "1.0.0"?
Что из этого можно править руками?
Что из этого в Гит?
Какой командой в итоге билдить?
Актуально для: node -v
— v20.5.0 и npm -v
— 10.2.3
Что предлагает Svelte на старте?
(После npm create svelte@latest my-app
)
- В
package-lock.json
толькоdevDependencies
(без prod-dependencies
):
И все эти зависимости «из коробки» НЕ строгие, т.е. с ^
:
```
"devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.20.4",
"svelte": "^4.0.5",
"vite": "^4.4.2"
},
```
-
.npmrc
(NPM Run Command) с единственной строкойengine-strict=true
.
P.S. package-lock.json
нет вообще (и не надо).
Что рекомендуют разработчики Svelte?
Определиться с адаптером, вместо adapter-auto
.
It's recommended to install the appropriate adapter to your devDependencies once you've settled on a target environment, since this will add the adapter to your lockfile and slightly improve install times on CI.
https://kit.svelte.dev/docs/adapter-auto
Мы люди простые, — возьмём универсальный adapter-node
.
Итак,
Как установить новый модуль?
https://docs.npmjs.com/cli/v10/commands/npm-install
По умолчанию, npm install @sveltejs/adapter-node
— запишет в prod-dependencies
.
Потом, можно перекинуть в devDependencies
путём:
npm install @sveltejs/adapter-auto --save-dev
.
Но, снова вернуть в «prod» той же командой:
npm install @sveltejs/adapter-auto
уже не получится.
Чтобы форсануть обратно в «prod»:
npm install @sveltejs/adapter-auto --save-prod
-
npm install @sveltejs/adapter-auto --save
— такого просто нет (как минимум в npm v10) - Но нода не ругается на несуществующие параметры.
- Более того, ей без разницы —
что так:
npm install module-name --param
, что так:npm install --param module-name
. - А вообще можно и просто
npm i module-name
. - Можно и
npm i module_name -g
, если модуль нужен не для проекта, а как консольная утилита для чего-нибудь.
Но это не то, что нам нужно.
Мы знаем, чем оборачивается «НЕ строгая версия».
Как установить строгую версию?
Есть 4 способа:
-
npm config set save-exact true
Сомнительно, т.к. делает запись где-то глобально, и только на локальной машине.
P.S.
Создаётся на самом деле 2-е переменные вnpm config list
:
save-exact = true
save-prefix = ""
Если вернуть обратно (
npm config set save-exact true
), будет:
save-exact = false
save-prefix = "^"
-
npm install @sveltejs/adapter-auto --save-exact
Делает свою работу, но нам нужна защита от дурака, на всю команду.
Добавить в
.npmrc
>>save-exact=true
.
Т.е., теперь, когда мы делаем npm i module-name
он автоматически будет устанавливать строгую версию, без ^
.
(Тут, никаких save-prefix = ""
не надо, это была внутренняя штука для глобального конфига.)
- Можно руками постирать все
^
, но — тогда у нас окажутся устаревшие пакеты :D.
То, что было вначале пришло в devDependencies
— не совсем свежее.
Но, пока мы ещё ничего не установили, у нас нет ни node_modules/
, ни package-lock.json
— нам ничего не мешает действительно всё прописать руками.
Итого:
- Идём по П.3. — добавляем в
.npmrc
>>save-exact=true
. - Для всего, что видим в
devDependencies
— заного поочерёдно делаемnpm i module-name
. (Они перелетят изdevDependencies
в prod-dependencies
. Пока, тут это нам и нужно.) - Ну и наконец-то устанавливаем наш
adapter-auto
:
npm i @sveltejs/adapter-auto
.
P.S. Устанавливая один модуль — установятся все dependencies
, как если бы мы делали всё это одним npm i
.
А @sveltejs/adapter-auto
можно удалить, чтоб не мешался.
Как удалить модуль?
https://docs.npmjs.com/cli/v10/commands/npm-uninstall
-
npm uninstall @sveltejs/adapter-auto
— удалит в каких бы*Dependencies
они не находились.Раньше нужно было дописывать
--save-dev
и т.д., иначе удалится изnode_modules/
, но не изpackage.json
и т.д.
Сейчас этого нет. Только если прописать в.npmrc
>>save=false
, тогда нужно будет--save
.
Но не вижу во всём этом смысла для общих случаев. -
Можно удалить строку
"@sveltejs/adapter-auto": "^2.0.0",
руками.При этом удалить
node_modules/
иpackage-lock.json
.
И сделатьnpm i
всего проекта заново.
Но, так делать не стоит, когда всё уже в бою.
Это может навредить и серверной сборке, и коллегам, но об этом позже.
Как не захламить prod-dependencies
?
Понятно, что в процессе разработки мы пробуем много разных модулей, которые чаще всего не пойдут на прод.
И, не хотелось бы, чтобы всё ложилось в prod-dependencies
.
Тут выясняется, что возможен ещё какой-то peerDependencies
,
где вообще — у каждого разработчика появляется свой личный блок с модулями:
npm i node_module --save-peer
(--save-peer
не задокументирован, но работает. https://stackoverflow.com/a/74549787/4117781)
Пропустил я эту команду, и получил что-то новое — звёздочку! в devDependencies
:
"devDependencies": {
"@sveltejs/adapter-auto": "*",
},
"peerDependencies": {
"@sveltejs/adapter-auto": "2.1.1"
}
Испугался, и решил не использовать.
Давайте лучше дружно хламить devDependencies
, но уж лучше без этого.
Там ещё как-то должен был прописаться мой личный скоуп, на основе имени компа, но и этого автоматически не произошло.
Валим из этой идеи короче :D
Как минимум в этой статье.
Не будем тянуть.
Чтобы все модули по-умолчанию сваливались в devDependencies
:
.npmrc
>> save-dev=true
Теперь, чтобы вогнать что-то в prod-dependencies
нужно будет npm i module-name --save-prod
.
Такое делается не каждый день. Но — это ответственно.
Потому, вероятно — это должен делать кто-то один из команды.
Зачем нужен package-lock.json
?
У модулей, которые у нас в зависимостях, — есть свои зависимости.
Каждая мажорная версия (1.0.0
—> 2.0.0
) по конвенции допускает нарушение обратной совместимости.
https://docs.npmjs.com/about-semantic-versioning
Зафиксируем:
^1.0.0
— тут разработчик модуля говорит, что версия зависимости сойдёт вплоть до 2.0.0
.
~1.0.0
— тут разработчик модуля говорит, что версия зависимости сойдёт вплоть до 1.1.0
.
И — наши зависимости, зависимости модулей — могут между собой пересекаться.
А сама конечная зависимость — может быть только одна.
И, делая npm i
— каждый новый раз — нода может выкачивать из своих репозиториев чутка разные набор зависимостей, более оптимальные на текущий момент, удовлетворяя при этом всем настройкам выше — и в наших зависимостях, и в зависимостях зависимостей.
Поэтому, несмотря на то, что package-lock.json
такой страшный — к сожалению, его лучше всё же класть в git.
Чтобы не попасть в ситуацию, когда набор зависимостей на локале и на проде разный, а ты не можешь понять в чём ошибка.
А ошибка может быть в любой даже минорной версии с баг-фиксом в любой из зависимостей.
Хотя, это и бывает редко. Но бьёт больно.
Чтобы package-lock.json
так не раздражал в git-e, парни предлагают:
.gitattributes
—> package-lock.json binary
https://stackoverflow.com/a/50982431/4117781
Итого в .npmrc
https://docs.npmjs.com/cli/v10/configuring-npm/npmrc
engine-strict=true <— добрая рекомендация от Svelte
save-exact=true
save-dev=true
Что ещё интересного в package.json
?
1. "private": true,
Consider also setting "private": true to prevent accidental publication.
https://docs.npmjs.com/cli/v10/configuring-npm/package-json
Не знаю как это возможно, но, если «accidental», то убирать не будем.
2. "type": module,
Это то, что позволяет нам делать модные import a from '/b.js
, вместо старых a = require('b')
и т.д.
3. Авторская рекомендация
Т.к. у нас кроме ноды есть строгое API со всякими проверками на всякие хосты, порты и заголовки,
стоит гарантировать на каком хосте/порте будет открываться dev-версия.
Заменить:
"dev": "vite dev",
На:
"dev": "vite dev --host 127.0.0.1 --port 3000",
А ещё добавить:
"host": "vite dev --host --port 3000",
чтобы просто npm run host
, и проект можно посмотреть хоть на телефоне (если подключен к тому же wi-fi)
Во имя науки
- Можно руками закинуть модуль и в «prod» и в «dev». И даже ничего не сломается, но — не знаю зачем.
При попытке обновить/форсировать установку ещё раз — одна из записей сотрётся, в зависимости от куда
--save-x
и т.д. -
optionalDependencies
— когда допускаем, что модуль может не установиться, а он нам и не очень-то и нужен. -
bundleDependencies
— когда пилим свой модуль. - Постоянно встречаются упоминания
npm-shrinkwrap.json
— Это «freeze»package-lock.json
для тех случаев когда это внезапно нужно:- Ноддерживает старые версии ноды (когда
package-lock.json
только с v5), - Необходим для публикации в качестве npm-модуля,
- А также, если встряли с версиями зависимостей. Тут
npm-shrinkwrap.json
позволит управлять версиями вручную (https://nodejs.org/en/blog/npm/managing-node-js-dependencies-with-shrinkwrap/). В общем, не думая об этом — мы ничего не упускаем. Просто будем знать на всякий случай.
- Ноддерживает старые версии ноды (когда
Как делать install
на проде?
Принято делать вот так:
npm ci --[ТОЛЬКО PROD-DEPENDENCIES]
- [ТОЛЬКО PROD-DEPENDENCIES]
Можно встретить много рекомендаций, обещающих один и тот же результат:
--omit=dev
, --include=prod
, --only=prod
, --production
По всей видимости это из-за долгой эволюции ноды.
Для последней 10-й версии в документации есть только --include=prod
(https://docs.npmjs.com/cli/v10/commands/npm-ci).
Но, так — у меня устанавливаются всё — и «prod» и «dev».
В итоге, делаю так:
npm ci --omit=dev
Множественное «опущение» делается так:
npm ci --omit=dev --omit=peer
Собственно, это то, что выкачивает node_modules/
на основе package-lock.json
, в обход package.json
, гарантируя то, что на проде будет так, как было на локале.
Иии, внииимаааниииеее...
Спасибо, за внимание.
Top comments (0)