Browserify 在多次 require 调用时只执行一次模块代码
Browserify execute a module code only once , on multiple require calls
app.js
var MedicineManager = new Marionette.Application();
MedicineManager.addRegions({
mainRegion: "#main-region"
});
MedicineManager.navigate = function (route, options) {
options || (options = {});
Backbone.history.navigate(route, options);
};
MedicineManager.getCurrentRoute = function () {
return Backbone.history.fragment;
};
MedicineManager.on("start", function () {
if (Backbone.history) {
Backbone.history.start();
}
});
$(function () {
MedicineManager.start();
})
module.exports=MedicineManager;
我正在尝试将我的应用程序从 Marionette 模块模式移动到 Browserify。
我在多个文件中调用 require('app')
,这会导致每次调用 require('app')
时执行 app.js 中的代码。
因此,我收到 Backbone.history has already been started
的错误。
这个问题的解决方案是代码只在初始化时被调用一次。
如何解决?
您不想将 require
用于实例化对象。它可以使用,但经验表明,虽然模块导出应该被缓存,但在很多情况下它不会被缓存并抛出错误。我发现静态 objects/methods 最好使用 require
。确保单例的最佳方法是在根方法中实例化,然后将实例传递到需要它的模块中。
如果您想使用 require
重构现有代码库,您可以将实例化对象绑定到全局对象(如 window
),然后检查实例的启动部分这个对象在那个全局对象上,而不是 return 它。
module.exports = function () {
if (!window.__medicineManager){
var MedicineManager = new Marionette.Application();
MedicineManager.addRegions({
mainRegion: "#main-region"
});
MedicineManager.navigate = function (route, options) {
options || (options = {});
Backbone.history.navigate(route, options);
};
MedicineManager.getCurrentRoute = function () {
return Backbone.history.fragment;
};
MedicineManager.on("start", function () {
if (Backbone.history) {
Backbone.history.start();
}
});
MedicineManager.start();
window.__medicineManager = MedicineManager;
}
return window.__medicineManager;
}()
更新:
顺便说一句,Browerify 似乎特别有这个问题(比 CommonJS 或 WebPack 更严重)。也许转移到不同的模块系统将为您解决这个问题。最终,问题仍然是实例化模块有点误用了模式。虽然污染全局范围并不理想,但我认为它更接近您想要的单例模式并且将始终有效,无论构建工具的特定模块缓存方法如何。
app.js
var MedicineManager = new Marionette.Application();
MedicineManager.addRegions({
mainRegion: "#main-region"
});
MedicineManager.navigate = function (route, options) {
options || (options = {});
Backbone.history.navigate(route, options);
};
MedicineManager.getCurrentRoute = function () {
return Backbone.history.fragment;
};
MedicineManager.on("start", function () {
if (Backbone.history) {
Backbone.history.start();
}
});
$(function () {
MedicineManager.start();
})
module.exports=MedicineManager;
我正在尝试将我的应用程序从 Marionette 模块模式移动到 Browserify。
我在多个文件中调用 require('app')
,这会导致每次调用 require('app')
时执行 app.js 中的代码。
因此,我收到 Backbone.history has already been started
的错误。
这个问题的解决方案是代码只在初始化时被调用一次。
如何解决?
您不想将 require
用于实例化对象。它可以使用,但经验表明,虽然模块导出应该被缓存,但在很多情况下它不会被缓存并抛出错误。我发现静态 objects/methods 最好使用 require
。确保单例的最佳方法是在根方法中实例化,然后将实例传递到需要它的模块中。
如果您想使用 require
重构现有代码库,您可以将实例化对象绑定到全局对象(如 window
),然后检查实例的启动部分这个对象在那个全局对象上,而不是 return 它。
module.exports = function () {
if (!window.__medicineManager){
var MedicineManager = new Marionette.Application();
MedicineManager.addRegions({
mainRegion: "#main-region"
});
MedicineManager.navigate = function (route, options) {
options || (options = {});
Backbone.history.navigate(route, options);
};
MedicineManager.getCurrentRoute = function () {
return Backbone.history.fragment;
};
MedicineManager.on("start", function () {
if (Backbone.history) {
Backbone.history.start();
}
});
MedicineManager.start();
window.__medicineManager = MedicineManager;
}
return window.__medicineManager;
}()
更新:
顺便说一句,Browerify 似乎特别有这个问题(比 CommonJS 或 WebPack 更严重)。也许转移到不同的模块系统将为您解决这个问题。最终,问题仍然是实例化模块有点误用了模式。虽然污染全局范围并不理想,但我认为它更接近您想要的单例模式并且将始终有效,无论构建工具的特定模块缓存方法如何。