gpt4 book ai didi

javascript - 通过 Grunt 将 JS 文件包含在另一个文件中,而不需要 Require.js

转载 作者:太空宇宙 更新时间:2023-11-04 02:24:15 27 4
gpt4 key购买 nike

我正在编写一个 Backbone.js 项目。目前,我的所有应用程序代码(一堆 View )都存在于一个巨大的整体文件中,结构如下:

'use strict';
(function(window, $, Backbone){
var app = app || {
Views: {}
Models: {}
Collections: {}
};

app.Views.MainView = Backbone.View.extend({
// etc etc. tons of code in here
});

app.views.ChildView = Backbone.View.extend({
// etc. etc. tons of code in here too.
});

$(function() {
new App.Views.MainView();
});
}(window, jQuery, Backbone))

该文件变得有点不奇怪,相反,我想将我的 View 分解为自己的文件,即 views/Main.jsviews/Child.js

我最初的想法是使用 Grunt 将所有文件连接在一起,但是我希望将所有代码包装在 IIFE 中,如上面所示。

使用 Grunt,在 IIFE 中“包含”文件的最干净/最简单的方法是什么?有点像 usemin,但用于 JavaScript 内部而不是标记。

最佳答案

根据我的经验,我发现最好将单独的模块留在它们自己的闭包(IIFE)中。以下代码示例演示了将所有文件组合在一个闭包中而不是将每个文件包装在自己的闭包中的陷阱:

//Your big closure
(function () {

//Included from file 1
var defaultOptions = {
label: 'Testing1'
};

window.MyObject1 = function (options) {
this.options = $.extend({}, defaultOptions, options);
}

//Included from file 2
var defaultOptions = {
label: 'Testing2'
};

window.MyObject2 = function (options) {
this.options = $.extend({}, defaultOptions, options);
}

})();

//Later in the site, you decide to use some objects:
var obj1 = new MyObject1();
var obj2 = new MyObject2();


$('#obj1').text(obj1.options.label);
$('#obj2').text(obj2.options.label);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="obj1"></div>
<div id="obj2"></div>

我通过利用事件在模块之间进行通信。

例如,假设您有一个工具栏和一个对话框,并且您希望在按下工具栏按钮时打开对话框。

(function () {

window.MyToolbar = function () {
this.onOpenDialogButtonClicked = function () {
$(document).trigger(window.events.MyDialog.open); //you can also send it data as the second parameter if you need to.
};
};

})();

(function (events) {

//Define your custom events for this dialog.
$.extend(events, {
MyDialog: {
open: 'window.events.myDialog.open' //Need a unique string here. I go back later and CRC32 these to help with minification.
}
});

window.MyDialog = function () {
$(document).on(window.events.MyDialog.open, function () {
//open the dialog here!
$('#dialog').text('opened!');
});
};

})(window.events = window.events || {});

var toolbar = new MyToolbar();
var dialog = new MyDialog();

$(document).on('click', '#button', toolbar.onOpenDialogButtonClicked);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="button">Open Dialog</button>
<div id="dialog"></div>

这样做的好处是不需要依赖加载顺序。在此示例中,工具栏模块需要加载对话框模块以供 window.events.MyDialog.open 解析,但仅在实际按下按钮时才需要。

如果这是一个问题,您可以将事件声明移动到一个名为 events.js 或其他文件的文件中。

除了事件的名称之外,还可以按下工具栏按钮,并且不需要引用对话框即可打开它。该对话框监听打开事件。如果它收到一个,它就会自行打开。如果没有对话框正在监听,则该按钮不会执行任何操作。

此示例还演示了模块如何通过将本来位于全局空间中的项目附加到全局空间来进行通信。就我个人而言,我创建了一个位于全局空间中的“命名空间”变量,并将我的所有内容附加到其中。

例如:

(function (myNamespace) {

//This is assuming myNamespace.events exists already - make sure it does before calling this.
$.extend(myNamespace.events, {
MyDialog: { open: 'myNamespace.events.MyDialog.open' }
});

})(window.myNamespace = window.myNamespace || {});

这只是封装了我编写的内容,并防止它与其他库可能放置在全局空间中的内容发生冲突。

<小时/>

因此,虽然您可以通过将所有文件连接到一个闭包中来在缩小过程中节省一些字节,但您可能会陷入一些不必要的麻烦。启用压缩和 gzip 后,在单个闭包下连接所有内容所节省的字节数是微不足道的。

我已经展示了闭包如何相互通信,以及隐藏模块私有(private)的项目。

我没有使用过 Backbone.js,很抱歉在示例中没有包含任何 Backbone.js 内容。我确信这些想法能够转化。

关于javascript - 通过 Grunt 将 JS 文件包含在另一个文件中,而不需要 Require.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31460597/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com