自定义适用于 Azure Pipelines 的 JavaScript

可以使用 Azure Pipelines 生成 JavaScript 应用,而无需设置自己的任何基础结构。 通常用于生成、测试和运行 JavaScript 应用(如 npm、Node、Yarn 和 Gulp)的工具在 Azure Pipelines 中的 Microsoft 托管代理 上预安装。

有关预安装的 Node.js 和 npm 版本,请参阅 Microsoft 托管的代理。 若要在 Microsoft 托管的代理上安装特定版本的这些工具,请将 Node Tool Installer 任务添加到进程的开头。 还可以使用 自承载 代理。

若要使用 JavaScript 创建第一个管道,请参阅 JavaScript 快速入门

使用特定版本的 Node.js

如果需要尚未安装在 Microsoft 托管代理上的 Node.js 和 npm 版本,请使用 Node 工具安装程序任务。 将以下代码片段添加到 azure-pipelines.yml 文件。

注意

托管代理会定期更新,并且设置此任务会导致每次运行管道时花费大量时间更新到较新的次要版本。 仅在管道中需要特定 Node 版本时才使用此任务。

- task: NodeTool@0 
  inputs:
    versionSpec: '16.x' # replace this value with the version that you need for your project

如果需要已在代理上安装的 Node.js/npm 版本:

  1. 在管道中,选择 “任务”,选择运行生成任务的阶段,然后选择 + 向该阶段添加新任务。

  2. 在任务目录中,查找并添加 节点工具安装程序 任务。

  3. 选择该任务并指定要安装的Node.js运行时的版本。

若要仅更新 npm 工具,请在 npm i -g npm@version-number 生成过程中运行该命令。

使用多个节点版本

可以使用 Node 工具安装程序任务在多个版本的 Node 上生成和测试应用。

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

steps:
- task: NodeTool@0 
  inputs:
    versionSpec: $(node_version)

- script: npm install

请参阅 多配置执行

在生成代理上安装工具

如果项目或package-lock.json文件中有开发依赖项package.json的工具,请通过 npm 安装工具和依赖项。 工具的确切版本在项目中定义,与生成代理上存在的其他版本隔离。

使用 脚本npm 任务

使用脚本通过 package.json 进行安装

- script: npm install --only=dev

使用 npm 任务通过 package.json 进行安装

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

使用 npm npx 包运行程序以这种方式安装工具,检测在路径解析中以这种方式安装的工具。 以下示例调用 mocha 测试运行程序,但在通过 npm install -g) 版本使用全局安装 (之前,查找安装为开发依赖项的版本。

- script: npx mocha

若要安装项目需要但未设置为开发依赖项 package.json的工具,请从管道中的脚本阶段调用 npm install -g

The following example installs the latest version of the Angular CLI by using npm. 然后 ng ,管道的其余部分可以使用其他阶段的工具 script

注意

在 Microsoft 托管的 Linux 代理上,使用 sudo命令开头,如下所示 sudo npm install -g

- script: npm install -g @angular/cli

提示

这些任务每次运行管道时都会运行,因此请注意安装工具对生成时间的影响。 如果开销对生成性能产生严重影响,请考虑使用所需的工具版本配置 自承载代理

在管道中使用 npm命令行 任务在生成代理上安装工具。

管理依赖项

在生成中,使用 Yarn 或 Azure Artifacts 从公共 npm 注册表下载包。 此注册表是在 .npmrc 文件中指定的专用 npm 注册表类型。

使用 npm

可以通过以下方式使用 npm 下载生成包:

  • 直接在管道中运行 npm install ,因为它是在不进行身份验证的情况下从注册表下载包的最简单方法。 如果生成不需要运行代理上的开发依赖项,则可以使用选项npm install加快生成时间--only=prod
  • 使用 npm 任务。 使用经过身份验证的注册表时,此任务非常有用。
  • 使用 npm 身份验证任务。 当你从任务运行程序内部运行 npm install -Gulp、Grunt 或 Maven 时,此任务非常有用。

如果要指定 npm 注册表,请将 URL .npmrc 放入存储库中的文件中。 如果源经过身份验证,请在 Project 设置中的“服务”选项卡上创建 npm 服务连接以管理其凭据。

若要在管道中使用脚本安装 npm 包,请将以下代码片段添加到 azure-pipelines.yml其中。

- script: npm install

若要使用文件中指定的 .npmrc 专用注册表,请将以下代码片段添加到 azure-pipelines.yml

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

若要通过任务运行程序(如 Gulp)将注册表凭据传递给 npm 命令,请在调用任务运行程序之前将 azure-pipelines.yml 以下任务添加到其中。

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

使用管道中的 npmnpm 身份验证 任务下载和安装包。

如果由于从 npm 注册表还原包时偶尔出现连接问题而生成失败,则可以将 Azure Artifacts 与 上游源一起使用,并缓存包。 连接到 Azure Artifacts 时,管道的凭据会自动使用。 这些凭据通常派生自 Project Collection 生成服务 帐户。

如果使用 Microsoft 托管的代理,则每次运行生成时都会获得一台新计算机,这意味着每次还原依赖项,这可能需要大量时间。 若要缓解此问题,可以使用 Azure Artifacts 或自承载代理 - 然后获得使用包缓存的好处。

使用 Yarn

使用脚本阶段调用 Yarn 来还原依赖项。 Yarn 在一些 Microsoft 托管的代理上预安装。 可以像任何其他工具一样在自承载代理上安装和配置它。

- script: yarn install

使用管道中的 CLIBash 任务调用 Yarn

运行 JavaScript 编译器

使用 BabelTypeScripttsc 编译器等编译器将源代码转换为Node.js运行时或 Web 浏览器中可使用的版本。

如果在运行编译器的项目package.json文件中设置了脚本对象,请使用脚本任务在管道中调用它。

- script: npm run compile

可以使用脚本任务直接从管道调用编译器。 这些命令从克隆的源代码存储库的根目录运行。

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

如果你有在项目 package.json 中定义的编译脚本来生成代码,请使用管道中的 npm 任务。 如果没有在项目配置中定义的单独脚本,请使用 Bash 任务编译代码。

运行单元测试

将管道配置为运行 JavaScript 测试,以便生成采用 JUnit XML 格式格式化的结果。 然后,可以使用内置的 发布测试结果 任务发布结果。

如果测试框架不支持 JUnit 输出,请通过合作伙伴报告模块(如 mocha-junit-reporter)添加支持。 可以更新测试脚本以使用 JUnit 记者,或者如果记者支持命令行选项,请将这些选项传递到任务定义中。

下表列出了最常用的测试运行程序和可用于生成 XML 结果的记者:

测试运行程序 记者生成 XML 报告
摩 卡 mocha-junit-reporter
赛普拉斯-多记者
茉莉花 jasmine-记者
开玩笑 jest-junit
jest-junit-reporter
卡玛-朱尼特-记者
Ava tap-xunit

以下示例使用 mocha-junit-reporter ,并使用脚本直接调用 mocha test 。 此脚本在默认位置 ./test-results.xml生成 JUnit XML 输出。

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

如果在项目 package.json 文件中定义了 test 脚本,则可以使用 npm test a0/> 调用它。

- 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@1
  inputs: 
    codeCoverageTool: Cobertura # or JaCoCo
    summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/*coverage.xml'
    reportDirectory: '$(System.DefaultWorkingDirectory)/**/coverage'

使用管道中的 “发布测试结果 ”和 “发布代码覆盖率结果 ”任务,使用伊斯坦布尔发布测试结果和代码覆盖率结果。

设置发布测试结果任务的控件选项以运行该任务,即使上一个任务失败,除非部署被取消。

测试浏览器端到端

使用 ProtractorKarma 等工具在无头浏览器中运行测试。 然后,使用以下步骤将生成的结果发布到 Azure DevOps:

  1. 在生成代理上安装无外设浏览器测试驱动程序(如无头 Chrome 或 Firefox)或浏览器模拟工具(如 PhantomJS)。
  2. 根据工具的文档,将测试框架配置为使用所选的无外设浏览器/驱动程序选项。
  3. 配置测试框架 (通常使用记者插件或配置) 输出 JUnit 格式的测试结果。
  4. 设置脚本任务以运行启动无外设浏览器实例所需的任何 CLI 命令。
  5. 在管道阶段以及单元测试中运行端到端测试。
  6. 使用与单元测试相同的 发布测试结果 任务发布结果。

打包 Web 应用

打包应用程序,将所有应用程序模块与中间输出和依赖项捆绑到可供部署的静态资产中。 在编译和测试之后添加管道阶段,以使用 Angular CLI 运行 webpackng 生成等工具。

第一个示例调用 webpack。 若要执行此操作,请确保将其 webpack 配置为 package.json 项目文件中的开发依赖项。 此操作使用默认配置运行 webpack ,除非项目根文件夹中有一个 webpack.config.js 文件。

- script: webpack

下一个示例使用 npm 任务调用npm run buildbuild在项目 package.json 中定义的脚本对象。 在项目中使用脚本对象会将生成逻辑移入源代码和管道外。

- script: npm run build

使用管道中的 CLIBash 任务调用打包工具,例如webpack或Angularng build

实现 JavaScript 框架

Angular

对于Angular应用,可以包含特定于 Angular 的命令,例如 ng 测试ng 生成ng e2e。 若要在管道中使用 Angular CLI 命令,请在生成代理上安装 angular/cli npm 包

注意

在 Microsoft 托管的 Linux 代理上,使用命令开头 sudo,例如 sudo npm install -g

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

将以下任务添加到管道:

  • npm

    • 命令:custom
    • 命令和参数:install -g @angular/cli
  • npm

    • 命令:install
  • bash

    • 类型:inline
    • 脚本:ng build --prod

对于管道中需要浏览器运行的测试(例如,在运行 Karma 的初学者应用中的 ng 测试 命令),请使用无头浏览器而不是标准浏览器。 在Angular初学者应用中:

  1. browserskarma.conf.js 项目文件中的条目从 browsers: ['Chrome'] 更改为 browsers: ['ChromeHeadless']

  2. singleRunkarma.conf.js 项目文件中的条目从值 false 更改为 true。 此更改有助于确保 Karma 进程在运行后停止。

React和 Vue

React和 Vue 应用的所有依赖项均在 package.json 文件中捕获。 azure-pipelines.yml 文件包含标准Node.js脚本:

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

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

生成文件位于新文件夹中, dist (Vue) 或build (React) 。 此代码片段将生成一个已准备好发布的项目 www。 它使用 节点安装程序复制文件以及 发布生成项目 任务。

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: NodeTool@0
  inputs:
    versionSpec: '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

若要发布,请将发布任务指向 distbuild 项目,并使用 Azure Web 应用部署任务

Webpack

可以使用 Webpack 配置文件指定编译器(如 Babel 或 TypeScript)以将 JSX 或 TypeScript 转译为普通 JavaScript,以及捆绑应用。

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

将以下任务添加到管道:

  • npm

    • 命令:custom
    • 命令和参数:install -g webpack webpack-cli --save-dev
  • bash

    • 类型:inline
    • 脚本:npx webpack --config webpack.config.js

生成任务运行程序

通常使用 GulpGrunt 作为任务运行程序来生成和测试 JavaScript 应用。

Gulp

Gulp 预安装在 Microsoft 托管的代理上。 gulp在 YAML 文件中运行以下命令:

- script: gulp                       # include any additional options that are needed

如果gulpfile.js文件中的步骤需要使用 npm 注册表进行身份验证:

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

- script: gulp                       # include any additional options that are needed

添加 发布测试结果 任务,将 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'

如果应用使用 Gulp 创建管道,最简单的方法是在创建管道时将 Node.js与 gulp 生成模板配合使用。 此模板会自动添加各种任务以调用 Gulp 命令并发布项目。 在任务中,选择“ 启用代码覆盖率” 以使用伊斯坦布尔启用代码覆盖率。

Grunt

Grunt 在 Microsoft 托管的代理上预安装。 若要在 YAML 文件中运行 grunt 命令,请执行以下操作:

- script: grunt                      # include any additional options that are needed

如果文件中的步骤 Gruntfile.js 需要使用 npm 注册表进行身份验证:

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

- script: grunt                      # include any additional options that are needed

如果应用使用 Grunt 创建管道,最简单的方法是在创建管道时将 Node.js与 Grunt 生成模板配合使用。 这会自动添加各种任务来调用 Gulp 命令和发布项目。 在任务中,选择“ 发布到 TFS/Team Services ”选项以发布测试结果,然后选择“ 启用代码覆盖率” 以使用伊斯坦布尔启用代码覆盖率。

打包并交付代码

生成并测试应用后,可以将生成输出上传到 Azure Pipelines、创建和发布 npm 或 Maven 包,或将生成输出打包到.zip文件中,以便部署到 Web 应用程序。

将文件发布到 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 供其他项目使用的模块,而不是 Web 应用程序,请使用 npm 任务将模块发布到本地注册表或公共 npm 注册表。 每次发布时提供唯一的名称/版本组合。

示例

第一个示例假设你通过对版本控制中的文件所做的更改package.json来管理版本信息 (,例如通过 npm 版本) 。 以下示例使用脚本任务发布到公共注册表。

- 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 包进行版本控制?

部署 Web 应用

若要创建可供发布到 Web 应用的.zip文件存档,请使用 存档文件 任务:

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

若要将此存档发布到 Web 应用,请参阅 Azure Web 应用部署

将项目发布到 Azure Pipelines

使用 “发布生成项目”任务 将文件从生成发布到 Azure Pipelines。

发布到 npm 注册表

若要创建和发布 npm 包,请使用 npm 任务。 有关版本控制和发布 npm 包的详细信息,请参阅 发布 npm 包

部署 Web 应用

若要创建可供发布到 Web 应用的.zip文件存档,请使用 存档文件任务。 若要将此存档发布到 Web 应用,请参阅 Azure Web 应用部署

生成映像并将其推送到容器注册表

源代码成功生成并且单元测试就位且成功后,还可以 生成映像 并将其 推送到容器注册表

疑难解答

如果可以在开发计算机上生成项目,但在 Azure Pipelines 上生成项目时遇到问题,请浏览以下潜在原因和纠正措施:

  • 检查开发计算机上的 Node.js 版本和任务运行程序是否与代理上的版本匹配。 可以在管道中包含命令行脚本,以 node --version 检查代理上安装的内容。 如本指南中所述,请使用 Node Tool Installer (,) 在代理上部署同一版本,或运行 npm install 命令将工具更新为所需版本。

  • 如果在还原包时生成间歇性失败,npm 注册表出现问题,或者 Azure 数据中心和注册表之间存在网络问题。 我们无法控制这些因素。 了解如何将 Azure Artifacts 与 npm 注册表配合使用作为上游源来提高生成的可靠性。

  • 如果使用 nvm 管理不同版本的Node.js,请考虑改为切换到 Node Tool Installer 任务。 nvm (由于 macOS image.) nvm通过添加 shell 别名和更改PATH来管理多个Node.js版本,这与 Azure Pipelines 在新进程中运行每个任务的方式交互不佳。

    Node Tool Installer 任务可正确处理此模型。 但是,如果你的工作需要使用 nvm,则可以将以下脚本添加到每个管道的开头:

    steps:
    - bash: |
        NODE_VERSION=16  # or whatever your preferred version is
        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>
    

常见问题解答

问:在哪里可以了解有关 Azure Artifacts 和包管理服务的详细信息?

答: Azure Artifacts 中的包管理

问:我可以在哪里了解有关任务的详细信息?

答: 生成、发布和测试任务

问:如何实现修复管道故障,并显示消息“严重错误:CALL_AND_RETRY_LAST分配失败 - JavaScript 堆内存不足”?

答:当Node.js包超出内存使用量限制时,会发生此故障类型。 若要解决此问题,请添加一个变量,例如 NODE_OPTIONS ,并为其赋值 --max_old_space_size=16384

问:如何在生成过程中对 npm 包进行版本控制?

答:一个选项是结合使用版本控件和 npm 版本。 在管道运行结束时,可以使用新版本更新存储库。 在此 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: NodeTool@0
  inputs:
    versionSpec: '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