Appveyor配置.NET MVC+Angular构建遇npm install错误求解决方案
看起来你遇到的核心问题有两个:一是PowerShell命令的会话隔离导致路径切换失效,二是老旧的Node.js版本引发的npm兼容性问题。咱们一步步来解决:
1. 修复PowerShell路径切换的核心问题
在AppVeyor中,每个ps:开头的命令都是在独立的PowerShell会话中执行的。你之前的写法:
- ps: cd angular - ps: npm install
其实npm install是在项目根目录执行的——因为第一个cd angular只在当前会话生效,下一个ps:命令会回到初始目录,自然找不到angular文件夹里的package.json,这就是404错误的根源!
解决方法:把多个PowerShell命令合并成一个会话,用Push-Location/Pop-Location保持上下文,或者用分号串联命令:
- ps: Push-Location angular; npm install; npm run build; Pop-Location
2. 升级Node.js版本
Node.js 8已经停止维护多年,很多npm包不再支持这个版本,容易出现诸如tar相关的奇怪警告。建议换成长期支持(LTS)版本,比如18.x:
environment: nodejs_version: "18"
3. 用npm ci替代npm install(推荐)
在CI环境中,npm ci比npm install更稳定:它会严格按照package-lock.json的版本安装依赖,避免版本不一致的问题,还能加快安装速度:
- ps: Push-Location angular; npm ci; npm run build; Pop-Location
4. 确保Angular构建产物被.NET项目包含
记得在Angular的angular.json里把outputPath设置为.NET项目的wwwroot目录(比如../something/wwwroot),这样.NET构建时会自动把Angular的静态文件打包进去。
修改后的完整AppVeyor配置
这里给出调整后的YAML,重点优化了before_build部分和Node版本:
# Project configuration version: $(versionNumber)-{branch}.{build} # Location of the cloned repo on the build server clone_folder: c:\projects\something # Environment Variables environment: nodejs_version: "18" # 升级到LTS版本 versionNumber: "1.9.0" devpackageVersion: "$(versionNumber)-alpha.$(APPVEYOR_BUILD_NUMBER)" relpackageVersion: "$(versionNumber).$(APPVEYOR_BUILD_NUMBER)" buildFolder: "$(APPVEYOR_BUILD_FOLDER)" # Install scripts. (runs after repo cloning) install: # Get the latest stable version of Node.js - ps: Install-Product node $env:nodejs_version # branches to build branches: only: - develop - /releases.*/ - /features.*/ - /bugfixes.*/ - /hotfixes.*/ # Nuget Restore nuget: # Retrieve packages from account feed account_feed: true # Retrieve packages from project feed project_feed: true image: Visual Studio 2017 # Build configuration platform: Any CPU configuration: Release # Step to execute before build before_build: # 合并PowerShell命令,保持路径上下文,同时执行npm install和build - ps: | Push-Location angular npm ci # 用ci替代install更适合CI环境 npm run build -- --configuration production # 指定生产环境构建 Pop-Location # Restore Nuget packages - cmd: nuget restore something.sln -Verbosity quiet # Step to build the solution build: parallel: true # Visual Studio solution to build project: something.sln verbosity: minimal # Conditional configuration depending on branch for: - branches: only: - develop - /features.*/ - /bugfixes.*/ # Powershell to pack files for Octopus after_build: - ps: octo pack --id=something.something --version="$env:devpackageVersion" --basePath="$env:buildFolder"\something\ --outFolder="$env:buildFolder"\packages\ # Step to create the artifact in AppVeyor artifacts: # Path to the packages created above - path: 'packages\*.nupkg' # Step to orchestrate Octopus Deploy deploy: - provider: Octopus push_packages: true create_release: true project: something create_release_advanced: --releaseNumber=$(devpackageVersion) deploy_release: true environment: QA server: https://something api_key: something deploy_wait: false push_packages_advanced: --ignoreSslErrors # Conditional configuration depending on branch - branches: only: - /releases.*/ - /hotfixes.*/ # Powershell to pack files for Octopus after_build: - ps: octo pack --id=something.something --version="$env:relpackageVersion" --basePath="$env:buildFolder"\something\ --outFolder="$env:buildFolder"\packages\ # Step to create the artifact in AppVeyor artifacts: # Path to the packages created above - path: 'packages\*.nupkg' # Step to orchestrate Octopus Deploy deploy: - provider: Octopus push_packages: true create_release: true project: something create_release_advanced: --releaseNumber=$(relpackageVersion) deploy_release: true environment: QA server: https://something api_key: something deploy_wait: false push_packages_advanced: --ignoreSslErrors
额外排查点
如果还是有问题,可以在before_build里加一步打印当前目录和文件列表,确认路径是否正确:
- ps: Get-Location; Get-ChildItem
这样能直观看到当前所在目录和文件,方便排查package.json是否存在。
内容的提问来源于stack exchange,提问作者Harry Blue

