【问题标题】:I'm trying out Grunt and need a simple way to concatenate my modules我正在尝试 Grunt,需要一种简单的方法来连接我的模块
【发布时间】:2012-10-06 03:19:26
【问题描述】:

这是我第一次使用 Grunt,我想让它结合我所有的 js 模块,每个模块都包装在一个立即执行的函数中,包含一个“use strict”声明并将它们放入一个文件中,包装只有一个立即执行的函数,只有一个“使用严格”声明。

这通常是怎么做的?

我认为这将是一个常见的用例?也许我做错了事?我是否应该使用其中一种模块加载格式(即 commonjs、amd)所有这些文件将始终一起加载到浏览器中,所以如果人们通常这样做的话,我实际上不介意删除所有立即执行的函数。重要的部分是最终结果以某种方式包装,通过了 lint 和单元测试并包含“use strict”声明。

(我应该澄清一下,我确实让它工作,linting,单元测试,连接和缩小,当我在最终连接文件中看到一堆不必要的立即执行函数时,感觉就像我做错了什么.)

【问题讨论】:

    标签: javascript concatenation gruntjs


    【解决方案1】:

    我通常像jQuery team does it 那样做。您创建一个 intro.jsoutro.js 并将其他所有内容放在两者之间:

    intro.js

    ;(function( window, undefined ){
      'use strict';
    

    outro.js

    }( window ));
    

    grunt.js

    concat: {
      dist: {
        src: [
          'js/src/intro.js',
          ...
          'js/src/outro.js'
        ],
        dest: 'js/out/app.js'
      }
    }
    

    【讨论】:

    • 该死,我什至查看了他们的 github repo 以了解他们是如何做到的,但完全没有明白这一点,谢谢!
    • 我实际上在开发过程中使用 grunt 来处理我的静态 html。我开始用 js 做同样的事情,但我使用页眉和页脚而不是 intro/outro。因为我不需要在开发过程中动态更新文档标题,所以效果很好。
    【解决方案2】:

    我建议您使用我的 grunt 插件 grunt-concat-deps,因为它会自动解析独立于您的架构的模块。

    另外:您不需要为插件进行任何显式模块配置,因为它依赖于 YUIDoc 样式中的声明性和分散式模块定义。

    更多信息请看这里:https://github.com/leoselig/grunt-concat-deps

    【讨论】:

      【解决方案3】:

      截至pull request 10,grunt-contrib-concat 现在有一个footer 选项。我会使用 bannerfooter 来代替 intro 和 outro 文件。

      Gruntfile.js

      concat: {
        dist: {
          src: ['src/my-lib.js'],
          dest: 'dist/<%= pkg.name %>.js',
          options: {
            banner: ";(function( window, undefined ){ \n 'use strict';",
            footer: "}( window ));"
          }
        }
      }
      

      在我看来,这更易于维护,并且允许使用 Gruntfile 中定义的其他属性进行模板化。

      【讨论】:

      • 同意,这比任何其他选项都好得多,而且由于是官方 Grunt 版本,您可以确定该插件将得到维护。
      【解决方案4】:

      只想添加到@elclanrs 的答案是,如果您希望能够将模块保存在单独的文件中以便在开发过程中进行调试,那么您显然还必须使用intro.jsoutro.js 将它们包装起来。使用内置的 concat 任务,您必须编写如下内容:

      concat: {
        events_debug: { // wrap the 'events' module in IIFE
          src: [
            'js/src/intro.js',
            'js/src/events.js',
            'js/src/outro.js'
          ],
          dest: 'js/out/events.js'
        },
        callbacks_debug: { // wrap the 'callbacks' module in IIFE
          src: [
            'js/src/intro.js',
            'js/src/callbacks.js',
            'js/src/outro.js'
          ],
          dest: 'js/out/callbacks.js'
        }
      
        // zzZZZ...
      }
      

      这是非常乏味和自我重复的。也许您可能想为批量包装文件创建一个自定义任务,例如

      wrap: {
          html: {
              intro: 'partials/intro.js',
              outro: 'partials/outro.js',
              src: 'js/*.js',
              dest: 'out' // output directory
          }
      }
      

      最近有一个关于这个的问题,看这个帖子:

      Using grunt concat, how would I automate the concatenation of the same file to many other files?

      【讨论】:

      • 谢谢@Dmitry,我想我正在慢慢了解它是如何工作的,它不是很直接。这让我想知道将每个模块包装在一个 iife 中是否更有意义,然后有一个繁重的任务来剥离包装器。就像它可能会删除 //&lt;--intro 之前的所有内容以及 //outro--&gt; 之后的所有内容...?
      • ...我猜做“wrap”而不是“unwrap”更符合“DRY”
      • 这取决于你 :) 当然,连接比剥离模式更容易、更安全、更快。但另一方面,我不确定我是否喜欢让我的源文件依赖于构建工具(即你的模块不再是可移植的,因为如果没有包裹在 IIFE 中它们就无法工作。相反,你会必须从您包含在项目中的任何外部模块中手动剥离 IIFE)。这么好的考虑...
      • 是的,构建工具很棒,但在调试方面,没有什么比得上好的 'ol cmd+shift+r :) 但是,我不明白你为什么必须这样做从 3rd 方模块中剥离 iife...?
      • 如果您想将第 3 方模块添加到您的串联代码旁边的一个大文件文件中,您可能需要这样做
      猜你喜欢
      • 2019-06-11
      • 2019-03-17
      • 2019-09-17
      • 2021-10-20
      • 2013-07-23
      • 2022-10-02
      • 1970-01-01
      • 2023-03-23
      • 2021-05-24
      相关资源
      最近更新 更多