【问题标题】:How to Add Global/Public Variables to grunt-contrib-uglify Output如何将全局/公共变量添加到 grunt-contrib-uglify 输出
【发布时间】:2015-06-19 08:29:20
【问题描述】:

好的,所以我对 Grunt 和 Node.js 还是很陌生。我正在构建一个站点,并认为“main.js”文件变得太大了。因此,我将其拆分,现在我尝试使用 Grunt 将所有这些 JS 文件重新组合在一起。

我遇到的问题是我需要为所有这些 JS 文件中的所有各种函数提供一些全局变量。更具体地说,我们网站上的每个页面都通过 body 标记中的 id 标识:

<body id="home">

这些 JS 文件中的许多都包含 if 语句,以确保某些功能仅在加载了相应的页面时才运行。例如:

if (page == 'home') {
    var title = "Home Page"
    $('.page-title').text(title);
}

注意到page 变量了吗?那个人是我需要让所有这些文件都可用的那个人(在 grunt-contrib-uglify 将它们合并在一起之后)。所以,我想我会分配一个新的“唯一”变量名,并使其成为全局变量。

我注意到grunt-contrib-uglify 在其文档中列出了一个“wrap”选项。但是,没有给出如何使用它的示例。

谁能告诉我: - 如何在 'grunt-contrib-uglify' 中使用 'wrap' 选项 - 如果这是我想要做的正确的 grunt 插件?

我的一个想法(作为最后的手段)是创建一个before.js 和after.js,并分别放置我希望在每个文件中环绕其他文件的开头和结尾。但是,我认为 'wrap' 选项是我需要的,是吗?

更新:这是我“合并”的 JS 文件的链接: main.js

还有一个指向我的 Gruntfile 的链接: Gruntfile.js

【问题讨论】:

  • 所以,让我试着澄清一下,你有像 file1.html file2.html 这样的文件,它们都导入你的(缩小后)main.min.js ?你需要你的变量 page 在你的 html 文件中的一些内联 javascript 中可用吗?
  • 否定,我有一系列使用 grunt-contrib-concat “合并”的 JS 文件。这些文件中的每一个都包含在它自己的$(document).ready(function(){}); 和(在某些情况下)其他事件中,例如$(window).load(function(){}); 和$(window).resize(function(){});。所以,我需要(在合并文件的开头)有page = $(body).attr('id');,在“合并”文件的最后,有一系列用于所有这些不同文件的函数。所以一开始就有一些东西,最后也有一些东西。那么,我应该使用“wrap”选项吗?
  • 我通过src: ['src/js/banner.js', 'src/js/*.js', 'src/js/functions.js'] 完成了我想要的行为,其中 banner.js 包含我的page = $('body').attr('id'); 并且 functions.js 包含一系列函数.但是,我仍然不确定 grunt-contrib-uglify 的 'wrap' 选项的预期用途。它做同样的事情吗?如果是这样,如何(以及使用什么语法)?
  • 我添加了一个指向我的 OP 的链接,该链接显示了生成的 JS 文件...

标签: javascript node.js gruntjs npm grunt-contrib-uglify


【解决方案1】:

好吧,这个有点棘手,我已经卡了一段时间了......

使用 grunt-contrib-uglify 为 frontend JS

执行此操作的方式

创建多个文件,如

SomeClass.js
OtherClass.js
main.js

并使用一些模块(grunt-file-dependencies 或 grunt-contrib-concat)并设置它来连接您的文件。然后在你的Gruntfile.js 中设置 uglify 就像

...
uglify: {
    options: {
        wrap: "myPublicObject",
        ...
    },

在文件中(例如main.js)必须分配exports变量,整个文件可能如下所示:

var otherClassInst = new OtherClass();
var someClassInst = new SomeClass();

exports = otherClassInst;

现在它究竟做了什么

Uglify 将选择高级上下文 (this) 并在其上定义名为 myPublicObject 的属性。然后它用函数包装你的源代码并在这里创建导出变量(DO NOT DECLARE var exports anywhere)。最后,它会将您导出的内容分配给该属性。如果你不分配任何东西(你不使用exports =)初始值是{},那么带有void对象的属性仍然存在。

为了让这个超级清晰,

  1. 如果你把你的代码放到像&lt;script src="myminifiedfile.min.js"&gt;&lt;/script&gt;这样的页面中,那么优越的上下文是window => window.myPublicObject 是 OtherClass 的实例,而 window.someClassInst、window.SomeClass 和 window.OtherClass 是 undefined。
  2. 这不太可能,但是如果你只是复制缩小结果的内容并用不同的函数包装它,你导出的对象将只能通过 this["myPublicObject"] 可见 => uglify wrap 不会使事物全局可访问,它使它们可访问在优越的环境中。

【讨论】:

    【解决方案2】:

    我在寻找解决方案时遇到了同样的问题。但我想我找到了答案。

    在你的 gruntfile 中使用它:

    uglify: {
      options: {
        wrap: true
      }
    }
    

    wrap 属性的文档表明这些变量将在全局变量中可用,并且查看生成的代码似乎确实如此。将字符串值传递给参数似乎确实会创建一个具有该名称的全局变量。

    但是,wrap: true 似乎使所有对象和属性在全局范围内都可用。因此,您可以使用page.title,而不是globals.page.title(无论如何我无法上班)。简单得多,简单得多。

    如果这符合您的目的,我建议您改为这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多