好吧,所以我对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.js
和after.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对象的属性仍然存在。
为了使这一点非常清楚,
- 如果将代码放入类似
<script src="myminifiedfile.min.js"></script>
的页面,则上级上下文为window
=>window.myPublicObject
是OtherClass
的实例,而window.someClassInst
、window.SomeClass
和window.OtherClass
是undefined
- 这是不可能的,但如果你只是复制缩小后的结果的内容,并用不同的函数包装它,你导出的对象将仅通过
this["myPublicObject"]
=>uglify包装可见。包装不能使事情全局可访问,它使它们在高级上下文中可访问