如何将全局/公共变量添加到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的文档中列出了一个"包装"选项。然而,没有给出如何使用它的例子

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

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

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

还有我的Gruntfile链接:Gruntfile.js

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

在你的咕哝文件中使用这个:

uglify: {
options: {
wrap: true
}
}

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

然而,wrap: true似乎使全局范围中的所有对象和属性都可用。因此,您可以使用page.title来代替globals.page.title(无论如何,我都无法使用它)。简单多了。

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

好吧,这个很棘手,我已经被卡住了一段时间。。。

对于前端JS,使用grunt contrib uglify的方法

创建多个文件,如

SomeClass.js
OtherClass.js
main.js

使用一些模块(grunt文件依赖项或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的属性。然后,它用函数包装源代码,并在此处创建导出变量(不要在任何地方声明var exports)。最后,它会将您导出的内容指定给该属性。如果不分配任何内容(不使用exports=),则初始值为{},因此带有void对象的属性仍然存在。

为了使这一点非常清楚,

  1. 如果将代码放入类似<script src="myminifiedfile.min.js"></script>的页面,则上级上下文为window=>window.myPublicObjectOtherClass的实例,而window.someClassInstwindow.SomeClasswindow.OtherClassundefined
  2. 这是不可能的,但如果你只是复制缩小后的结果的内容,并用不同的函数包装它,你导出的对象将仅通过this["myPublicObject"]=>uglify包装可见。包装不能使事情全局可访问,它使它们在高级上下文中可访问

最新更新