【问题标题】:How do I concatenate JavaScript files into one file?如何将 JavaScript 文件连接到一个文件中?
【发布时间】:2010-09-23 00:29:22
【问题描述】:

我想为我的网站创建一个已编译的 JavaScript 文件。对于开发,我更愿意将 JavaScript 保存在单独的文件中,作为我的自动化脚本的一部分,将文件连接成一个文件并在其上运行压缩器。

我的问题是,如果我使用旧的 DOS 复制命令,它还会放入压缩器抱怨的 EOF 标记:

复制 /A *.js 编译.js /Y

其他人在做什么?

【问题讨论】:

  • Phil,从您对我的回答的评论中,我现在可以看到您没有得到 EOF 标记(好吧,我在结果文件的末尾得到了一个带有副本的标记)但确实是 BOM ,因为您以某种方式编写了 Unicode 文件。将它们展平为 Ascii,您应该摆脱它们。
  • 确实,我一整天都在使用多种不同语言的 Windows、Linux 和 Mac 工作。 Unicode 是我的标准。

标签: javascript batch-file compression


【解决方案1】:

我推荐使用 Apache Ant 和 YUI Compressor。

http://ant.apache.org/

http://yui.github.com/yuicompressor/

在 Ant 构建 xml 中添加类似的内容。 它将创建两个文件,application.js 和 application-min.js。

<target name="concatenate" description="Concatenate all js files">
    <concat destfile="build/application.js">
        <fileset dir="src/js" includes="*.js" />
    </concat>
</target>

<target name="compress" depends="concatenate" description="Compress application.js to application-min.js">
    <apply executable="java" parallel="false">
        <filelist dir="build" files="application.js" />
        <arg line="-jar" />
        <arg path="path/to/yuicompressor-2.4.2.jar" />
        <srcfile />
        <arg line="-o" />
        <mapper type="glob" from="*.js" to="build/*-min.js" />
        <targetfile />
    </apply>
</target>

【讨论】:

  • 这给我带来了Unexpected element "{}target" {antlib:org.apache.tools.ant}target 错误。有什么想法吗?
  • 几年前我停止使用 Ant。现在我用 Node 来做这些事情。看看这个:mechanics.flite.com/blog/2012/06/19/…
【解决方案2】:

不使用EOF复制使用二进制模式:

copy /B *.js compiled.js /Y

如果生成的文件仍有 EOF,则可能来自原始文件之一, 它可以通过这个变体来修复:

copy /A *.js compiled.js /B /Y

/A 会从原始文件中删除尾随 EOF(如果有),/B 会阻止将 EOF 附加到结果文件中。如果 EOF 不在末尾,则源文件将被截断。开关的顺序很重要。如果你写

copy /A *.js /B compiled.js /Y  

- 源文件中的 EOF 不会被删除,但仍不会附加生成的 EOF。

自己尝试一下,这就是我得到它的地方。 DOS命令很奇怪。

【讨论】:

  • 奇怪的是 /B 选项对我的文件没有影响
  • 我尝试了您的建议,但我仍然得到: 作为文件连接位置之间的标记...感谢您查看此内容。
  • 看来我明白了, 是一个 UTF8 前缀字节。它应该在文件的开头,否则它会被视为数据并且您的编译器会抱怨它。这不是EOF问题。而且你不能使用copy。
【解决方案3】:

在 asp.net AJAX 中,您可以使用“CompositeScript”标签。这会将所有脚本合并为 1 个大 js 文件,通过减少 http 304 和可能的 http 401 的数量来节省带宽。

示例:

 <asp:ScriptManager ID="ScriptManager1" runat="server">
        <CompositeScript>
            <Scripts>
                <asp:ScriptReference Path="~/Scripts/Script1.js" />
                <asp:ScriptReference Path="~/Scripts/Script2.js" />
                <asp:ScriptReference Path="~/Scripts/Script3.js" />
            </Scripts>
        </CompositeScript>
    </asp:ScriptManager>

有关详细信息,请参阅此处: http://msdn.microsoft.com/en-us/library/cc488552.aspx

【讨论】:

    【解决方案4】:

    这是一个非常古老的问题,但我想提一下,也有使用 javascript 连接 javascript 的方法!显然使用 nodejs ......例如,有一些工具作为 npm 模块发布,如 this 还有gruntgulp 插件。

    我还想提一下一个非常非常有趣的技术,它被用于像 jQuery 和 Modernizr 这样的大型项目中。这两个项目都是完全使用 requirejs 模块开发的,然后他们使用requirejs optimizer 作为一个非常智能的连接器。有趣的是,正如您所看到的,jQuery 和 Modernizr 都不需要 requirejs 才能工作,这是因为它们删除了 requirejs 语法仪式以便在代码中摆脱 requirejs。所以他们最终得到了一个使用 requirejs 模块开发的独立库!多亏了这一点,他们能够执行库的 cutsom 构建,以及其他优势。 Here 是一篇博文,更详细地解释了这一切。

    【讨论】:

      【解决方案5】:

      在你的机器上安装压缩器uglifyjs:

      sudo npm -g install uglify-js
      

      那么下面的命令就可以用来拼接和压缩所有的js文件了。

      cat myAppDir/*.js | uglifyjs > build/application.js
      

      【讨论】:

        【解决方案6】:

        我们创建了一个由以下部分组成的机制:

        • minfication(用于 js 和 css)
        • 包中的聚合
        • 缓存(http 状态 304 内容)
        • 在开发模式下发送原始文件

        这可能对您的需求来说太多了,但至于回答您的问题,其他人是怎么做的,这是它的工作原理:

        1. 一个请求进来了,比如说, /css.aspx?package=core
        2. 我们在 xml 配置文件(其中 例如声明 包“核心”包含文件 /js/mootools.js 和 /js/swfobject.js)
        3. 我们检查是否启用了缩小。例如,在一个 我们没有的开发环境 希望缩小的 js 内容是 送达,而是写 原始文件。对于 js,这是完成的 通过 document.writes 的脚本 包括,我们为 css 编写导入规则。
        4. 如果需要缩小(在生产环境中),我们会检查请求中的 if-modified-since 标头。如果这个客户端已经有了缩小的内容,我们发送 http 头 304。如果客户端确实需要内容,我们检查缓存中是否有缩小的内容并提供服务。否则,我们会缩小并发送结果。

        所有这些都被分解为单独的服务。 jsminificationwriter 服务中注入了缓存服务。这利用了仅处理缩小规则的原始缩小服务。

        这种方法的好处是:

        • 它迫使我们的开发团队在 js/css“包”中进行思考,因此正确地拆分功能并将它们分发到需要它们的页面上。
        • 在开发过程中,您可以完美地进行调试,获得正确的文件和行号。
        • 您可以连接任何其他缩小服务实现,例如 YUI 等。 JsMin 只是我们的第一次尝试。
        • 这是一种适用于不同内容类型的通用方法。

        希望这会有所帮助。如果您愿意,我可以发布一些代码片段来进行更多说明。

        【讨论】:

          【解决方案7】:

          你也可以这样做:

          type *.js > compiled.js
          

          【讨论】:

          • 我的设置一定有些奇怪,因为 type 给出的标记与复制方法完全相同:
          • BOM?你的文件是 ANSI 还是 UTF?
          【解决方案8】:

          我将使用第二个 yuicompressor,但我使用 /packer/

          http://johannburkard.de/blog/programming/javascript/automate-javascript-compression-with-yui-compressor-and-packer.html

          这对我来说真的很棒。

          【讨论】:

          【解决方案9】:

          你也可以试试wro4j(java的web资源优化器),它可以用作构建工具(maven插件)、运行时解决方案(使用过滤器)或命令行工具。它允许您使用十几种机器人类型资源的压缩器轻松组织资源并为您处理合并:js 和 css。

          定义要合并的资源很简单:

          <groups xmlns="http://www.isdc.ro/wro">
            <group name="all">
              <css>/asset/*.css</css>
              <js>/asset/*.js</js>
            </group>
          </groups>  
          

          免责声明:我是这个项目的提交者。

          【讨论】:

            【解决方案10】:

            我知道这是一个非常古老的问题,但为了完整起见,我会提到使用Browserify 的选项。它允许您使用 NPM 的 require 函数将项目构建为不同的模块来解析依赖项,然后它会解析这些依赖项并将整个项目连接到一个文件中。

            例如,假设您的项目名为 FooBar,并且您想要输出一个名为 foobar.js 的文件。您将创建一个 main.js 文件作为项目的入口点,需要所有应包含的模块。

            main.js

            require("./doFoo");
            require("./doBar");
            

            然后运行:

            browserify main.js -o foobar.js
            

            或者,要在每次源文件更改时自动执行此操作,您也可以使用 Watchify

            watchify main.js -o foobar.js
            

            Browserify 还将解决模块之间的依赖关系。例如,如果 doBar.js 依赖于doQux.js...

            doBar.js

            require("./doQux");
            const doBar = ()=>{
                //Do some bar stuff.
            }
            exports.doBar = doBar;
            

            然后 Browserify 将确保将 doQux.js 包含到 foobar.js 中,这样您就不会有任何损坏的依赖项。

            【讨论】:

              猜你喜欢
              • 2020-06-28
              • 2019-08-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-11-24
              • 2021-05-31
              相关资源
              最近更新 更多