Partilhar via


Pipelines para aplicações JavaScript

Este artigo explica como o Azure Pipelines funciona com aplicativos JavaScript. Os agentes hospedados pela Microsoft pré-instalam ferramentas comuns de compilação, teste e implantação de JavaScript, como npm, Node.js, Yarn e Gulp, sem exigir que você configure nenhuma infraestrutura. Você também pode configurar agentes auto-hospedados.

Para criar rapidamente um pipeline para JavaScript, consulte o Guia de início rápido do JavaScript.

Instaladores de ferramentas Node

Para instalar versões Node.js e npm que não estão pré-instaladas ou para instalar as ferramentas em agentes auto-hospedados:

Para instalar uma versão Node.js específica, adicione o seguinte código ao arquivo azure-pipelines.yml :

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

Nota

Essa tarefa pode exigir um tempo significativo de atualização para uma versão secundária mais recente sempre que o pipeline for executado. Os agentes hospedados pela Microsoft são atualizados regularmente, portanto, use essa tarefa apenas para instalar versões específicas do Node que não estejam pré-instaladas. Para descobrir quais versões Node.js e npm estão pré-instaladas em agentes hospedados pela Microsoft, consulte Software.

Usar várias versões de nós

Você pode usar a tarefa Usar Node.js ecossistema v1 com uma matrix estratégia para criar e testar seu aplicativo em várias versões do Node.js. Para obter mais informações, consulte Configuração de vários trabalhos.

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

Instalação da ferramenta para gestão de dependências

Se tiver ferramentas de dependência de desenvolvimento no arquivo do projeto package.json ou package-lock.json, instale as ferramentas e dependências por meio do npm. O arquivo de projeto define a versão exata das ferramentas, independente de outras versões que existem no agente de compilação.

Para instalar essas ferramentas em seu agente de compilação, use um script, a tarefa npm ou uma tarefa de linha de comando em seu pipeline.

Para usar um script:

- script: npm install --only=dev

Para usar a tarefa npm:

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

As ferramentas instaladas dessa forma usam o executor de pacote npm npx , que deteta as ferramentas em sua resolução PATH. O exemplo a seguir chama o mocha runner de testes e usa a versão de dependência de desenvolvimento em vez da versão instalada globalmente por meio do npm install -g.

- script: npx mocha

Para instalar ferramentas de que seu projeto precisa que não estão definidas como dependências de desenvolvimento no package.json, chame npm install -g a partir de um script em seu pipeline. O exemplo a seguir instala a versão mais recente da CLI Angular usando npmo . Outros scripts no fluxo de trabalho podem usar os comandos Angular ng .

- script: npm install -g @angular/cli

Nota

Em agentes Linux hospedados pela Microsoft, prefacie o comando com sudo, como sudo npm install -g.

Essas tarefas de instalação de ferramentas são executadas sempre que o pipeline é executado, portanto, esteja ciente de seu impacto nos tempos de compilação. Se a sobrecarga afetar seriamente o desempenho da compilação, considere o uso de agentes auto-hospedados pré-configurados com as versões de ferramenta necessárias.

Nota

Essas tarefas de instalação de ferramentas são executadas sempre que o pipeline é executado, portanto, esteja ciente de seu impacto nos tempos de compilação.

Downloads de pacotes de dependência

Você pode usar o Yarn ou o Azure Artifacts para baixar pacotes do registro npm público ou de um registro npm privado especificado em um arquivo *.npmrc . Para especificar um registro npm, adicione sua URL ao arquivo *.npmrc em seu repositório de código.

Usar npm

Você pode usar o npm para baixar pacotes de compilação em seu pipeline das seguintes maneiras:

  • Para a maneira mais simples de baixar pacotes sem autenticação, execute diretamente npm install.
  • Para usar um registro autenticado, adicione a tarefa npm .
  • Para executar npm install de dentro dos executores de tarefas Gulp, Grunt ou Maven, use a tarefa npm authenticate .

Nota

Se seu feed npm usa autenticação, você deve criar uma conexão de serviço npm na guia Serviços nas configurações do Projeto de DevOps do Azure para gerenciar suas credenciais.

Para instalar pacotes npm diretamente, use o seguinte script no azure-pipelines.yml. Se o seu agente de compilação não precisar de dependências de desenvolvimento, você poderá acelerar os tempos de compilação adicionando a --only=prod opção ao npm install.

- script: npm install --only=prod

Para usar um registo privado especificado no seu arquivo *.npmrc, adicione a tarefa Npm@1 ao azure-pipelines.yml.

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

Para passar credenciais do registo para comandos npm por meio de ferramentas de automação de tarefas como Gulp, adicione a tarefa npmAuthenticate@0 no ficheiro azure-pipelines.yml antes de chamar a ferramenta de automação de tarefas.

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

Nota

Os agentes hospedados pela Microsoft usam uma nova máquina a cada compilação. Restaurar dependências pode levar uma quantidade significativa de tempo. Para atenuar o problema, você pode usar os Artefatos do Azure ou um agente auto-hospedado com o cache do pacote.

Se suas compilações falharem ocasionalmente devido a problemas de conexão ao restaurar pacotes do registro npm, você poderá usar Artefatos do Azure com fontes upstream para armazenar os pacotes em cache. Azure Artifacts usam automaticamente as credenciais do pipeline, que normalmente são derivadas da conta Project Collection Build Service.

Nota

Restaurar dependências pode levar uma quantidade significativa de tempo. Para atenuar o problema, você pode usar os Artefatos do Azure ou um agente auto-hospedado com o cache do pacote.

Se suas compilações falharem ocasionalmente devido a problemas de conexão ao restaurar pacotes do registro npm, você poderá usar Artefatos do Azure com fontes upstream para armazenar os pacotes em cache. Azure Artifacts usam automaticamente as credenciais do pipeline, que normalmente são derivadas da conta Project Collection Build Service.

Usar fios

Use um script para instalar o Yarn para restaurar dependências. O Yarn está pré-instalado em alguns agentes hospedados pela Microsoft. Você pode instalar e configurar o Yarn em agentes auto-hospedados como qualquer outra ferramenta.

- script: yarn install

Você também pode usar a tarefa CLI ou Bash no seu pipeline para invocar o comando Yarn.

Compiladores JavaScript

Os aplicativos JavaScript usam compiladores como Babel e o compilador TypeScripttsc para converter o código-fonte em versões utilizáveis pelo tempo de execução do Node.js ou em navegadores da Web. Se você tiver um objeto de script configurado em seu arquivo depackage.json de projeto para executar seu compilador, poderá invocá-lo em seu pipeline.

- script: npm run compile

Você também pode chamar compiladores diretamente do pipeline usando um script. Esses comandos são executados a partir da raiz do repositório de código-fonte clonado.

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

Você pode usar a tarefa npm para criar o código se seu projeto package.json define um script de compilação. Se você não definir um script de compilação, poderá usar a tarefa Bash para compilar seu código.

Teste de unidades

Você pode configurar seus pipelines para executar seus testes JavaScript para que eles produzam resultados no formato XML JUnit. Em seguida, você pode publicar os resultados usando a tarefa Publicar resultados do teste .

Se sua estrutura de teste não suportar a saída JUnit, adicione suporte por meio de um módulo de relatório de parceiro, como mocha-junit-reporter. Você pode atualizar seu script de teste para usar o repórter JUnit ou passar essas opções para a definição de tarefa se o repórter oferecer suporte a opções de linha de comando.

A tabela a seguir lista os executores de teste mais usados e os repórteres que você pode usar para produzir resultados XML:

Corredor de teste Repórteres para relatórios XML
Mocha Mocha-Junit-Repórter
cipreste-multi-repórteres
Jasmim Jasmine-Repórteres
Jest Jest-Junit
jest-junit-repórter
Karma karma-junit-repórter
Ava torneira-xunit

O exemplo a seguir usa o mocha-junit-reporter e invoca mocha test diretamente usando um script. Este script produz a saída XML JUnit no local padrão de ./test-results.xml.

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

Se você definiu um test script em seu projeto package.json arquivo, você pode invocá-lo usando npm test.

- script: npm test

Publicar resultados de testes

Para publicar resultados de teste, use a tarefa Publicar resultados de teste .

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

Publicar resultados de cobertura de código

Se os scripts de teste executarem uma ferramenta de cobertura de código, como Istambul, adicione a tarefa Publicar resultados de cobertura de código . Em seguida, você pode ver as métricas de cobertura no resumo da compilação e baixar relatórios HTML para análise adicional.

A tarefa espera que a Cobertura ou o JaCoCo gerem relatórios. Certifique-se de que sua ferramenta de cobertura de código seja executada com as opções necessárias para gerar a saída certa, por exemplo --report cobertura.

O exemplo a seguir usa a interface de linha de comando do Istambul nyc junto com mocha-junit-reporter e invoca 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'

Teste completo do navegador

Seu pipeline pode usar ferramentas como Protractor ou Karma para executar testes em navegadores sem cabeça e, em seguida, publicar os resultados do teste. Para configurar o teste do navegador e publicar resultados, siga estas etapas:

  1. Instale um driver para teste de navegadores sem interface gráfica, como o Chrome ou o Firefox sem interface gráfica, ou uma ferramenta de simulação de navegador, como o PhantomJS, no agente de compilação.
  2. Configure sua estrutura de teste para usar seu navegador sem cabeça ou opção de driver de acordo com a documentação da ferramenta.
  3. Configure sua estrutura de teste para produzir resultados de teste formatados em JUnit, geralmente com um plug-in ou configuração de repórter.
  4. Adicione um script ou uma tarefa CLI para iniciar as instâncias do navegador sem cabeça.
  5. Execute os testes de ponta a ponta nos estágios de pipeline junto com seus testes de unidade.
  6. Publique os resultados junto com seus testes de unidade usando a mesma tarefa Publicar resultados de teste .

Embalagem e entrega

Depois de criar e testar seu aplicativo, você pode:

  • Carregue a saída de compilação para o Azure Pipelines.
  • Crie e publique um pacote npm ou Maven.
  • Empacote a saída da compilação em um arquivo ZIP para implantação em um aplicativo Web.

Publicar arquivos no Azure Pipelines

Para carregar todo o diretório de trabalho, adicione a tarefa Publicar artefatos de compilação ao seu arquivo azure-pipelines.yml .

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

Para carregar um subconjunto de arquivos, primeiro copie os arquivos necessários do diretório de trabalho para um diretório de preparo com a tarefa Copiar arquivos e, em seguida, use a tarefa Publicar artefatos de compilação .

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

- task: PublishBuildArtifacts@1

Publicar um módulo em um registro npm

Se a saída do seu projeto for um npm módulo para outros projetos usarem e não for um aplicativo Web, use a tarefa npm para publicar o módulo em um registro local ou no registro npm público. Forneça uma combinação exclusiva de nome/versão sempre que publicar.

O exemplo a seguir usa o script para publicar no registro npm público. O exemplo pressupõe que você gerencie informações de versão, como npm version , por meio de um arquivo package.json no controle de versão.

- script: npm publish

O exemplo a seguir publica em um registro personalizado definido no arquivo *.npmrc do repo. Configure uma conexão de serviço npm para injetar credenciais de autenticação na conexão à medida que a compilação é executada.

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

O exemplo a seguir publica o módulo em um feed de gerenciamento de pacotes do Azure DevOps Services.

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

Para obter mais informações sobre controle de versão e publicação de pacotes npm, consulte Publicar pacotes npm e Como posso fazer a versão de meus pacotes npm como parte do processo de compilação.

Empacotar e implantar um aplicativo Web

Você pode empacotar aplicativos para agrupar todos os módulos com saídas e dependências intermediárias em ativos estáticos prontos para implantação. Adicione um estágio de pipeline após a compilação e os testes para executar uma ferramenta como webpack ou o comando ng build da Angular CLI.

O exemplo a seguir chama webpack. Para que esse processo funcione, verifique se webpack está configurado como uma dependência de desenvolvimento em seu arquivo de projetopackage.json . Esse script é executado webpack com a configuração padrão, a menos que você tenha um arquivo webpack.config.js na pasta raiz do seu projeto.

- script: webpack

O exemplo a seguir usa npm run build para chamar o build objeto de script definido no arquivo depackage.json do projeto. Usar o objeto script em seu projeto move a lógica de construção para o código-fonte e para fora do pipeline.

- script: npm run build

Você também pode usar a tarefa CLI ou Bash em seu pipeline para invocar sua ferramenta de empacotamento, como webpack ou Angular's ng build.

Para criar um arquivo de arquivo *.zip pronto para publicação em um aplicativo Web, use a tarefa Arquivar arquivos .

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

Para publicar este arquivo num aplicativo Web, consulte Deploy to Azure App Service by using Azure Pipelines.

Estruturas JavaScript

Você pode instalar pacotes em seu pipeline para suportar várias estruturas JavaScript.

Angular

Para aplicativos Angular, você pode executar comandos específicos do Angular, como ng test, ng builde ng e2e. Para usar comandos da CLI Angular em seu pipeline, instale o pacote npm angular/cli no agente de compilação.

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

Nota

Em agentes Linux hospedados pela Microsoft, prefacie o comando com sudo, como sudo npm install -g.

Para testes em seu pipeline que exigem a execução de um navegador, como executar o Karma com o ng test comando, use um navegador sem cabeça em vez de um navegador padrão. No aplicativo Angular starter:

  • Altere a browsers entrada no arquivo de projeto karma.conf.js de browsers: ['Chrome'] para browsers: ['ChromeHeadless'].
  • Altere a singleRun entrada no arquivo de projeto karma.conf.js de false para true. Essa alteração ajuda a garantir que o processo de Karma pare depois de terminar.

Reagir e Vue

Todas as dependências dos aplicativos React e Vue são capturadas em seu arquivo package.json . Seu arquivo azure-pipelines.yml contém os scripts padrão npm .

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

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

Os arquivos de compilação estão em uma nova pasta, dist para Vue ou build para React. O exemplo a seguir cria um artefato, www, que está pronto para lançamento. O pipeline usa as tarefas Usar Node.js, Copiar arquivo e Publicar artefatos de compilação .

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

Para lançar a aplicação, aponte a tarefa de lançamento para o artefato dist ou build e utilize a tarefa Aplicação Web do Azure.

Pacote Web

Você pode usar um arquivo de configuração do webpack para especificar um compilador, como Babel ou TypeScript, para transpilar JavaScript XML (JSX) ou TypeScript para JavaScript simples e para agrupar seu aplicativo.

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

Criar executores de tarefas

É comum usar Gulp ou Grunt como executores de tarefas para criar e testar aplicativos JavaScript.

Gulp

O Gulp está pré-instalado em agentes hospedados pela Microsoft.

Você pode executar o gulp comando no arquivo de pipeline YAML.

- script: gulp # add any needed options

Se as etapas no arquivo gulpfile.js exigirem autenticação com um registro npm, adicione a tarefa npm authenticate .

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

- script: gulp

Para publicar os resultados do teste JUnit ou xUnit no servidor, adicione a tarefa Publicar resultados do teste .

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

Para publicar resultados de cobertura de código no servidor, adicione a tarefa Publicar resultados de cobertura de código . Você pode encontrar métricas de cobertura no resumo da compilação e pode baixar relatórios HTML para análise adicional.

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

Grunt

O Grunt está pré-instalado em agentes hospedados pela Microsoft.

Você pode executar o grunt comando no arquivo YAML.

- script: grunt # add any needed options

Se as etapas no arquivo Gruntfile.js exigirem autenticação com um registro npm, adicione a tarefa npm authenticate .

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

- script: grunt

Solução de problemas

Se você pode criar seu projeto em sua máquina de desenvolvimento, mas não pode criá-lo no Azure Pipelines, explore as seguintes causas potenciais e ações corretivas.

  • Verifique se as versões do Node.js e do executor de tarefas em sua máquina de desenvolvimento correspondem às do agente.

    Você pode incluir scripts de linha de comando, como node --version em seu pipeline, para verificar as versões instaladas no agente. Use a tarefa Use Node.js para instalar a mesma versão no agente, ou execute os comandos npm install para atualizar as versões da ferramenta.

  • Se suas compilações falharem intermitentemente enquanto você restaura pacotes, o registro npm terá problemas ou haverá problemas de rede entre o data center do Azure e o registro. Explore se o uso de Artefatos do Azure com um registro npm como uma fonte upstream melhora a confiabilidade de suas compilações.

  • Se você estiver usando nvm para gerenciar versões diferentes do Node.js, considere mudar para a tarefa Usar Node.js (UseNode@1 ). nvm é instalado por razões históricas na imagem do macOS. nvm gere várias versões de Node.js adicionando aliases de shell e alterando PATH, que não interage bem com a forma como o Azure Pipelines executa cada tarefa em um novo processo. Para obter mais informações, consulte Execuções de pipeline.

    A Use Node.js tarefa lida com esse modelo corretamente. No entanto, se o seu trabalho exigir o uso de nvm, você poderá adicionar o seguinte script ao início de cada pipeline.

    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"
    

    Em seguida, node e outras ferramentas de linha de comando funcionam para o restante do trabalho de pipeline. Em cada etapa em que você usa o nvm comando, inicie o script com o seguinte código:

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

FAQ

Como posso corrigir uma falha de pipeline com a mensagem 'ERRO FATAL: CALL_AND_RETRY_LAST Falha na alocação - falta de memória no heap do JavaScript'?

Esse tipo de falha ocorre quando o pacote de Node.js excede o limite de uso de memória. Para resolver o problema, adicione uma variável como NODE_OPTIONS e atribua-lhe um valor de --max_old_space_size=16384.

Como posso fazer a versão dos meus pacotes npm como parte do processo de compilação?

Uma opção é usar uma combinação de controle de versão e versão npm. No final de uma execução de pipeline, você pode atualizar seu repositório com a nova versão. O pipeline YAML a seguir tem um repositório GitHub, e o pacote é implantado no npmjs. A compilação falhará se houver uma incompatibilidade entre a versão do pacote no npmjs e o arquivo 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