Особенности 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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *