代码之家  ›  专栏  ›  技术社区  ›  salgiza

Visual Studio 2010:发布缩小的javascript文件,而不是原始的文件

  •  24
  • salgiza  · 技术社区  · 14 年前

    我有一个脚本文件夹,其中包括项目中使用的所有.js文件。使用Ajax微型化器任务,我为每个文件生成.min.js文件。 根据应用程序是在调试模式下运行还是在发布模式下运行,我将包含原始的.js文件,或者是小型的.js文件。

    脚本文件夹如下所示:

    Scripts/script1.js
    Scripts/script1.min.js   // Outside the project, generated automatically on build
    Scripts/script2.js
    Scripts/script2.min.js   // Outside the project, generated automatically on build
    

    .min.js文件在项目外部(尽管与原始文件在同一文件夹中),在我们发布项目时,它们不会复制到目标文件夹中。

    我没有任何使用构建任务的经验(好吧,除了包括缩小任务),所以如果有人能告诉我哪种方法是正确的:

    • 当我从Visual Studio发布应用程序时,将.min.js文件复制到目标文件夹。
    • 删除/不复制原始JS文件(这并不重要,但我宁愿不复制应用程序中不使用的文件)。

    谢谢,

    编辑: 从回答中,我发现我遗漏了一些细节,也许我在寻找问题的错误解决方案。我将在问题中添加以下详细信息:

    • 如果可能,我们宁愿不在解决方案的构建过程中创建复制脚本。当然,我们考虑过了,但是直到现在我们都在使用Web部署项目,我们宁愿开始使用VS2010的新发布功能(应该替换这些项目),而不是手动将复制命令添加到构建任务中。
    • 项目中不包括*.min.js文件,因为它们不在源代码管理系统(此时为tfs)中。它们是编译期间生成的文件,类似于将“bin”文件夹包含在TFS中(包括它会导致的问题)。也许我们应该在另一个文件夹中创建min文件,并将其视为“bin”?(这可能吗?)
    5 回复  |  直到 12 年前
        1
  •  20
  •   Eamon Nerbonne    12 年前

    编辑(2012年10月): ASP.NET 4.5现在包括 Bundling and minification . 当前版本不太支持动态javascript生成,但它在其他方面非常有用,例如,它确实观察文件系统进行如下所述的实时更改;在滚动您自己的压缩之前,请尝试这样做!

    老回答:

    我建议您在运行时这样做,而不是在构建时实现它。这有许多优点:

    • 您可以包括调试参数,这些参数可以关闭组合和缩小,以便更容易地识别错误。这还允许您在开发和生产环境之间的差异较小的情况下运行。
    • 你获得了一些灵活性。我已经两次通过一个只能直接运行的脚本修复来修复错误。对于简单但关键的错误,这是一个不错的选择。
    • 实现起来要简单得多——您已经具备了实现HTTP响应的专业知识,这在这里非常适用。
    • 您可以跟踪所涉及脚本的最后修改日期,不仅可以使用它来设置适当的etags和whatnot(这也是IIS可以做的),而且可以设置一个远未来的到期日期。然后,您可以使用查询字符串中的一些短标记链接脚本,而不是链接实际的scipt(无论是否缩小),这样客户机就不需要检查JS是否已更新。如果有,页面将链接到需要单独请求的“新”脚本文件。(这可以在构建脚本中进行,但更复杂)。
    • 一个复杂的构建过程通常有隐藏的成本。不仅运行时间更长,而且当您想要更新构建自动化工具时会发生什么?当您切换IIS或Windows版本时?当您迁移到vs 2010时?让新开发人员跟上进度有多容易?

    这是我所遵循的流程的大致概述:

    1. 我将两个目录指定为只包含可压缩的css和js。在AppDomain实例化时或之后不久通过静态构造函数,类查找这些目录的内容并创建 FileSystemWatcher 观察变化。
    2. 所有文件都按文件名的顺序读取(使用诸如 00_jquery.js 10_init.js 等等,有助于控制这里的秩序)。文件名列表存储用于调试。
    3. 所有文件通过字符串串联组合,然后由yui缩小,然后通过压缩 GZipStream . 特定于版本的令牌可以通过最新的上次修改日期或结果的哈希计算。
    4. 压缩的结果(字节数组、文件名和特定于版本的令牌)存储在静态类变量中(由 lock )如果文件系统监视程序检测到更新,那么步骤2将再次启动,并在后台运行,直到压缩完成-因此锁定。
    5. 任何希望包含合并的javascript(和/或css)的页面都会调用共享静态变量。如果我们处于调试模式,它将为步骤2中存储的每个文件名生成一个脚本(或链接)标记,否则,它将生成一个脚本(或链接)标记,指向一个由自定义 IHttpHandler . 所有的URI都在querystring中包含特定于版本的令牌-对于组合的小型化版本,IIS静态文件处理程序和自定义HTTP处理程序都会忽略这一点,但这使得缓存变得容易。
    6. 在自定义的ihtphandler中,当接收到对合并的javascript(或css)的请求时,将设置内容编码:gzip头和一个远未来的到期日期。然后,通过将预压缩字节数组直接写入HTTP流 context.Response.OutputStream .

    使用这种方法,您不需要在添加或删除脚本文件时处理web.config选项;您可以在应用程序运行时更新脚本,客户机将在下一个页面视图上请求这些脚本,但您仍然可以获得最佳的缓存行为,因为浏览器甚至不会发送由于到期头而未修改的请求。通常,压缩脚本需要一秒钟左右的时间,压缩结果应该很小,静态变量的内存开销可以忽略不计(对于真正大量的脚本/css,最多只有100 kb)。

        2
  •  7
  •   Daniel Lee    13 年前

    如果您想通过Visual Studio进行JavaScript缩小,这将使您开始: http://encosia.com/2009/05/20/automatically-minify-and-combine-javascript-in-visual-studio/

    否则,我建议使用一个可以自动组合和缩小JavaScript的工具。我看到的两个工具是 Justin Etheredge Bundler Combres . 我在当前的项目中使用Bundler,我的一个同事正在使用Combres。邦德勒有点简单使用,但它比梳子少。如果bundler在web.config中关闭了debug,那么它不会缩小和合并,这意味着您可以在开发环境中调试javascript。

    P.S.Bundler被重新命名为Squishit。

        3
  •  3
  •   Community c0D3l0g1c    7 年前

    你可能想看看 Build Events ,使用该命令行可以指定执行后期生成的命令行。另外,你的问题类似于 these questions .

    对于实际的复制,您可以很容易地利用 COPY 命令。

        4
  •  2
  •   flq    14 年前

    我不太确定这种方法在这种情况下是否有用,但我可以想象… 您可以修改csproj文件,例如影响某些类型的构建中应包含哪些文件。

    对于某些类型,我指的是配置管理器。

    调试和发布是默认的,但是没有什么能阻止您创建新的。基于所选的配置,您可以将不同的文件作为配置的一部分,我认为您可以这样发布不同的文件。我在我的博客上描述了这一策略: http://realfiction.net/go/130

        5
  •  1
  •   Ivo    14 年前

    这篇关于“在ASP.NET项目中自动缩小、合并、压缩和缓存*.js和*.css文件”的文章可能会帮助您

    http://www.codeproject.com/KB/aspnet/CssAndJavaScriptOptimizer.aspx?display=Print