本地工作中的 nuget 包
Posted
技术标签:
【中文标题】本地工作中的 nuget 包【英文标题】:nuget packages in local work 【发布时间】:2017-03-21 13:22:10 【问题描述】:在我们的产品中,我们有几个项目。几乎它们中的每一个都依赖于单个,称为“核心”。我们将每个项目作为单独的 nuget 包分发。对于部署我们为其他团队/产品所做的工作,nuget 工作得很好,在我们本地工作期间真的很痛苦。
每次更改“核心”项目时,我们都需要重新构建它,构建 nuget,将其发布到某个存储库中,然后在其他项目中进行还原。 这需要时间。 有时我们需要在几次迭代中对核心进行更改。我们需要一遍又一遍地让 build-publish nuget-update nuget 循环
到目前为止,我们找到的最佳解决方案是在本地工作期间将 nuget 引用切换为项目引用,并在我们想要发布时将其切换回 nuget。
但我们不确定这是否是最好的方法。
那么,在不增加工作量的情况下,在两个本地项目中处理块引用的最佳方法是什么?
谢谢
【问题讨论】:
【参考方案1】:在不增加工作量的情况下,在两个本地项目中处理 nuget 引用的最佳方法是什么?
NuGet 作为 Microsoft 开发平台的包管理器有很多优点,但这并不意味着它没有缺陷。正如您所遇到的,如果引用的项目被频繁修改,我们必须重新构建它,构建 nuget,为每次修改发布它。那会带来很多无聊的工作。为了解决这个缺点,项目到项目的引用应该是一个更好的方法。
项目到项目引用的优点是它在构建系统中的项目之间创建了依赖关系。如果依赖项目自上次构建引用项目后发生更改,则将构建依赖项目。文件引用不会创建构建依赖项,因此可以在不构建依赖项目的情况下构建引用项目。
所以你所做的就是最好的方法。当被引用的项目经常被修改时,建议使用project-to-project的引用,将引用的项目分享给他人或发布时更适合使用nuget引用。
【讨论】:
【参考方案2】:在 Node 社区中,本地包问题早已通过符号链接得到解决(参见 this blog post 和 npm link 命令)。
它是如何工作的:分布式包的目录被“符号链接”到包源目录。这样,包消费者透明地重定向到包源项目,包源的变化自动反映在消费者端。
由于某种原因,NuGet 仍然没有 链接 功能。有一个功能请求https://github.com/NuGet/Home/issues/1821,表示他们没有添加它的计划。
同时我为 NuGet 包创建了一个类似于 npm link 的工具,您可能想尝试一下:https://www.nuget.org/packages/NuLink
【讨论】:
【参考方案3】:我过去所做的是编写一个小脚本,用您刚刚编译的二进制文件覆盖您的 Nuget 二进制文件。
这样,每次更改 Nuget 包中的单个字符时,您都可以解决打包、分发和恢复包的开销
...无需更改您的消费项目中的项目引用
工作流程如下:
-
编码和构建 Nuget 二进制文件
在使用 Nuget 包的项目的 /packages 文件夹中运行脚本覆盖二进制文件
享受
我已经编写了一个完成这项工作的 Powershell 脚本 - 我自己不时使用它:
$ErrorActionPreference = 'Stop'
$SourceBasePath = 'C:\Projects\MyNugetPackage\Main'
$TargetBasePath = 'C:\Projects\MyNugetConsumer\Main'
$Configuration = 'bin\debug'
#0 = Source DLL
#1 = Source location in $SourceBasePath
$maps = @(
,@('SomeBinary.dll', 'Foo\Bar')
,@('AnotherBinary.dll', 'Bar\Baz')
)
foreach($map in $maps)
#Find all packages that contains a copy of the source binary
$targets = Get-ChildItem "$TargetBasePath\$($map[1].Split('\')[0])\packages" -Filter $map[0] -Recurse
foreach($target in $targets)
$sourcePathDll = "$SourceBasePath\$($map[1])\$Configuration\$($map[0])"
$targetPathDll = Join-Path $target.Directory.FullName $map[0]
$sourcePathPdb = $sourcePathDll.Replace('.dll', '.pdb')
$targetPathPdb = $targetPathDll.Replace('.dll', '.pdb')
Write-Host ''
Write-Host $sourcePathDll
Write-Host $targetPathDll
Write-Host $sourcePathPdb
Write-Host $targetPathPdb
if (!(Test-Path $sourcePathDll))
throw "Source not found: ", $sourcePathDll
if (!(Test-Path $targetPathDll))
throw "Target not found: ", $targetPathDll
copy $sourcePathDll $targetPathDll
copy $sourcePathPdb $targetPathPdb
您可能会遇到 Visual Studio 锁定 DLL 的问题 - 我猜没有免费午餐之类的东西 :o)
【讨论】:
【参考方案4】:我最近遇到了同样的问题,并且花了很长时间才为 nuget 包找出一个好的本地开发工作流程。我决定了以下几点:
使用来自其他库(例如“dependent-lib”)的“核心”项目引用。我们所有的库都在一个 git repo 中,我们对它们进行版本更新并一起发布。在为“dependent-lib”创建包时,dotnet 会做正确的事情,并且不会在包中包含“core.dll”。
使用 nuget 对非库中的库的引用。我们在进行本地开发时将这些引用设置为版本“1.0.0-local”,否则设置为“1.0.$LATEST_CI_BUILD_NUMBER”。由于我们所有的库都是版本化和一起发布的,所以只有一个库版本号,我们只在 LibraryVersion.targets
文件中的一处修改它。
nuget 包缓存可能会影响本地构建库的消耗。我通过在所有库 .csproj
文件中添加以下内容来解决这个问题,以便在必要时从缓存中删除包:
<Project>
<Target Name="DeleteLocalCache" BeforeTargets="Pack">
<RemoveDir Directories="$(NugetPackageRoot)/$(PackageId.ToLower())/1.0.0-local"/>
</Target>
</Project>
考虑到解决这一切需要付出多少努力,我在一篇博文中详细记录了结果,以防其他人发现它有帮助:https://www.nyckel.com/blog/local-development-and-testing-of-nuget-packages/
【讨论】:
【参考方案5】:从 NuGet 3.3 开始,您可以只使用本地文件夹,它可以托管分层 NuGet 源。为“本地服务器”创建一个文件夹,然后去那里运行“nuget init source dest”,其中“source”是一个我有完整的 *.nupkg”文件的文件夹。 由于 NuGet Server 是从 C:\LocalNuGet 中提取的,因此您可以使用一个包含 NuPkg 文件(平面)的文件夹并使用以下命令导入它们:
nuget init c:\source c:\localnuget
有关详细信息,请查看这些
https://github.com/NuGet/NuGetGallery/wiki/Hosting-the-NuGet-Gallery-Locally-in-IIS
http://haacked.com/archive/2010/10/21/hosting-your-own-local-and-remote-nupack-feeds.aspx/
【讨论】:
我们已经在使用本地提要。它根本没有帮助。在依赖核心的项目中仍然需要进行nuget更新过程,并且与仅具有项目参考相比,这些更新过程需要大量时间。但是感谢您的回答:)以上是关于本地工作中的 nuget 包的主要内容,如果未能解决你的问题,请参考以下文章