【问题标题】:How do I exclude a folder from a project but not from publish?如何从项目中排除文件夹但不从发布中排除?
【发布时间】:2017-06-08 03:11:21
【问题描述】:

我已将一个 asp.net 核心项目迁移到 VS2017 RC,它现在支持从项目中排除文件的功能。我排除了两个文件夹,它们将这些行添加到我的 csproj 文件中:

<ItemGroup>
  <Content Remove="wwwroot\dist\**" />
  <Content Remove="wwwroot\lib\**" />
</ItemGroup>

这很好用,但现在这些文件不再发布。如何从项目中排除这些文件夹,但在发布时仍然包含它们?

【问题讨论】:

  • 问个问题,如果您希望它们被发布,为什么要将它们排除在项目之外?
  • @DavidG 这样它们就不会被 Visual Studio 在文件中查找、在解决方案资源管理器中显示等拾取。它们是缩小的 javascript/css 文件和外部库。
  • 那么最好把它们隐藏起来。 DnxInvisibleFolder 还能用吗?例如:&lt;ItemGroup&gt;&lt;DnxInvisibleFolder Include="wwwroot\dist\" /&gt;&lt;/ItemGroup&gt;。虽然我仍然不明白你为什么关心不在那里展示它们。
  • 不,这不起作用。我很在意,因为 Visual Studio 在文件中查找可能需要很长时间,并且会从外部库或缩小文件中返回数百个搜索字符串的结果。
  • 你可以在VS中右键单击文件夹并隐藏它吗?这就是以前的工作方式。

标签: msbuild asp.net-core visual-studio-2017


【解决方案1】:

以下从 dotnet new spa 模板中获取的 msbuild 项目帮助我实现了我相信您所追求的目标:

<ItemGroup>
    <Content Remove="wwwroot\dist\**" />
    <Content Remove="wwwroot\lib\**" />
</ItemGroup>

<Target Name="GiveAName" AfterTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec Command="npm install" />
    <Exec Command="npm etc etc do your stuff" />
    <Exec Command="or webpack" />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
        <DistFiles Include="wwwroot\dist\**; wwwroot\lib\**" />
        <ResolvedFileToPublish Include="@(DistFiles-&gt;'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
            <RelativePath>%(DistFiles.Identity)</RelativePath>
            <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        </ResolvedFileToPublish>
    </ItemGroup>
</Target>

【讨论】:

  • 我刚刚在 VS2017 (v15.3.5) 上测试了这个,它可以工作。谢谢!作为旁注,我删除了 npm 的东西,因为我不需要它。
  • 不用担心。仅供参考,我还删除了 npm 命令,发现在 VS 之外处理前端任务效率更高。
  • 我试图让它工作,但是对于我的 .net 项目之外的 npm 构建目录(后端位于一个文件夹中,并且在部署期间,从第二个文件夹捆绑 UI 资源)。即我的 dist 文件看起来像 但是我正在努力收集任何输出......我不明白 inlcude distfiles -> fullpath 的语法?有其他人尝试过这种文件夹结构吗?
【解决方案2】:

我通过将以下行添加到 csproj 文件中的 PrepublishScript 目标来解决此问题,因为似乎还没有一种优雅的方法来做到这一点。

<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
  <!-- Other things here already -->
  <ItemGroup>
    <Lib Include="wwwroot/lib/**;" />
    <Dist Include="wwwroot/dist/**;" />
  </ItemGroup>
  <Copy SourceFiles="@(Lib)" DestinationFolder="$(PublishDir)\wwwroot\lib\%(RecursiveDir)" SkipUnchangedFiles="true" />
  <Copy SourceFiles="@(Dist)" DestinationFolder="$(PublishDir)\wwwroot\dist\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>

【讨论】:

  • 代码示例似乎期望 csproj 中有一个 PrepublishScript 目标。 ASP.NET Core Web 应用模板没有这个。在这种情况下,您是否只需将其添加到 Project 元素中?
【解决方案3】:

您可以通过Condition 来满足您的需求,例如:

<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
  <Content Remove="wwwroot\dist\**" />
  <Content Remove="wwwroot\lib\**" />
</ItemGroup>

编辑:

或者尝试一下:

<ItemGroup>
  <Content Condition=" '$(Configuration)' == 'Debug'" Remove="wwwroot\dist\**" />
  <Content Condition=" '$(Configuration)' == 'Debug'" Remove="wwwroot\lib\**" />
</ItemGroup>

编辑 2:

由于 IDE 似乎将尊重 Condition,您可以改为将项目从 Content 更改为 None 并添加一个 BeforePublish 目标,以添加等效的 Content 项目。

编辑 3:

所以具体来说,保留你的原件

<ItemGroup>
  <Content Remove="wwwroot\dist\**" />
  <Content Remove="wwwroot\lib\**" />
</ItemGroup>

并在&lt;/Project&gt;之前添加

<Target Name="BeforePublish">
  <ItemGroup>
    <Content Include="wwwroot\dist\**" />
    <Content Include="wwwroot\lib\**" />
  </ItemGroup>
</Target>

【讨论】:

  • Visual Studio 2017 解决方案资源管理器忽略 Condition?我想我不应该感到惊讶。我添加了一个变体,以防万一它从 IDE 中获得所需的行为,但我怀疑它不会。 :(
  • 试过了,在visual studio中发布根本无法复制wwwroot,即使使用BeforePublish目标,使用dotnet publish仍然排除dist和lib
  • 您能否提供项目文件中的其他
  • 没有其他内容包含或删除行
  • 尝试将目标名称从 BeforePublish 更改为 BeforeBuild。
猜你喜欢
  • 1970-01-01
  • 2014-10-20
  • 2011-08-31
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多