如何使用Require.js加载Q库?

2022-02-28 00:00:00 javascript requirejs q

我的库使用kriskowal/Q promises library,现在我正在尝试加载使用我的库的应用程序(使用requijs),因此我放置了所有路径和垫片,我的requirejs.config部分如下所示:

requirejs.config({
    baseUrl: './',
    catchError: false,
    paths: {
        beril: '../engine/build/src/bundle',
        lodash: 'bower_components/lodash/lodash',
        three: 'bower_components/three.js/build/three',
        q: 'bower_components/q/q',

    },
    shim: {
        lodash: {
            exports: '_'
        },
        three: {
            exports: 'THREE'
        },
        q: {
            exports: 'Q'
        },
        beril: {
            deps: ['lodash', 'three', 'q'],
            exports: 'beril'
        },
    }
});
之后,我假设变量3、_和q在全局空间中定义。 现在,我用下面这行简单的代码加载和运行应用程序:

require(['beril', 'js/stepbystep/' + $stateParams.page + '/app'], (beril, app) => app());
但是我收到了错误:即使我可以在Chrome的网络检查器中看到Q库已经加载。

还定义了所有睡觉依赖项(三个和_)。看来Requirejs的填充程序不适用于此库。可能是还是我遗漏了什么?

那么我做错了什么,我应该如何处理这种情况?


解决方案

您的配置有几个问题。首先,您有不必要的shim配置。我刚刚安装了locash(使用bower install lodash)并搜索了它的代码。它调用define。因此您不能为其设置shim。RequireJS不会给您一个错误,但是您会得到未定义的行为。q也是如此:它调用defineso,因此不调用shim。Last I checked,THREE需要shim

q调用define的事实也是它不会将符号Q泄漏到全局空间的原因。它的作用类似于性能良好的AMD模块。

好的,那么我们怎样才能让Beril找到Q呢?Your solution有效,但我觉得有点可疑。问题是init是在加载填充模块之后执行的。只要Beril只在稍后执行的函数体中引用Q,它就可以工作。我猜这就是贝里尔现在的工作方式。但是,如果新版本的Beril在包含Beril的文件首次执行时需要引用Q,则会失败,因为Q尚不存在。

解决该问题的一种方法是使用map和一些胶水,这是面向未来的。保留berilshim,但删除init。定义名为q-glue

的模块
define(['q'], function (Q) {
    window.Q = Q;
    return Q;
});

并在您的配置中声明map

map: {
    beril: {
        q: "q-glue"
    }
}
显示为"当从beril加载q-glue请求q时"。通过执行此操作,将在加载Beril之前定义window.Q

我猜你是"贝里尔"的作者。我强烈建议您使您的库与AMD兼容,这样您的库的用户就不必经历配置之苦才能使其与AMD加载器(如RequireJS)一起工作。

相关文章