У меня довольно простое веб-приложение на основе шаблона Visual Studio "React". Когда я запускаю MSBuild, он запускает npm install
, а затем вызывает webpack
для создания Javascript пакета. Когда я строю это локально, приложение работает нормально. Когда я строю это в конвейере DevOps, домашняя страница представляет собой пустую белую страницу с ошибками скрипта в консоли:
Я действительно сомневаюсь в ошибке имеет большое значение, и я бы даже не стал знать, где его искать. Тем не менее, после небольшого исследования вот что я знаю до сих пор:
- Исходный код, который я создаю локально, и исходный код, который создает DevOps, точно такой же.
- Я проверил
package.json
и package-lock.json
точно так же. - Я сделал diff для каталога
node_modules
локально и в DevOps , Каждый файл в каждом каталоге абсолютно одинаков. У меня npm install
одинаковые точные версии всего. - И моя локальная машина, и DevOps используют
node 12.10.0
- Это не веб-сервер. Если я заархивирую свои локально созданные файлы и загрузлю их на веб-сервер, это сработает.
Вот мой package.json
файл:
{
"name": "LimeadeDocs",
"version": "0.1.0",
"private": true,
"dependencies": {
"bootstrap": "^3.4.1",
"core-js": "^3.1.4",
"js-yaml": "^3.13.1",
"mobx": "^5.13.0",
"mobx-react": "^6.1.3",
"react": "^16.9.0",
"react-bootstrap": "^0.31.5",
"react-dom": "^16.9.0",
"react-is": "^16.9.0",
"react-router-bootstrap": "^0.24.4",
"react-router-dom": "^4.2.2",
"react-scripts": "1.0.17",
"redoc": "2.0.0-rc.14",
"rimraf": "^2.6.2",
"styled-components": "^4.4.0",
"swagger-diff": "^0.6.0"
},
"scripts": {
"start": "rimraf ./build && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Вот мой конвейер сборки DevOps :
trigger:
- master
pool:
vmImage: 'windows-latest'
variables:
buildConfiguration: 'Debug'
steps:
- task: UseNode@1
displayName: 'Install Node 12.10.0'
inputs:
version: '12.10.0'
- task: NuGetCommand@2
displayName: 'Restore NuGet Packages'
inputs:
command: 'restore'
restoreSolution: './LimeadeDocs.sln'
- task: MSBuild@1
inputs:
solution: './LimeadeDocs.sln'
platform: 'Any CPU'
configuration: '$(BuildConfiguration)'
msbuildArguments: '/t:publish'
- task: PublishBuildArtifacts@1
displayName: 'Publish Build Artifacts'
inputs:
PathtoPublish: '$(Build.SourcesDirectory)/LimeadeDocs/bin/$(BuildConfiguration)/netcoreapp2.1/publish/'
ArtifactName: 'Website'
condition: succeededOrFailed()
Вот файл CSPROJ, который он строит:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
<SpaRoot>ClientApp\</SpaRoot>
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<!-- Don't publish the SPA source files, but do show them in the project files list -->
<Content Remove="$(SpaRoot)**" />
<None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
</ItemGroup>
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
<!-- Ensure Node.js is installed -->
<Exec Command="node --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<DistFiles Include="$(SpaRoot)build\**" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
</Project>
Итак, в итоге, если я запускаю msbuild .\LimeadeDocs.sln /t:publish
из моей командной строки, заархивирую содержимое \bin\Debug\netcoreapp2.1\publish
и бросьте его на веб-сервер, он работает. Однако при развертывании содержимого артефакта Website , встроенного в DevOps, я получаю ошибку сценария.
Я также запустил diff между файлом комплекта. js, созданным локально, и файлом один DevOps производит. Есть огромных различий, поэтому я не совсем уверен, что это может объяснить. Изначально казалось, что разные версии пакетов устанавливаются локально, чем в DevOps, но я сделал все, что мог, чтобы показать, что это не так. Итак, механизм связывания, который берет все эти пакеты и создает гигантский комплект. js Файл должен работать по-разному в DevOps, как это происходит локально. Тем не менее, это все тот же код. Я довольно застрял в том, где go отсюда.