Скрипты и рабочие пространства — Примеры
Пример 1 — Команда сборки, живущая в документе
В документе для участников перечислена команда проверки изменений перед push; в ней четыре флага, и она уже дважды устаревала. Перенесите это знание в манифест.
# CONTRIBUTING.md
# запустите это перед push:
npx tsc --noEmit && npx eslint . && npx vitest run --reporter=dot
{ "scripts": { "dev": "vite" } }
Решение
{
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build",
"test": "vitest run",
"lint": "eslint .",
"check": "npm run lint && npm run test && npm run build"
}
}
npm run check
Скрипты — интерфейс проекта: новый участник читает манифест и знает, что набрать, а непрерывная интеграция вызывает те же имена, что и разработчик. Порядок внутри одного скрипта check — линт и проверка типов до медленной сборки — кодируется один раз, для человека, хука перед push и конвейера сразу. Документ после этого называет скрипт, а не повторяет флаги, которые разойдутся, — что здесь уже дважды и случилось; в автоматизации же используйте npm ci, а не npm install, чтобы lockfile соблюдался, а не переинтерпретировался.
Пример 2 — Одна и та же библиотека, скопированная в два приложения
Два приложения в одном репозитории держат по своей копии общей библиотеки компонентов, поэтому исправление приходится делать дважды. Перестройте репозиторий так, чтобы у библиотеки остался один источник.
repo/
apps/shop/ package.json, своя копия components/
apps/admin/ package.json, своя копия components/
Решение
{
"name": "root",
"private": true,
"workspaces": ["packages/*", "apps/*"]
}
repo/
packages/components/ package.json (объявляет каждую импортируемую зависимость)
apps/shop/ зависит от "components" по имени
apps/admin/ зависит от "components" по имени
Рабочее пространство заставляет инструмент ставить все пакеты вместе и разрешать внутреннюю зависимость по имени, поэтому изменение в библиотеке видно в обоих приложениях без публикации и ручного связывания. Держите корневой манифест private, чтобы его нельзя было опубликовать случайно. Об одной ловушке стоит сказать отдельно: из-за подъёма пакет может импортировать то, что он никогда не объявлял, потому что в корне это случайно оказалось рядом, — здесь это работает, однако при отдельной установке пакета ломается; поэтому общий пакет объявляет каждую используемую зависимость.