始终使用 WebDeploy on Destination 删除 Angular dist 文件夹内容

Always remove Angular dist folder contents with WebDeploy on Destination

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

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

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

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

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

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

<?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 部署的了解基本上为零。

最好的, 克里斯

编辑 我也试过这个:(基于此:)

  <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

The first comment from there is the same problem we're experiencing: This comes very handy in deploying Angular distribution files along with ASP.Net backend, whenever both SPA and the backend share the same single virtual application. Unfortunately, due to browser cache busting techniques, the bundle files for Angular deployment will always ship with unique names and, therefore, an msbuild command/attribute or other possibility to wipe the folder clean on the IIS side before sending the updated files would be very welcomed. If anyone has found a way to do that, please share.

"Sync" 此处为 msdeploy 描述的功能正是我们需要做的,但我不知道如何连接到这里: https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd569034(v=ws.10)#sync

In a sync operation, if the source file or folder does not exist on the destination, the provider creates the folder and any subfolders that have the corresponding files and attributes. If the destination folder already exists, the provider updates only those objects that do not match the source. This means that in some cases only one file or folder will be updated. Files on the destination that do not exist on the source will be deleted. The source and destination folders for contentPath do not have to have the same name. If the name of the destination folder differs from that of the source, the name of the destination folder will remain the same, but the contents of the folder will be updated to those of the source.

请尝试在发布配置文件中设置此项

 <SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>

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

<DeleteExistingFiles>True</DeleteExistingFiles>

If set to True the output directory (publishUrl) will be purged before output is written to it, it's good to start out with a clean slate.


How can I apply this to a specific folder, ex. only delete the "Project\dist" folder?

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

<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(使用目标的一些片段)

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