【问题标题】:Browserify execute a module code only once , on multiple require callsBrowserify 在多个 require 调用上只执行一次模块代码
【发布时间】:2016-06-09 20:34:29
【问题描述】:

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'),这会导致 app.js 中的代码在每次调用 require('app') 时都会执行。

因此,我收到Backbone.history has already been started 的错误。 这个问题的解决方法是代码在初始化时只被调用一次。

我该如何解决?

【问题讨论】:

  • 我真的觉得在使用模块模式时我根本不需要 Application 对象。只需摆脱它,拥有一个启动历史记录并设置路由器的app.js 文件。有了 Regions、Initializers 和 Application channel deprecated 以及即将发布的 v3.x 版本,我个人认为,当您拥有模块系统时,它确实不会提供太多有用的东西。
  • 一定会试试的
  • 对资源的任何建议可以让我了解您所说的内容,我们将不胜感激
  • 我可以尝试用一些脚手架为我设置我的最后一个木偶项目的方式写一个答案,但我不能做出任何承诺,因为我现在有点忙(这是为什么我评论而不是回答)。接受的答案中的建议没有任何问题(如果您想要多态,您甚至可以检查您是否在服务器上并使用global 而不是window)。
  • 如果可能的话,你能提供一个项目的链接吗

标签: javascript backbone.js marionette browserify commonjs


【解决方案1】:

您不想将require 用于实例化对象。它可以使用,但经验表明,虽然模块导出应该被缓存,但在很多情况下它不是并且会引发错误。我发现最好将require 用于静态对象/方法。确保单例的最佳方法是在根方法中实例化,然后将实例传递给需要它的模块。

如果您想使用require 重构现有代码库,您可以将实例化对象绑定到全局对象(如window),然后在您的启动部分中检查该对象在该全局上的实例对象并返回它。

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 更多)。也许迁移到不同的模块系统会为您解决这个问题。最终,问题仍然是实例化模块有点滥用模式。虽然污染全局范围并不理想,但我认为它更接近您想要的单例模式,并且无论构建工具的特定模块缓存方法如何,它都将始终有效。

【讨论】:

  • 但是污染全局命名空间不是坏习惯
  • 理论上是这样,特别是如果你想运行多态代码。但是,如果您的目标是及时启动工作代码而不必重写整个库,那么它就变成了一个小问题。
  • 我想暂时,我会选择你的解决方案
猜你喜欢
  • 2021-04-19
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多