Особенности npm, npx, yarn. Деплой через CI/CD
npm
npm — это стандартный менеджер пакетов для Node.js, используемый для установки и управления зависимостями в проекте.
Команда npm install (или кратко npm i) устанавливает все зависимости, указанные в package.json, и создает файл package-lock.json
npm i -D typescript ts-node @types/node
- Все указанные пакеты (
typescript,ts-node,@types/node) будут установлены в папкуnode_modulesвашего проекта - Пакеты будут добавлены в секцию
"devDependencies"вpackage.jsonс флагом-D(или--save-dev), что означает, что они будут отмечены как зависимости для разработки.
npm i -g
- Установленный глобально (-g) пакет становится доступен в командной строке по всему вашему компьютеру, и можно запускать его из любой директории.
- Пакеты, установленные глобально, не попадают в
node_modulesвашего проекта и не добавляются вpackage.json. Они сохраняются в глобальной папке npm, которая зависит от системы (например,/usr/local/lib/node_modulesна macOS и Linux илиC:\Users\YourUser\AppData\Roaming\npm\node_modulesна Windows).
npx
npx — это утилита для запуска пакетов из npm без их предварительной установки. Это удобно для выполнения одноразовых задач.
Команда npx позволяет запустить пакет временно:
npx create-react-app my-app
- npx не загрязняет проект лишними зависимостями в
node_modulesи не добавляет пакет вpackage.json. Это делает npx удобным для одноразовых команд и временного использования инструментов - npx использует кэш для уже загруженных пакетов, чтобы избежать постоянного скачивания из сети
- По умолчанию, кэш npm (включая кэшированные пакеты, которые загружаются через
npx) хранится на уровне системы (например, в директории~/.npm/_npxна Unix-системах или%AppData%/npm-cache/_npxна Windows). Кэш остается на диске, пока его не удалят вручную или с помощью специальных команд. Нет автоматического ограничения на срок хранения. npm cache clean --forceможно вручную очистить весь кэш npm, включая пакеты, загруженные черезnpx.- При использовании флага
--no-cacheкомандаnpxне будет использовать кэшированные копии и всегда загружает пакет заново. Это может быть полезно, если требуется гарантированно последняя версия пакета - Через конфигурации npm (
npm config) можно контролировать размер кэша или перенести его в другую директорию.
npm config set cache /path/to/cache-directory
yarn
yarn — это альтернатива npm, ориентированная на скорость и стабильность установки, а также улучшенное разрешение конфликтов.
Команда yarn install (или просто yarn) устанавливает все зависимости, создавая yarn.lock, который фиксирует точные версии пакетов.
yarn install
Используйте yarn, если планируете управлять зависимостями только через него. При этом рекомендуется удалить package-lock.json и всегда использовать yarn вместо npm для установки пакетов, чтобы избежать конфликтов.
yarn add typescript ts-node @types/node --dev
Для установки зависимостей для разработки с yarn используйте команду yarn add --dev, эквивалентную npm install -D.
yarn check
yarn checkстрого проверяет, что каждая зависимость вpackage.jsonполностью соответствуетyarn.lockи физически установленным версиям.- Любые несоответствия между
package.jsonи установленными версиями пакетов вызовут ошибку, даже если это не влияет на совместимость.
yarn check --verify-tree
- Флаг
--verify-treeболее снисходителен к мелким несоответствиям междуpackage.jsonиyarn.lock, если они не нарушают совместимость зависимостей. - Эта команда проверяет только, что дерево зависимостей совместимо и не имеет конфликтующих версий. Поэтому она может пропустить мелкие расхождения, которые не приводят к конфликтам версий.
yarn why @puppeteer/browsers
Команда yarn why покажет цепочку зависимостей и какой основной пакет требует @puppeteer/browsers.
Управление совместимыми версиями зависимостей с помощью resolutions в Yarn
Опция resolutions в Yarn позволяет задать конкретную версию для зависимости на уровне проекта, игнорируя требования других пакетов. Например, если несколько зависимостей требуют разных версий одного пакета, с помощью resolutions можно указать единую версию, чтобы избежать потенциальных конфликтов. Необходимо добавить в файл package.json раздел, в котором указаны версии для конфликтующих зависимостей. Если какая-либо зависимость указывает более старую или иную версию react, Yarn будет использовать версию 18.3.1
"resolutions": {
"react": "18.3.1"
}
Это может быть полезно для Обновления уязвимых зависимостей. Если требуется обновить библиотеку для устранения уязвимости, но при этом обновления основной библиотеки задерживаются.
Использование yarn-deduplicate
yarn-deduplicate — это сторонний инструмент, разработанный для оптимизации файла yarn.lock, устраняя дублирующиеся зависимости. Когда зависимости обновляются или добавляются, файл yarn.lock может содержать несколько записей для разных версий одной и той же библиотеки. yarn-deduplicate анализирует yarn.lock, находит дублирующиеся зависимости и оптимизирует их.
npx yarn-deduplicate
У yarn-deduplicate есть несколько стратегий для выбора версии дублирующейся зависимости:
- highest: выбирает самую высокую версию зависимости.
- lowest: выбирает самую низкую версию зависимости.
- major/minor/patch: выбирает дубликат в зависимости от семантической версии.
npx yarn-deduplicate --strategy highest
Комбинирование с resolutions
yarn-deduplicate также можно комбинировать с resolutions в случае, если нужно зафиксировать конкретные версии. Сначала используйте resolutions для выбора нужных версий, затем примените yarn-deduplicate
Настройка CI/CD. npm ci/yarn install –frozen-lockfile
При использовании CI/CD для автоматизации деплоя, нужно настроить GitHub Actions так, чтобы на сервере зависимости устанавливались с помощью npm ci или yarn install --frozen-lockfile. Это гарантирует, что билд будет использовать только те версии, которые зафиксированы в lock-файле.
Пример для Next.js в GitHub Actions:
# Пример для GitHub Actions
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: npm ci # или yarn install --frozen-lockfile для Yarn
- name: Build Next.js app
run: npm run build # или yarn build
- name: Start Next.js server
run: npm start # или yarn start
Более полный пример GitHub Actions:
name: Next.js CI/CD Workflow
on:
push:
branches:
- main # Триггер на пуш в основную ветку
pull_request:
branches:
- main # Триггер на открытие PR в основную ветку
jobs:
build-and-deploy:
runs-on: ubuntu-latest
# Устанавливаем кэш для node_modules, чтобы ускорить последующие сборки
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Use Node.js 16
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache Node.js modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: |
~/.npm # Кэшируем npm
.next/cache # Кэшируем .next для оптимизации повторных билдов
key: ${{ runner.os }}-build-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install dependencies
run: npm ci
- name: Run Linter
run: npm run lint
continue-on-error: true # Позволяет workflow продолжиться, даже если lint выдаёт ошибки
- name: Run Tests
run: npm test
- name: Build Next.js app
run: npm run build
- name: Upload production artifacts
if: ${{ success() }}
run: |
mkdir -p build-artifacts
cp -R .next build-artifacts
echo "Artifacts uploaded for future deployment."
- name: Deploy to Production Server
if: ${{ github.ref == 'refs/heads/main' && success() }}
env:
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
NEXT_PUBLIC_ANALYTICS_KEY: ${{ secrets.NEXT_PUBLIC_ANALYTICS_KEY }}
run: |
echo "Starting deployment to production..."
# Здесь можно добавить команду для отправки артефактов на сервер, например через SCP
# Или использовать специализированные CI/CD сервисы для деплоя
echo "Deployment completed successfully."
notify:
runs-on: ubuntu-latest
needs: build-and-deploy
steps:
- name: Notify team of deployment status
if: ${{ always() }}
run: |
if [ "${{ success() }}" = "true" ]; then
echo "Build and deployment succeeded! Notifying team..."
# Здесь можно добавить отправку уведомления (например, через Slack API)
else
echo "Build or deployment failed. Please check logs."
# Можно добавить отправку уведомления об ошибке
Использование матриц и кэширования для оптимизации CI/CD: Пример с матрицей сборки для поддержки разных версий Node.js или операционных систем. Это позволяет проверять совместимость кода на разных конфигурациях:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16, 18]
steps:
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Cache Node.js modules
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies
run: npm ci
Настраиваем работу с уведомлениями и аварийными откатами. Уведомление команды о статусе деплоя и возможность автоматического отката при ошибке могут значительно улучшить процесс. Например, добавление шагов с уведомлением через Slack API или интеграцию с инструментами мониторинга и логирования
- name: Notify team of deployment status
if: ${{ always() }}
run: |
if [ "${{ success() }}" = "true" ]; then
curl -X POST -H 'Content-type: application/json' --data '{"text":"Deployment succeeded"}' $SLACK_WEBHOOK_URL
else
curl -X POST -H 'Content-type: application/json' --data '{"text":"Deployment failed"}' $SLACK_WEBHOOK_URL