Поделиться через


Конвейеры для приложений JavaScript

В этой статье объясняется, как Azure Pipelines работает с приложениями JavaScript. Размещенные корпорацией Майкрософт агенты предустанавливают распространенные средства сборки, тестирования и развертывания JavaScript, такие как npm, Node.js, Yarn и Gulp, не требуя от вас настройки какой-либо инфраструктуры. Вы также можете настроить локальные агенты.

Чтобы быстро создать конвейер для JavaScript, ознакомьтесь с кратким руководством по JavaScript.

Установщики инструментов Node.js

Чтобы установить Node.js и версии npm, которые не предварительно установлены, или установить средства на локальных агентах:

Чтобы установить определенную версию Node.js, добавьте следующий код в файл azure-pipelines.yml :

- task: UseNode@1
  inputs:
    version: '16.x' # replace with the version you need

Примечание.

Для этой задачи может потребоваться значительное количество времени на обновление до более новой минорной версии при каждом запуске конвейера. Агенты, размещенные Microsoft, регулярно обновляются, поэтому используйте эту задачу только для установки определённых версий Node.js, которые не предустановлены. Чтобы узнать, какие версии Node.js и npm предварительно установлены в агентах, размещенных корпорацией Майкрософт, см. статью Software.

Использование нескольких версий узлов

Вы можете использовать задачу "Использование экосистемы Node.js версии 1" с matrix стратегией создания и тестирования приложения на нескольких версиях Node.js. Дополнительные сведения см. в разделе "Конфигурация с несколькими заданиями".

pool:
  vmImage: 'ubuntu-latest'
strategy:
  matrix:
    node_16_x:
      node_version: 16.x
    node_13_x:
      node_version: 18.x

steps:
- task: UseNode@1
  inputs:
    version: $(node_version)

- script: npm install

Установка инструмента зависимостей

Если в вашем проекте в файле package.json или package-lock.json есть средства разработки и зависимости, установите их через npm. Файл проекта определяет точную версию средств, независимо от других версий, существующих в агенте сборки.

Чтобы установить эти средства в агенте сборки, используйте скрипт, задачу npm или задачу командной строки в конвейере.

Чтобы использовать скрипт, выполните следующие действия.

- script: npm install --only=dev

Чтобы использовать задачу npm, выполните следующие действия.

- task: Npm@1
  inputs:
     command: 'install'

Средства, устанавливаемые таким образом, используют менеджер пакетов npm npx, который определяет расположение инструментов в PATH. В следующем примере вызывается mocha тестовый раннер и используется версия зависимости из разработки, а не версия, установленная глобально через npm install -g.

- script: npx mocha

Чтобы установить средства, необходимые для проекта, которые не задаются в качестве зависимостей разработки в package.json, вызовите npm install -g из скрипта в конвейере. В следующем примере устанавливается последняя версия Angular CLI с помощью npm. Затем другие скрипты в конвейере могут использовать команды Angular ng .

- script: npm install -g @angular/cli

Примечание.

В агентах Linux, размещенных в Корпорации Майкрософт, предусловит команду следующим sudoобразом sudo npm install -g.

Эти задачи установки инструментов выполняются каждый раз при запуске конвейера, поэтому учитывайте их влияние на время сборки. Если накладные расходы серьезно влияют на производительность сборки, рассмотрите возможность использования предварительно настроенных агентов с помощью необходимых версий инструментов.

Примечание.

Эти задачи установки инструментов выполняются каждый раз при запуске конвейера, поэтому учитывайте их влияние на время сборки.

Загрузка пакетов зависимостей

Вы можете использовать Yarn или Azure Artifacts для скачивания пакетов из общедоступного реестра npm или частного реестра npm, указанного в файле *.npmrc . Чтобы указать реестр npm, добавьте его URL-адрес в файл *.npmrc в репозитории кода.

Использование npm

Npm можно использовать для скачивания пакетов сборки в конвейере следующими способами:

  • Для самого простого способа скачивания пакетов без проверки подлинности, выполните npm install напрямую.
  • Чтобы использовать прошедший проверку подлинности реестр, добавьте задачу npm .
  • Чтобы запустить npm install с помощью модулей Gulp, Grunt или Maven, используйте задачу npm authenticate.

Примечание.

Если фид npm использует проверку подлинности, необходимо создать подключение службы npm на вкладке "Службы " в разделе Параметры проекта Azure DevOps для управления учетными данными.

Чтобы установить пакеты npm напрямую, используйте следующий сценарий в azure-pipelines.yml. Если агент сборки не нуждается в зависимостях разработки, можно ускорить скорость сборки, добавив параметр --only=prod в команду npm install.

- script: npm install --only=prod

Чтобы использовать частный реестр, указанный в файле *.npmrc , добавьте Npm@1 задачу в azure-pipelines.yml.

- task: Npm@1
  inputs:
    customEndpoint: <Name of npm service connection>

Чтобы передать учетные данные реестра в команды npm с помощью таскраннеров, таких как Gulp, добавьте задачу npmAuthenticate@0 в azure-pipelines.yml перед вызовом таскраннера.

- task: npmAuthenticate@0
  inputs:
    customEndpoint: <Name of npm service connection>

Примечание.

Агенты под управлением Microsoft используют новую машину для каждой сборки. Восстановление зависимостей может занять значительное время. Чтобы устранить проблему, можно использовать Azure Artifacts или самостоятельно размещаемый агент с кэшем пакетов.

Если сборки иногда завершаются сбоем из-за проблем с подключением при восстановлении пакетов из реестра npm, можно использовать Azure Artifacts с вышестоящими источниками для кэширования пакетов. Артефакты Azure автоматически используют учетные данные конвейера, которые обычно являются производными от учетной записи службы сборки коллекции проектов .

Примечание.

Восстановление зависимостей может занять значительное время. Чтобы устранить проблему, можно использовать Azure Artifacts или самостоятельно размещаемый агент с кэшем пакетов.

Если сборки иногда завершаются сбоем из-за проблем с подключением при восстановлении пакетов из реестра npm, можно использовать Azure Artifacts с вышестоящими источниками для кэширования пакетов. Артефакты Azure автоматически используют учетные данные конвейера, которые обычно являются производными от учетной записи службы сборки коллекции проектов .

Использование Yarn

Используйте скрипт для установки Yarn для восстановления зависимостей. Yarn предварительно установлен на некоторых размещенных корпорацией Майкрософт агентах. Вы можете установить и настроить Yarn на локальных агентах, таких как любой другой инструмент.

- script: yarn install

Вы также можете использовать задачу CLI или Bash в конвейере для вызова Yarn.

Компиляторы JavaScript

Приложения JavaScript используют компиляторы, такие как Babel и компилятор TypeScripttsc , для преобразования исходного кода в версии, доступные для использования средой выполнения Node.js или в веб-браузерах. Если у вас есть объект скрипта , настроенный в файле проекта package.json для запуска компилятора, его можно вызвать в конвейере.

- script: npm run compile

Компиляторы также можно вызывать непосредственно из конвейера с помощью скрипта. Эти команды выполняются из корня клонированного репозитория исходного кода.

- script: tsc --target ES6 --strict true --project tsconfigs/production.json

Задачу npm можно использовать для сборки кода, если проект package.json определяет скрипт компиляции. Если скрипт компиляции не определен, можно использовать задачу Bash для компиляции кода.

Модульное тестирование

Конвейеры можно настроить для выполнения тестов JavaScript, чтобы они могли получать результаты в формате JUnit XML. Затем можно опубликовать результаты с помощью задачи "Опубликовать результаты теста ".

Если тестовая платформа не поддерживает выходные данные JUnit, добавьте поддержку через модуль отчетов партнера, например mocha-junit-reporter. Вы можете обновить тестовый скрипт для использования репортера JUnit или передать эти параметры в определение задачи, если репортер поддерживает параметры командной строки.

В следующей таблице перечислены наиболее часто используемые тестовые средства выполнения и репортеры, которые можно использовать для получения результатов XML:

Средство выполнения теста Репортеры для XML-отчетов
Mocha mocha-junit-репортер
cypress-multi-репортеры
Жасмин jasmine-reporters
Jest jest-junit
jest-junit-репортер
Karma карма-хунит-репортер
Ava tap-xunit

В следующем примере используется mocha-junit-reporter и вызывается mocha test непосредственно с помощью скрипта. Этот скрипт создает выходные данные XML JUnit в расположении по умолчанию ./test-results.xml.

- script: mocha test --reporter mocha-junit-reporter

Если вы определили test скрипт в файле package.json проекта, его можно вызвать с помощью npm test.

- script: npm test

Опубликовать результаты теста

Чтобы опубликовать результаты теста, используйте задачу "Опубликовать результаты теста ".

- task: PublishTestResults@2
  condition: succeededOrFailed()
  inputs:
    testRunner: JUnit
    testResultsFiles: '**/test-results.xml'

Публикация результатов покрытия кода

Если тестовые скрипты запускают средство покрытия кода, например Стамбул, добавьте задачу "Публикация результатов покрытия кода ". Затем можно просмотреть метрики покрытия в сводке сборки и скачать отчеты HTML для дальнейшего анализа.

Задача ожидает выходные данные отчетов Cobertura или JaCoCo. Убедитесь, что инструмент покрытия кода выполняется с необходимыми параметрами для создания корректного результата, например --report cobertura.

В следующем примере используется инструмент командной строки nyc вместе с mocha-junit-reporter и вызывается npm test.

- script: |
    nyc --reporter=cobertura --reporter=html \
    npm test -- --reporter mocha-junit-reporter --reporter-options mochaFile=./test-results.xml
  displayName: 'Build code coverage report'

- task: PublishCodeCoverageResults@2
  inputs: 
    summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/*coverage.xml'

Сквозное тестирование браузера

Ваш пайплайн может использовать такие инструменты, как Protractor или Karma, для выполнения тестов в безголовых браузерах, а затем опубликовать результаты тестов. Чтобы настроить тестирование браузера и опубликовать результаты, выполните следующие действия.

  1. Установите драйвер тестирования безголового браузера, например, headless Chrome или Firefox, или инструмент эмуляции браузера, такой как PhantomJS, на агент сборки.
  2. Настройте ваш тестовый фреймворк для использования безголового браузера или варианты драйвера, в соответствии с документацией инструмента.
  3. Настройте платформу тестирования для вывода результатов теста в формате JUnit, как правило, с подключаемым модулем или конфигурацией репортера.
  4. Добавьте скрипт или задачу CLI, чтобы запустить экземпляры браузера без головы.
  5. Запустите сквозные тесты на этапах конвейера вместе с модульными тестами.
  6. Опубликуйте результаты вместе с модульными тестами с помощью той же задачи публикации результатов теста .

Упаковка и доставка

После сборки и тестирования приложения вы можете:

  • Отправьте выходные данные сборки в Azure Pipelines.
  • Создание и публикация пакета npm или Maven.
  • Упаковать выходные данные сборки в ZIP-архив для развертывания в веб-приложении.

Публикация файлов в Azure Pipelines

Чтобы отправить весь рабочий каталог, добавьте задачу "Публикация артефактов сборки " в файл azure-pipelines.yml .

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)'

Чтобы отправить подмножество файлов, сначала скопируйте необходимые файлы из рабочего каталога в промежуточный каталог с задачей " Копирование файлов ", а затем используйте задачу "Публикация артефактов сборки ".

- task: CopyFiles@2
  inputs:
    SourceFolder: '$(System.DefaultWorkingDirectory)'
    Contents: |
      **\*.js
      package.json
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: PublishBuildArtifacts@1

Публикация модуля в реестре npm

Если выходные данные вашего проекта — это модуль, предназначенный для использования в других проектах и не являющийся npm веб-приложением, используйте задачу npm для публикации модуля в локальном реестре или общедоступном реестре npm. При каждой публикации укажите уникальное сочетание имен и версий.

В следующем примере скрипт используется для публикации в общедоступном реестре npm. В этом примере предполагается, что вы управляете сведениями о версиях, например npm, с помощью файла package.json в элементе управления версиями.

- script: npm publish

В следующем примере публикация осуществляется в пользовательский реестр, указанный в файле *.npmrc вашего репозитория. Настройте подключение службы npm для внедрения учетных данных проверки подлинности в подключение при выполнении сборки.

- task: Npm@1
  inputs:
     command: publish
     publishRegistry: useExternalRegistry
     publishEndpoint: https://my.npmregistry.com

В следующем примере модуль публикуется в веб-канале управления пакетами Azure DevOps Services.

- task: Npm@1
  inputs:
     command: publish
     publishRegistry: useFeed
     publishFeed: https://my.npmregistry.com

Дополнительные сведения об использовании версий и публикации пакетов npm см. в статье "Публикация пакетов npm" и "Как я могу управлять версиями моих пакетов npm в процессе сборки".

Упаковка и развертывание веб-приложения

Вы можете упаковать приложения для упаковки всех модулей с промежуточными выходными данными и зависимостями в статические ресурсы, готовые к развертыванию. Добавьте этап конвейера после компиляции и тестирования для запуска инструмента, такого как webpack, или команды Angular CLI ng build.

В следующем примере вызывается webpack. Чтобы этот процесс работал, убедитесь, что webpack он настроен как зависимость разработки в файле проекта package.json . Этот скрипт выполняется webpack с конфигурацией по умолчанию, если у вас нет файлаwebpack.config.js в корневой папке проекта.

- script: webpack

В следующем примере используется npm run build для вызова объекта скрипта build , определенного в файле package.json проекта. Использование объекта скрипта в проекте перемещает логику сборки в исходный код и из конвейера.

- script: npm run build

Вы также можете использовать задачу CLI или Bash в вашем конвейере для вызова средства упаковки, такого как webpack или Angular.ng build.

Чтобы создать архив файла *.zip , готовый к публикации в веб-приложении, используйте задачу "Архивные файлы ".

- task: ArchiveFiles@2
  inputs:
    rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
    includeRootFolder: false

Сведения о публикации этого архива в веб-приложении см. в статье "Развертывание в службе приложений Azure" с помощью Azure Pipelines.

Платформы JavaScript

Пакеты можно установить в конвейере для поддержки различных платформ JavaScript.

Angular

Для приложений Angular можно выполнять такие команды, как ng testng build, и ng e2e. Чтобы использовать команды Angular CLI в конвейере, установите пакет angular/cli npm в агенте сборки.

- script: |
    npm install -g @angular/cli
    npm install
    ng build --prod

Примечание.

В агентах Linux, размещенных в Корпорации Майкрософт, предусловит команду следующим sudoобразом sudo npm install -g.

Для тестов в конвейере, для выполнения которых требуется браузер, например запуск Кармы с ng test помощью команды, используйте безголовой браузер вместо стандартного браузера. В начальном приложении Angular:

  • Измените browsers запись в файле проекта karma.conf.js на browsers: ['Chrome']browsers: ['ChromeHeadless'].
  • Измените singleRun запись в файле проекта karma.conf.js на falsetrue. Это изменение обеспечивает остановку процесса Карма после его выполнения.

React и Vue

Все зависимости для приложений React и Vue записываются в файл package.json . Файл azure-pipelines.yml содержит стандартные npm скрипты.

- script: |
    npm install
  displayName: 'npm install'

- script: |
    npm run build
  displayName: 'npm build'

Файлы сборки находятся в новой папке, dist for Vue или build for React. В следующем примере создается артефакт www, который готов к выпуску. В конвейере используются задачи использования Node.js, копирования файла и публикации артефактов сборки .

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UseNode@1
  inputs:
    version: '16.x'
  displayName: 'Install Node.js'

- script: npm install
  displayName: 'npm install'

- script: npm run build
  displayName: 'npm build'

- task: CopyFiles@2
  inputs:
    Contents: 'build/**' # Pull the build directory (React)
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: PublishBuildArtifacts@1
  inputs: 
    PathtoPublish: $(Build.ArtifactStagingDirectory) # dist or build files
    ArtifactName: 'www' # output artifact named www

Чтобы освободить приложение, укажите задачу выпуска на dist или build артефакт и используйте задачу веб-приложения Azure .

веб-пакета

Файл конфигурации webpack можно использовать для указания компилятора, например Babel или TypeScript, для транспиляции JavaScript XML (JSX) или TypeScript в обычный JavaScript и для сборки вашего приложения.

- script: |
    npm install webpack webpack-cli --save-dev
    npx webpack --config webpack.config.js

Запуски задач сборки

Обычно для создания и тестирования приложений JavaScript используется Gulp или Grunt в качестве средств выполнения задач.

Gulp

Gulp предварительно установлен для агентов, размещенных в Майкрософт.

Команду gulp можно запустить в YAML-файле конвейера.

- script: gulp # add any needed options

Если действия в файле gulpfile.js требуют проверки подлинности с помощью реестра npm, добавьте задачу проверки подлинности npm .

- task: npmAuthenticate@0
  inputs:
    customEndpoint: <Name of npm service connection>

- script: gulp

Чтобы опубликовать результаты теста JUnit или xUnit на сервере, добавьте задачу "Опубликовать результаты теста ".

- task: PublishTestResults@2
  inputs:
    testResultsFiles: '**/TEST-RESULTS.xml'
    testRunTitle: 'Test results for JavaScript using gulp'

Чтобы опубликовать результаты покрытия кода на сервере, добавьте задачу " Публикация результатов покрытия кода ". Метрики покрытия можно найти в сводке сборки и скачать отчеты HTML для дальнейшего анализа.

- task: PublishCodeCoverageResults@1
  inputs: 
    codeCoverageTool: Cobertura
    summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/*coverage.xml'
    reportDirectory: '$(System.DefaultWorkingDirectory)/**/coverage'

Grunt

Grunt предварительно установлен на агентах, размещенных Майкрософт.

Команда grunt может быть запущена в файле YAML.

- script: grunt # add any needed options

Если действия в файле Gruntfile.js требуют проверки подлинности с помощью реестра npm, добавьте задачу проверки подлинности npm .

- task: npmAuthenticate@0
  inputs:
    customEndpoint: <Name of npm service connection>

- script: grunt

Устранение неполадок

Если вы можете создать проект на компьютере разработки, но не можете создать его в Azure Pipelines, изучите следующие потенциальные причины и корректирующие действия.

  • Убедитесь, что версии Node.js и средство выполнения задач на компьютере разработки соответствуют версиям агента.

    Вы можете включить скрипты командной строки, такие как node --version в конвейере, чтобы проверить версии, установленные на агенте. Используйте Use Node.js задачу для установки той же версии агента или выполнения npm install команд для обновления версий средства.

  • Если сборки завершаются сбоем во время восстановления пакетов, реестр npm имеет проблемы или возникают проблемы с сетью между центром обработки данных Azure и реестром. Узнайте, повышает ли использование артефактов Azure с реестром npm в качестве вышестоящего источника, что повышает надежность сборок.

  • Если вы используете nvm для управления различными версиями Node.js, попробуйте переключиться на задачу Use Node.js (UseNode@1). nvm устанавливается по историческим причинам на образе macOS. nvm управляет несколькими версиями Node.js путем добавления псевдонимов оболочки и изменения PATH, которые плохо взаимодействуют с тем, как Azure Pipelines выполняет каждую задачу в новом процессе. Дополнительные сведения см. в разделе "Запуски конвейера".

    Задача Use Node.js правильно обрабатывает эту модель. Однако если для работы требуется использовать nvm, можно добавить следующий сценарий в начало каждого конвейера:

    steps:
    - bash: |
        NODE_VERSION=16  # or your preferred version
        npm config delete prefix  # avoid a warning
        . ${NVM_DIR}/nvm.sh
        nvm use ${NODE_VERSION}
        nvm alias default ${NODE_VERSION}
        VERSION_PATH="$(nvm_version_path ${NODE_VERSION})"
        echo "##vso[task.prependPath]$VERSION_PATH"
    

    node Затем другие средства командной строки работают для остальных заданий конвейера. На каждом шаге nvm , в котором используется команда, запустите скрипт со следующим кодом:

    - bash: |
        . ${NVM_DIR}/nvm.sh
        nvm <command>
    

Вопросы и ответы

Как исправить сбой конвейера с сообщением "Критическая ошибка: CALL_AND_RETRY_LAST — ошибка распределения памяти, JavaScript heap out of memory"?

Этот тип сбоя возникает, когда пакет Node.js превышает ограничение использования памяти. Чтобы устранить проблему, добавьте переменную, например NODE_OPTIONS , и назначьте ее значение --max_old_space_size=16384.

Как можно использовать версию пакетов npm в процессе сборки?

Одним из вариантов является использование системы управления версиями и команды npm version. В конце выполнения конвейера можно обновить репозиторий с новой версией. Следующий конвейер YAML содержит репозиторий GitHub, а пакет развертывается в npmjs. Сборка завершается ошибкой, если существует несоответствие между версией пакета в npmjs и файлом package.json .

variables:
    MAP_NPMTOKEN: $(NPMTOKEN) # Mapping secret var

trigger:
- none

pool:
  vmImage: 'ubuntu-latest'

steps: # Checking out connected repo
- checkout: self
  persistCredentials: true
  clean: true
    
- task: npmAuthenticate@0
  inputs:
    workingFile: .npmrc
    customEndpoint: 'my-npm-connection'
    
- task: UseNode@1
  inputs:
    version: '16.x'
  displayName: 'Install Node.js'

- script: |
    npm install
  displayName: 'npm install'

- script: |
    npm pack
  displayName: 'Package for release'

- bash: | # Grab the package version
    v=`node -p "const p = require('./package.json'); p.version;"`
    echo "##vso[task.setvariable variable=packageVersion]$v"

- task: CopyFiles@2
  inputs:
      contents: '*.tgz'
      targetFolder: $(Build.ArtifactStagingDirectory)/npm
  displayName: 'Copy archives to artifacts staging directory'

- task: CopyFiles@2
  inputs:
    sourceFolder: '$(Build.SourcesDirectory)'
    contents: 'package.json' 
    targetFolder: $(Build.ArtifactStagingDirectory)/npm
  displayName: 'Copy package.json'

- task: PublishBuildArtifacts@1 
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)/npm'
    artifactName: npm
  displayName: 'Publish npm artifact'

- script: |  # Config can be set in .npmrc
    npm config set //registry.npmjs.org/:_authToken=$(MAP_NPMTOKEN) 
    npm config set scope "@myscope"
    # npm config list
    # npm --version
    npm version patch --force
    npm publish --access public

- task: CmdLine@2 # Push changes to GitHub (substitute your repo)
  inputs:
    script: |
      git config --global user.email "username@contoso.com"
      git config --global user.name "Azure Pipeline"
      git add package.json
      git commit -a -m "Test Commit from Azure DevOps"
      git push -u origin HEAD:main