【问题标题】:Always remove Angular dist folder contents with WebDeploy on Destination始终使用目标上的 WebDeploy 删除 Angular dist 文件夹内容
【发布时间】:2018-09-20 09:02:35
【问题描述】:

我们在 Angular 5 上有一个带有 ASP.NET 后端的单页应用程序,当我们编译它时,Angular 的发布内容会输出到文件夹“Project\dist”。

这在本地开发机器上效果很好,但是所有的 dist 文件都是随机命名的,例如:

  • polyfills.dc7175a7225af84b3c9b.bundle.js
  • styles.dc7175a7225af84b3c9b.bundle.js
  • inline.dc7175a7225af84b3c9b.bundle.js

当我们使用 Web Publishing 部署到登台或生产时,一切都很好地传输,并且我们在发布配置文件中的自定义文件夹被包含并发布。

但是,在目标服务器(暂存或生产)上,这些旧的、随机命名的文件和旧的(不再使用的)文件夹仍然存在。这会导致成百上千的旧文件(来自旧网络部署)在登台和生产服务器上累积。每次我们使用 webdeploy 推送更新时,我都需要一种方法来自动删除这些内容。

理想情况下,工作流程是:

  • 选择发布配置文件,点击发布
  • 输入我的凭据
  • 应用构建成功
  • 如果应用程序构建成功,我们将删除目标服务器上的“Project\dist”文件夹。例如,“项目”可以在 c:\inetpub\www\project 或 d:\websites\Project 中。
  • 已复制更新的文件
  • Web 部署执行并复制 dist 文件夹中的自定义文件(已经工作)。

这是我们当前发布配置文件的修订版本:

<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <MSDeployServiceURL>staging.example.com</MSDeployServiceURL>
    <DeployIisAppPath>Project</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
    <EnableMSDeployBackup>False</EnableMSDeployBackup>
    <UserName>WebDeployUser</UserName>
    <PublishDatabaseSettings>
      <Objects xmlns="">
      </Objects>
    </PublishDatabaseSettings>
    <ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
  </PropertyGroup>
  <Target Name="CustomCollectFiles">
    <ItemGroup>
      <_CustomFiles Include="..\Project\dist\**\*" />

      <FilesForPackagingFromProject  Include="%(_CustomFiles.Identity)">
        <DestinationRelativePath>dist\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
  </Target>
  <PropertyGroup>
    <CopyAllFilesToSingleFolderForPackageDependsOn>
      CustomCollectFiles;
      $(CopyAllFilesToSingleFolderForPackageDependsOn);
    </CopyAllFilesToSingleFolderForPackageDependsOn>

    <CopyAllFilesToSingleFolderForMsdeployDependsOn>
      CustomCollectFiles;
      $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
    </CopyAllFilesToSingleFolderForMsdeployDependsOn>
  </PropertyGroup>
</Project>

我已经尝试了一些公认的答案解决方案,但无法使其正常工作:

有什么想法吗?除了在 IIS 中进行设置之外,我对 Web 部署的了解基本上为零。

最好, 克里斯

编辑我也试过这个:(基于此:https://stackoverflow.com/a/15113445/559988

  <Target Name="CleanFolder">

    <PropertyGroup>
      <TargetFolder>$(_MSDeployDirPath_FullPath)\dist</TargetFolder>
    </PropertyGroup>

    <ItemGroup>
      <FilesToClean Include="$(TargetFolder)\**\*"/>
      <Directories Include="$([System.IO.Directory]::GetDirectories('$(TargetFolder)', '*', System.IO.SearchOption.AllDirectories))"
                   Exclude="$(TargetFolder)"/>
    </ItemGroup>

    <Delete Files="@(FilesToClean)" ContinueOnError="true"/>
    <RemoveDir Directories="@(Directories)" />
  </Target>

更新 这就是我们正在做的事情:https://docs.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/deploying-extra-files

那里的第一条评论与我们遇到的问题相同: 这在部署 Angular 分发文件时非常方便 使用 ASP.Net 后端,只要 SPA 和后端共享相同 单个虚拟应用程序。不幸的是,由于浏览器缓存 破坏技术,用于 Angular 部署的捆绑文件将 总是带有唯一的名称,因此,一个 msbuild 命令/属性或其他可能性将文件夹擦除干净 IIS 端在发送更新文件之前会非常欢迎。如果 有人找到了方法,请分享。

此处为 msdeploy 描述的“同步”功能正是我们需要做的,但我不知道如何挂钩: https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd569034(v=ws.10)#sync

在同步操作中,如果源文件或文件夹不存在于 目的地,提供者创建文件夹和任何子文件夹 具有相应的文件和属性。如果目的地 文件夹已经存在,提供者只更新那些对象 与来源不符。这意味着在某些情况下只有一个文件或 文件夹将被更新。目标上不存在的文件 源将被删除。源文件夹和目标文件夹 contentPath 不必具有相同的名称。如果名称 目标文件夹与源文件夹不同, 目标文件夹将保持不变,但 文件夹将更新为源文件夹。

【问题讨论】:

  • 您如何在没有哈希的情况下构建生产环境:ng build --prod --output-hashing none?我能想到的唯一缺点是服务工作者不会正确缓存应用程序。
  • 用户可能使用的是旧版本,因为浏览器认为它仍然正确。
  • 大家好,感谢您的回复! @Phil -- 不幸的是,我们需要输出散列创建的缓存破坏目的。
  • @RobinDijkhof -- 问题不是缓存或最终用户,而是旧文件保留在磁盘上,因为 web 部署不会覆盖它们,因为文件凭借“输出哈希”的名称不同.这里的解决方案应该侧重于利用 web deploy 在发布时清空文件夹,然后发布所有新的本地文件。
  • 可以,但不使用输出哈希会。

标签: asp.net-mvc angular msbuild webdeploy microsoft-web-deploy


【解决方案1】:

请尝试在发布配置文件中进行设置

 <SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>

【讨论】:

  • 如何将其应用到特定文件夹,例如。只删除“Project\dist”文件夹?
  • 你是否使用 TFS 发布前端应用程序?
  • 不,我们使用 npm 构建生产的 AOT 文件集。然后我在这里使用了自定义文件方法:docs.microsoft.com/en-us/aspnet/web-forms/overview/deployment/… 在 Visual Studio 中通过 Web 部署发布这些文件
  • 我尝试将其放置在 CustomCollectFiles 的 内的 中,它只是删除了目标上不受欢迎的所有内容。
  • 您的网络服务器 IIS?可以用 ftp 发布前端应用吗?)我们使用这种方式,因为前端和后端应用不同的项目。
【解决方案2】:

如果我理解正确,那么解决这个问题是帮助发布配置文件中的DeleteExistingFiles 属性。

<DeleteExistingFiles>True</DeleteExistingFiles>

如果设置为 True,输出目录 (publishUrl) 将被清除 在将输出写入它之前,最好从一个干净的开始 石板。


如何将它应用到特定文件夹,例如。只删除 “Project\dist”文件夹?

据我所知,此属性的结果是删除所有文件。要指定要删除的目录,您可以尝试 MSDeploy 中的动词 delete,它可以包含在自定义脚本的 &lt;Exec&gt; 任务中:

<Exec Command="$(MSDeploy) -verb:delete -dest:&quot;ContentPath=D:\TestDir\Test.txt&quot"/>

/* 
 * $(MSDeploy) is path to MSDeploy binary that you passed to script.                                                                     
 */

此示例显示在本地计算机上删除文件。您应该自定义自己的调用。


Exec Task | How to create a Web Deploy package when publishing a ClickOnce project(一些使用目标的sn-ps)

【讨论】:

  • 如何将其应用到特定文件夹,例如。只删除“Project\dist”文件夹?
  • 你能帮我写下任务吗? (我不明白如何将您显示的 msdeploy 命令转换为 exec 任务)
  • 我想我们已经接近了!我在 PropertyGroup 中添加了这个键:"C:\Program Files (x86)\iis\Microsoft Web Deploy V3\msdeploy.exe" 我运行您指定的命令(修复了引号位置): 但是我收到错误:(太长,无法在评论中发布)pastebin.com/5QhPvWmw 基本上是这些错误:EXEC(0,0):错误代码:FileOrFolderNotFound EXEC(0,0):错误:设备未准备好。 EXEC(0,0):错误计数:1。
  • 按照说明(此处:link),我将其与硬编码的用户名和密码一起使用。 (这并不理想,但我猜总比没有好)。 &lt;Exec Command="$(MSDeployPath) -verb:delete -dest:ContentPath=&amp;quot;D:\Website\dist&amp;quot;,computerName=Server,username=Admin,password=Password"/&gt;关于如何锁定它的任何想法,所以我没有这个用户名/源代码/明文传递?我在没有用户/密码的情况下尝试过,但出现错误 ERROR_USER_NOT_ADMIN (401) Unauthorized
  • 有趣的是,如果我确实指定了“管理员”以外的用户(即使该用户在管理员组中并被授权为 Web 部署用户),我最终也会遇到同样的问题:ERROR_USER_NOT_ADMIN (401)未经授权。有什么想法吗?
【解决方案3】:

在使用 nodejs 时,我们将使用 'ng build --output-hashing=false' 来处理这个问题。也许你可以在这个范围内搜索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-30
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多