如何将全局/公共变量添加到grunt-contrib-uglify输出

时间:2015-04-13 21:21:30

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

好的,所以我是Grunt和Node.js的新手。我正在建立一个网站,并认为'main.js'文件太大了。所以,我把它拆分了,现在我正在尝试使用Grunt将所有这些JS文件重新组合在一起。

我遇到的问题是我需要为所有这些JS文件中的所有各种函数提供一些全局变量。更具体地说,我们网站上的每个页面都通过正文标记中的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'选项 - 如果这是我正在尝试做的正确的咕噜插件?

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

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

和我的Gruntfile的链接: Gruntfile.js

2 个答案:

答案 0 :(得分:0)

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

在你的gruntfile中使用它:

uglify: {
  options: {
    wrap: true
  }
}

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

但是,wrap: true似乎使全局范围内的所有对象和属性都可用。因此,您可以使用globals.page.title代替page.title(无论如何我都无法工作)。更容易,更简单。

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

答案 1 :(得分:0)

好的,这个很棘手,我已经被困了一段时间......

使用 grunt-contrib-uglify 前端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的属性。然后用函数包装你的源代码并在这里创建exports变量(不要声明 var exports 任何地方)。最后,它将分配您导出到该属性的内容。如果你没有指定任何东西(你不使用exports =),初始值是{},所以无论如何都存在带有void对象的属性。

为了使这个超级清晰,

  1. 如果您将代码放入<script src="myminifiedfile.min.js"></script>这样的页面,则上级上下文为window =&gt; window.myPublicObjectOtherClass的实例,而window.someClassInstwindow.SomeClasswindow.OtherClassundefined
  2. 这不太可能,但如果你只是复制缩小结果的内容并用不同的功能包装它,你导出的对象只能通过this["myPublicObject"] =&gt;看到。 uglify wrap不会使全局可访问,它使它们可以在更好的环境中访问。