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

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

问题描述

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

 < 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文件夹中.

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

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

NuGet包文件未复制到构建过程中的项目内容

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

整个过程的重点是我希望能够从源代码管理中签出一个修订版本,并使用正确的依赖关系构建该版本,并且我想使用NuGet的精美包装功能.因此,我不希望任何在构建过程中自动更新到最新版本."

存在针对NuGet的问题( http://nuget.codeplex.com/workitem/2094)关于NuGet文件未还原内容文件.并且被标记为按设计封闭".

考虑到它的工作原理,我觉得(但是我不是100%确信)对于程序集,NuGet具有不同的行为-它不会将它们复制到项目中,而是从中引用它们软件包文件夹中的位置.令我惊讶的是,应该像引用dll一样引用来引用NuGet包中的js文件.

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

如果没有,那么我将按照Jeff Handley的建议在关闭上面提到的Nuget Issue 2094时打钩:

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

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

解决方案

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

对于C#,当您安装软件包时,它会将.csproj文件中的引用添加到磁盘上的程序集中.生成时,MSBuild知道将引用的内容复制到bin目录.由于您没有签入bin目录,因此一切正常.

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

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

如果您来自像C#这样的现代生态系统,那么整个系统将非常陈旧.

您可以 要做的是创建一个MSBuild任务,在构建之前,该任务将遍历所有包,查找内容并将该内容复制到所需位置.尽管会花费一些工作,但这并不是很难的事情.

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

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>

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.

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

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 package files not being copied to project content during build

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 >=).

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."

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.

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.

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?

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

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?

解决方案

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

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.

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.

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.

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.

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天全站免登陆