在Visual Studio 2010中处理常见的JavaScript文件

43

我们正在开发几个完全依赖JavaScript的Web应用程序(我们以前的应用程序是基于ASP.NET MVC,然后再加上一些JavaScript)。

我们有一些文件将在所有项目中共享,将这些文件存储在一个公共项目中,并将它们作为链接添加到各个项目中(就像编译代码一样)会很不错。

显然,对于JavaScript这样的东西,实际上没有“正确位置”的文件,所以这种方法行不通。

有没有人有任何建议,如何保持单个版本的共享JavaScript文件,以供多个项目使用?


很好的问题,我已经思考了相当长的时间。在我的脑海中浮现出的唯一解决方案是将文件托管在网络上并像使用CDN一样使用它们,或者使用符号链接。您可以添加一个代码片段到您的Visual Studio中来引用它们。 - Blowsie
9个回答

49

我知道这个问题已经很古老了,但我还是想提出我的解决方案,因为它比beardtwizzle的方案简单一些。

你可以在你的.csproj文件末尾添加以下内容,确保Visual Studio将所有链接的文件都复制到你在Visual Studio的Solution Explorer中放置链接的位置:

  <Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
    <Copy SourceFiles="%(Content.Identity)" 
          DestinationFiles="%(Content.Link)" 
          SkipUnchangedFiles='true' 
          OverwriteReadOnlyFiles='true' 
          Condition="'%(Content.Link)' != ''" />
  </Target>

我在我的博客文章http://mattperdeck.com/post/Copying-linked-content-files-at-each-build-using-MSBuild.aspx中描述了这是如何工作的。


谢谢!我喜欢这个比xcopy PostBuildEvent更好,因为我的资产中有子目录要复制,并且不希望所有项目中都有共享资产。这样可以照顾到它们全部! - Cody
我喜欢这个!不幸的是,它有一个小缺点,就是在更新这些引用的.js文件的智能感知之前,你需要重新构建。但到目前为止,这是最好的解决方案。 - Bigjim
@Bigjim 尽管智能感知不起作用,但是我是否必须构建才能获取共享文件的最新更改,或者我可以修改链接的 JavaScript 文件,在调试时查看最新更改? - crush
在看到这个之前,我花了大约一个小时的时间在这个上面工作。然后我把它忽略了,认为它可能会过于具有侵入性,接着又花了大约5个小时的时间继续工作,直到最终实现了它,而且非常容易!效果非常好。 - Ross Brasseaux
它会将JS文件物理复制到项目中吗? - DasDas
这是最佳选择,因为它在使用TFS构建解决方案时也能正常工作。而复制和xcopy对我来说总是失败的。 - Kai Hartmann

20

最终,我是这样实现的。可能不是每个人都喜欢,但对我很有效。

注意:在我们所有的项目中,静态资源都在名为'Assets'的根目录中,例如JavaScript始终位于 /Assets/js/,CSS则为/Assets/css/。

解决方案

  1. 在将要“导入”通用代码的项目中,我只需在 /Assets/js/ 中“链接”公共 .js 文件即可。
  2. 转到新添加项的属性,将“复制到输出目录”设置为“仅在更改时复制”。
  3. 现在,我只需编辑项目的后期生成事件命令行如下所示: xcopy /Y /E "$(TargetDir)\Assets" "$(ProjectDir)\Assets"

当项目构建时,它会将导入的文件复制到 \bin\Assets\js - 然后,后期生成事件会将这些文件的副本复制到项目目录中,以供站点使用。


5
你可以添加/D参数以仅复制更改过的文件:xcopy /Y /E /D "$(TargetDir)\Assets" "$(ProjectDir)\Assets"。 - Cohen
2
从这个问题中最受欢迎的答案中得到启示: https://dev59.com/E3A75IYBdhLWcg3w8-BJ我修改了命令行为以下内容:echo f | xcopy /Y /E "$(TargetDir)Content" "$(ProjectDir)Content",这样就可以防止在我的情况下出现“以代码X退出”的错误。 - robyaw
通过启用“复制到输出目录”,bin文件夹将被污染,其中包含不属于它们的.js文件。我理解您在将它们复制到\Assets之前使用它作为临时文件夹。它们将被包含在部署中,但不会被使用。 - Bigjim

1
我可以看到这个问题很古老,但是想要加上我的两分钱……
我有一个独立的项目中的javascript文件。我添加了链接引用,这在发布时很有效,但在IIS Express或Casinni中不起作用。我尝试添加自定义路由来捕获丢失的文件并手动重新映射它,但这有点像黑客行为,并且因为某种原因在我升级到MVC 5.1时停止工作了,所以我找到了更好的方法:
System.Web.Optimization有javascript包。
在您的共享项目中,将“复制到输出目录”设置为“始终复制”,将“生成操作”设置为“内容”以使用js文件。这意味着您的js文件最终会出现在网站项目的bin文件夹中。它们不能从那里提供服务(出于明显的安全原因,IIS不会为bin文件夹中的任何内容提供服务),但它们可以包含在bundles中。
using System.Web;
using System.Web.Optimization;

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {   
        bundles.Add(new ScriptBundle("~/bundles/externalLibrary").Include(
                    "~/bin/scripts/externalLibrary.js"
                    ));
    }
}

然后您需要将此内容添加到global.asax文件中的Application_Start中(紧贴着注册路由的位置)

BundleConfig.RegisterBundles(System.Web.Optimization.BundleTable.Bundles);

然后在Razor CSHTML中使用您的捆绑链接,如下所示:
<script type='text/javascript' src='@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/externalLibrary")'></script>

您需要安装 microsoft.aspnet.web.optimization 的 NuGet 包。


1
我喜欢这个想法,但当禁用捆绑时它不起作用(<compilation debug="true">没有设置BundleTable.EnableOptimizations),因为它仍然试图从bin目录中提供它们。 - Tyler

1

3
虽然这是一个有趣的解决方案,但在脚本src属性中需要查询字符串并不好(这可能导致某些代理无法缓存)。更重要的是,我无法将公共资源与本地项目文件合并为单个压缩JS文件。 - isNaN1247
开发很少是一刀切的,无法说出“正确的解决方案”。 - sclarson

1
未来遇到此问题的任何人都应该知道,Visual Studio中现在有共享项目来解决这个问题。通用Windows项目默认使用它们,您可以通过下载和安装VS扩展来创建自己的共享项目:https://visualstudiogallery.msdn.microsoft.com/315c13a7-2787-4f57-bdf7-adae6ed54450
下载扩展后,您可以向解决方案添加共享项目(空)。该项目可以在Visual C#,Visual C ++和JavaScript的项目模板中找到。
然后,将要共享到共享项目中的文件包含在任何对您有意义的文件夹结构中。
接下来,您将在需要访问共享文件的该解决方案中的其他项目中将共享项目作为共享引用包含。右键单击其他项目,然后选择“添加共享项目引用”。
现在,您可以像共享项目中的文件存在于其中一样,在主项目中引用共享文件。它们作为该项目的一部分进行编译。
该技术旨在实现通用应用程序,以便在Windows Phone和Windows Store应用程序之间共享代码,因此请注意,在不同的情况下可能会遇到共享问题,但是值得尝试以查看它是否能满足您的需求。

你能再详细解释一下这项技术是如何工作的吗? - crush

0

1
谢谢您的建议,但我认为那只会在创建时采用“通用”代码。之后,任何后续的代码更改都需要在每个单独的项目中进行。 - isNaN1247

0
很好的问题,我已经思考了相当长的时间。在我的脑海中浮现出的唯一解决方案是将文件托管在网络上并像CDN一样使用它们,或者使用符号链接。您可以在Visual Studio中添加代码片段来引用它们。

0

本博客文章介绍了一种替代方案,以回答@beardtwizzle的问题:

http://consultingblogs.emc.com/jamesdawson/archive/2008/06/03/using-linked-files-with-web-application-projects.aspx

思路相似:

  1. 将共享文件作为链接添加到Web项目中
  2. 修改项目中的_CopyWebApplication构建步骤,使链接的文件被复制到正确的目标路径。

因此,与其使用后期构建事件,不如通过修改构建步骤来复制文件。对我来说,这种解决方案感觉更加简洁(但这可能只是个人喜好问题)。无论如何,我刚刚将其添加到我们的解决方案中,目前运行良好!


-4

使用适当的版本控制。

将js文件保存在一个位置,然后只需使用git pull(或相应的Mercurial / Bazaar命令)将它们更新到您的代码中。


我们使用的是 TFS 2010,但好像找不到在不同项目中拉取单个文件的类似功能。 - isNaN1247
@beardtwizzle,我建议你将你的JS代码放在一个项目或版本控制位置中,然后将其检出到现有代码中。或者你可以作弊,在Git服务器上托管你的JS代码 ;) - Raynos
我不确定这样做是否能解决问题?你是否可以将它们配置为 git-submodules(类似于 svn:externals)? - Cohen
@Cohen 我个人会使用 JavaScript 的包管理器,并将它们设置为模块/包。然后只需要运行 package_manager update 或类似的命令。 - Raynos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接