本文介绍 Azure Pipelines 如何与 JavaScript 应用配合使用。 Microsoft托管的代理 预安装常见的 JavaScript 生成、测试和部署工具,例如 npm、Node.js、Yarn 和 Gulp,而无需设置任何基础结构。 还可以配置 自承载代理。
若要快速创建适用于 JavaScript 的管道,请参阅 JavaScript 快速入门。
节点工具安装程序
若要安装未预安装的 Node.js 和 npm 版本,或在自承载代理上安装这些工具:
- 在你的管道中,运行 npm 的
npm i -g npm@version-number命令。 - 对于 Node.js,请将 Use Node.js 生态系统 v1 (UseNode@1) 任务添加到管道。
若要安装特定的 Node.js 版本,请将以下代码添加到 azure-pipelines.yml 文件中:
- task: UseNode@1
inputs:
version: '16.x' # replace with the version you need
注意
每次运行管道时,这项任务可能需要大量时间来更新到较新的次要版本。 Microsoft托管代理定期更新,因此请仅使用此任务安装未预安装的特定 Node 版本。 若要了解Microsoft托管代理上预安装的 Node.js 和 npm 版本,请参阅 软件。
使用多个节点版本
可以使用具有策略的 “使用 Node.js 生态系统 v1 ”任务 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 。 以下示例使用 安装最新版本的 npm。 然后,管道中的其他脚本可以使用 Angular ng 命令。
- script: npm install -g @angular/cli
注意
在 Microsoft 托管的 Linux 代理上,在命令前面加上 sudo,例如 sudo npm install -g。
这些工具安装任务每次运行管道时都会运行,因此请注意它们对生成时间的影响。 如果开销严重影响构建性能,请考虑使用具有所需工具版本的预配置的自承载代理。
注意
每次运行管道时,这些工具安装任务都会执行,因此请注意它们可能对构建时间造成的影响。
依赖包下载
可以使用 Yarn 或 Azure Artifacts 从公共 npm 注册表或 你在 *.npmrc 文件中指定的专用 npm 注册表下载包。 若要指定 npm 注册表,请将其 URL 添加到代码存储库中的 *.npmrc 文件。
使用 npm
可以通过以下方式使用 npm 在管道中下载生成包:
- 若要以最简单的方式下载不进行身份验证的包,请直接运行
npm install。 - 若要使用经过身份验证的注册表,请添加 npm 任务。
- 若要从任务运行程序 Gulp、Grunt 或 Maven 内部运行
npm install,请使用 npm 身份验证 任务。
注意
如果 npm 源使用身份验证,则必须在 Azure DevOps 项目设置中的“服务”选项卡上创建 npm 服务连接来管理其凭据。
若要直接安装 npm 包,请在 azure-pipelines.yml中使用以下脚本。 如果您的生成代理不需要开发依赖项,可以通过在 npm install 中添加 --only=prod 选项来加快生成时间。
- script: npm install --only=prod
若要使用 *.npmrc 文件中指定的专用注册表,请将 Npm@1 任务添加到 azure-pipelines.yml。
- task: Npm@1
inputs:
customEndpoint: <Name of npm service connection>
若要通过任务运行程序(如 Gulp)将注册表凭据传递给 npm 命令,请在调用任务运行程序之前将 npmAuthenticate@0 任务添加到 azure-pipelines.yml 。
- task: npmAuthenticate@0
inputs:
customEndpoint: <Name of npm service connection>
注意
Microsoft托管的代理 在每次构建中使用新计算机。 还原依赖项可能需要很长时间。 若要缓解此问题,可以将 Azure Artifacts 或自承载代理与包缓存配合使用。
如果由于连接问题导致从 npm 注册表还原包时构建偶尔失败,您可以使用 Azure Artifacts 结合 上游源 来缓存这些包。 Azure Artifacts 自动使用管道的凭据,这些凭据通常派生自 Project Collection 生成服务 帐户。
注意
还原依赖项可能需要很长时间。 若要缓解此问题,可以将 Azure Artifacts 或自承载代理与包缓存配合使用。
如果偶尔因为从 npm 注册表还原包时的连接问题导致生成失败,您可以使用 Azure Artifacts 和 上游源 来缓存这些包。 Azure Artifacts 自动使用管道的凭据,这些凭据通常派生自 Project Collection 生成服务 帐户。
使用 Yarn
使用脚本安装 Yarn 来还原依赖项。 Yarn 预安装在某些 Microsoft托管代理上。 可以像任何其他工具一样在自承载代理上安装和配置 Yarn。
- script: yarn install
还可以在管道中使用 CLI 或 Bash 任务来调用 Yarn。
JavaScript 编译器
JavaScript 应用使用编译器(如 Babel 和 TypeScripttsc 编译器)将源代码转换为 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 cypress-multi-reporters |
| 茉莉花 | jasmine-reporters |
| Jest |
jest-junit jest-junit-reporter |
| Karma | karma-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 来调用它。
- 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 等工具在无外设浏览器中运行测试,然后发布测试结果。 若要配置浏览器测试和发布结果,请执行以下步骤:
- 在生成代理上安装无外设浏览器测试驱动程序(如无外设 Chrome 或 Firefox)或浏览器模拟工具(如 PhantomJS)。
- 根据工具的文档,将测试框架配置为使用你的无头浏览器或驱动程序选项。
- 将测试框架配置为输出 JUnit 格式的测试结果,通常通过报告插件或配置来实现。
- 添加脚本或 CLI 任务以启动无外设浏览器实例。
- 在管道阶段以及单元测试中运行端到端测试。
- 使用相同的发布测试结果任务,连同单元测试一起 发布结果 。
打包和交付
生成并测试应用后,可以:
- 将生成输出上传到 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 注册表。 每次发布时提供唯一的名称/版本组合。
以下示例使用脚本发布到公共 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 应用
可以将应用程序打包为将所有模块与中间输出和依赖项捆绑到可供部署的静态资产中。 编译和测试后添加管道阶段,以运行 Webpack 或 Angular CLI ng 生成等工具。
以下示例调用 webpack。 若要使此过程正常工作,请确保 webpack 在 package.json 项目文件中配置为开发依赖项。 此脚本使用默认配置运行 webpack ,除非项目根文件夹中有 webpack.config.js 文件。
- script: webpack
以下示例使用 npm run build 来调用项目 package.json 文件中定义的 build 脚本对象。 在项目中使用脚本对象会将生成逻辑移到源代码中,然后移出管道。
- script: npm run build
还可以在管道中使用 CLI 或 Bash 任务来调用打包工具,例如 webpack 或 Angular ng build。
若要创建准备发布到 Web 应用的 *.zip 文件存档,请使用 存档文件 任务。
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
includeRootFolder: false
若要将此存档发布到 Web 应用,请参阅 使用 Azure Pipelines 部署到 Azure 应用服务。
JavaScript 框架
可以在管道中安装包以支持各种 JavaScript 框架。
Angular
对于 Angular 应用,可以运行特定于 Angular 的命令,例如 ng test, ng build和 ng e2e。 要在管道中使用 Angular CLI 命令,请在生成代理上安装 angular/cli npm 包。
- script: |
npm install -g @angular/cli
npm install
ng build --prod
注意
在 Microsoft 托管的 Linux 代理上,在命令前面加上 sudo,例如 sudo npm install -g。
对于在管道中需要浏览器运行的测试(例如以 ng test 命令运行 Karma),请使用无头浏览器而不是标准浏览器。 在 Angular 启动器应用中:
- 将
browsers项目文件中的 条目从browsers: ['Chrome']更改为browsers: ['ChromeHeadless']。 - 将
singleRun项目文件中的 条目从false更改为true。 此更改有助于确保 Karma 进程在运行后停止。
React 和 Vue
React 和 Vue 应用的所有依赖项都在 package.json 文件中捕获。
azure-pipelines.yml文件包含标准npm脚本。
- script: |
npm install
displayName: 'npm install'
- script: |
npm run build
displayName: 'npm build'
生成文件位于新文件夹中,Vue 使用 dist,而 React 使用 build。 以下示例生成一个可供发布的项目 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 Web 应用 任务。
Webpack
可以使用 Webpack 配置文件来指定编译器(如 Babel 或 TypeScript),将 JavaScript XML(JSX)或 TypeScript 转译为普通 JavaScript,以及捆绑应用。
- script: |
npm install webpack webpack-cli --save-dev
npx webpack --config webpack.config.js
生成任务运行程序
通常使用 Gulp 或 Grunt 作为任务运行程序来生成和测试 JavaScript 应用。
Gulp
Gulp 预安装在Microsoft托管代理上。
可以在 YAML 管道文件中运行 gulp 该命令。
- 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 预安装在Microsoft托管的代理上。
可以在 YAML 文件中运行 grunt 命令。
- script: grunt # add any needed options
如果 Gruntfile.js 文件中的步骤需要使用 npm 注册表进行身份验证,请添加 npm 身份验证 任务。
- task: npmAuthenticate@0
inputs:
customEndpoint: <Name of npm service connection>
- script: grunt
Troubleshooting
如果可以在开发计算机上生成项目,但无法在 Azure Pipelines 中生成项目,请浏览以下潜在原因和纠正措施。
检查开发计算机上的 Node.js 版本和任务运行程序是否与代理上的版本匹配。
可以在管道中包含诸如
node --version的命令行脚本,以便检查代理上安装的版本。 使用Use Node.js任务在代理上安装同一版本,或运行npm install命令来更新工具版本。如果在还原包时,生成会出现间歇性失败,则可能是 npm 注册表出现问题,或者 Azure 数据中心与注册表之间存在网络连接问题。 了解将 Azure Artifacts 与 npm 注册表一起使用作为上游源是否可以提高生成的可靠性。
如果使用
nvm管理不同版本的 Node.js,请考虑改为切换到 “使用 Node.js”(UseNode@1) 任务。nvm在 macOS 映像中是为了历史原因而安装的。nvm通过添加 shell 别名和更改PATH来管理多个 Node.js 版本,这与 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>
FAQ
如何修复管道故障,并显示消息“严重错误: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: 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
相关内容
- 有关 Azure Artifacts 和包管理服务的详细信息,请参阅 Azure Artifacts 中的包管理。
- 有关任务的详细信息,请参阅 生成、发布和测试任务。