如何在 TeamCity 的构建时引用而不是复制 Nuget 包中的 js 文件? [英] How do I reference instead of copy js files from a Nuget package at build time in TeamCity?

查看:11
本文介绍了如何在 TeamCity 的构建时引用而不是复制 Nuget 包中的 js 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将 packages.config 文件签入源代码管理.这指定了我想要的 Nuget 依赖项的确切版本.我们有自己的 NuGet 存储库.我们正在自己创建这些 NuGet 包.

I've got a packages.config file checked into source control. This specifies the exact version of the Nuget dependency I want. We have our own NuGet repository. We are creating these NuGet packages ourselves.

<packages>
  <package id="Dome" version="1.0.0.19" targetFramework="net45" />
  <package id="Dome.Dojo" version="1.0.0.19" targetFramework="net45" />
</packages>

这些包有一些 JavaScript 文件,当您在 Visual Studio 中添加 Nuget 包作为引用时,这些文件会复制到项目中的 Scripts 文件夹中.

These packages have some JavaScript files which when you add the Nuget package as a reference in Visual Studio are copied to the Scripts folder in the project.

我不想将这些 JS 文件签入源代码控制,我只想签入 packages.config 文件.

I don't want to check these JS files in to source control, I just want to check in the packages.config file.

当我的项目在 Team City 中构建时(或者当我在重新签出后在 Visual Studio 中构建时),它不会从 NuGet 包中复制 JS 文件.这里有一个问题解释了类似的问题:

When my project builds in Team City (or when I build in Visual Studio after a fresh checkout) it doesn't copy the JS files from the NuGet package. There's a question here explaining a similar problem:

NuGet 包文件未复制到构建期间的项目内容

但是,该问题的答案中的解决方案对我不起作用;该解决方案使用 ReInstall,这是有问题的,因为它可以自动升级 packages.config 文件中的版本(例如,如果将依赖项指定为 >=).

But, the solution in the answer to that question doesn't work for me; that solution uses ReInstall, which is problematic because it can automatically upgrade the version in the packages.config file (say if a dependency is specified as a >=).

我希望能够从我的源代码管理中签出一个修订版,并使用正确的依赖项构建该版本,并且我希望使用 NuGet 的出色打包功能.所以,我不希望任何在构建过程中自动更新到最新版本".

The whole point of this is that I want to be able to checkout a revision from my source control, and build that version with the right dependencies AND I want to use the nice packaging features of NuGet. So, I don't want any "automatically update to the latest version during the build."

NuGet 存在问题 (http://nuget.codeplex.com/workitem/2094) 关于 NuGet 文件不恢复内容文件.它被标记为按设计关闭.

There's an issue against NuGet (http://nuget.codeplex.com/workitem/2094) about NuGet files not restoring content files. And it's Marked as Closed By Design.

再考虑一下这是如何工作的,在我看来(但我不是 100% 确定)对于程序集 NuGet 具有不同的行为 - 它不会将它们复制到项目中,而是从包文件夹中的位置.让我印象深刻的是,NuGet 包中的 js 文件应该引用,类似于引用 dll 的方式.

Thinking about how this works a little more, it appears to me (but I'm not 100% sure) that for assemblies NuGet has a different behaviour - it doesn't copy them into the project, instead it references them from the location in the packages folder. It strikes me that js files in the NuGet package should be referenced analogous to how dlls are referenced.

有没有办法构造一个 NuGet 包,以便它引用 JS 作为项目中的链接(类似于在 VS 中添加现有文件作为链接的方式)?这能解决我的问题吗?

Is there a way to construct a NuGet package so that it references the JS as links in the project (in a similar way to how you can add an existing File as a Link in VS)? And would this solve my problem?

如果没有,那么我将在关闭上面提到的 Nuget Issue 2094 时接受 Jeff Handley 给出的建议:

If not then I'll take the advice given by Jeff Handley when closing ticked Nuget Issue 2094 mentioned above:

您可以选择创建一个新的控制台可执行文件,引用 NuGet.Core,您可以构建一个补充包restore 供您自己使用,将包内容复制到项目.

The option you'd have is to create a new console executable that references NuGet.Core, and you could build a supplemental package restore for your own use that copies package contents into the project.

编写我自己的命令行工具来复制内容似乎我在这里推水 - 我在做一些根本错误的事情吗?

Writing my own command line tool to copy the contents does seem like I'm pushing water uphill here - am I doing something fundamentally wrong?

推荐答案

这里的根本问题是 Visual Studio 对 JavaScript 项目的支持相对较差,以及 JavaScript 缺少内置的模块加载器.

The underlying problem here is Visual Studio's relatively poor support of JavaScript projects and JavaScript's lack of built-in module loader.

对于 C#,当您安装一个包时,它会在您的 .csproj 文件中添加对磁盘上程序集的引用.构建时,MSBuild 知道将引用的内容复制到 bin 目录.由于您没有签入您的 bin 目录,这一切都很好.

For C#, when you install a package it adds a reference in your .csproj file to the assembly on disk. When you build, MSBuild knows to copy the thing referenced to the bin directory. Since you aren't checking in your bin directory, this all works great.

不幸的是,对于 JavaScript,构建系统还不够成熟,也没有明确定义的准则供 NuGet 遵循.理想情况下(IMO),Visual Studio 不会直接从您的源目录运行网站.相反,当你构建它时,它会将 JavaScript 文件、CSS 和 HTML 文件复制到一个 bin 目录中,并从中执行它们.调试时,它会将这些映射回原始 JavaScript 或 TypeScript 文件(因此,如果您进行更改,它不会映射到临时文件).如果发生这种情况,那么现在有一个明确定义的构建步骤,并且可能是一个明确定义的 JavaScript 文件标签(而不仅仅是内容").这意味着 NuGet 将能够利用定义明确的 MSBuild 标记,并且包作者可以利用 NuGet 功能做正确的事情.

Unfortunately for JavaScript, the build system isn't nearly as matured and there aren't well defined guidelines for NuGet to follow. Ideally (IMO), Visual Studio would not run web sites directly from your source directory. Instead, when you built it would copy the JavaScript files, CSS and HTML files to a bin directory from which they would be executed. When debugging, it would map those back to the original JavaScript or TypeScript files (so if you make a change it isn't to a transient file). If that were to happen then there is now a well-defined build step and presumably a well-defined tag for JavaScript files (rather than just "content"). This means that NuGet would be able to leverage that well-defined MSBuild tag and package authors could leverage the NuGet feature to do the right thing.

不幸的是,以上都不是真的.JavaScript 文件在原地运行,如果您在构建时将它们复制到 bin,Visual Studio 会做错事,并且从调试器进行编辑会编辑临时文件(而不是原始文件).因此,NuGet 没有明确定义的文件放置位置,因此将决定权留给包作者.包作者知道普通用户将直接从源代码运行(无构建步骤),因此他们将文件转储到源文件夹中,必须将它们签入到版本控制中.

Unfortunately, none of the above is true. JavaScript files are run in-place, If you did copy them to bin on build Visual Studio would do the wrong thing and editing from a debugger would edit the transient files (not the originals). NuGet therefore has no well-defined place to put files so it leaves the decision up to the package author. Package authors know that the average user is just going to be running directly from source (no build-step) so they dump files into the source folder where they must be checked in to version control.

如果您来自像 C# 这样的现代生态系统,那么整个系统就会非常陈旧,因为有人花时间思考这些事情.

The entire system is very archaic if you are coming from a modern ecosystem like C# where someone took time to think these things through a bit.

可以做的是创建一个 MSBuild 任务,该任务在构建之前会遍历所有包、查找内容并将该内容复制到所需位置.这不会很困难,虽然需要一些工作.

What you could do is create an MSBuild task that, before build, would go through all of your packages, look for content, and copy that content to the desired location. This wouldn't be terribly difficult, though would take a bit of work.

此外,包作者可以在其包中包含执行此操作的构建任务,以便在构建之前将其所有内容复制到本地.不幸的是,如果只有一些包作者这样做,那么您最终会出现奇怪的碎片,其中一些包需要提交给版本控制,而另一些则不需要.

Also, package authors could include a build-task that does this in their package so that before-build all of their content was copied local. Unfortunately, if only some package authors do this then you end up with weird fragmentation where some packages need to be committed to version control and others do not.

这篇关于如何在 TeamCity 的构建时引用而不是复制 Nuget 包中的 js 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆