Javascript Can';t使用所需配置路径和垫片加载把手

Javascript Can';t使用所需配置路径和垫片加载把手,javascript,requirejs,amd,Javascript,Requirejs,Amd,我已经用bower加载了把手,因此它位于供应商目录中。似乎我已经配置了所有东西,在inspector中可以看到handlebar.js文件已加载,但没有给出404。。但据我所知,下面应该将其附加到全局名称空间(窗口)。正如您所看到的,我的模块已“加载”,并且工作正常,但在该模块内,它取决于把手-ReferenceError:没有定义把手 requirejs.config({ baseUrl: "/scripts", urlArgs: "bust=" + (new Date()).

我已经用bower加载了把手,因此它位于供应商目录中。似乎我已经配置了所有东西,在inspector中可以看到handlebar.js文件已加载,但没有给出404。。但据我所知,下面应该将其附加到全局名称空间(窗口)。正如您所看到的,我的模块已“加载”,并且工作正常,但在该模块内,它取决于把手-
ReferenceError:没有定义把手

requirejs.config({
    baseUrl: "/scripts",
    urlArgs: "bust=" + (new Date()).getTime(),
    paths: {
        "jquery": "vendor/jquery/dist/jquery",
        "loaded": "vendor/loaded/dist/loaded",
        "handlebars": "vendor/handlebars/handlebars"
    },
    shim: {
        "loaded": {
            deps: ["jquery", "handlebars"],
            exports: "loaded"
        },
        "handlebars": {
            exports: "Handlebars"
        }
    }
});

requirejs(["app"]);
下面是加载模块的一个片段(非AMD,使用shim config加载):

如前所述,我可以在inspector中看到Handlebar不是全局名称空间(窗口)的属性。从我读过的其他帖子中,我看不出我配置错了什么。此外,由于装载是必需的,我不知道什么问题是与把手

更新

新的main.js作为Handlebar版本不需要它,看起来:

requirejs.config({
    baseUrl: "/scripts",
    urlArgs: "bust=" + (new Date()).getTime(),
    paths: {
        "jquery": "vendor/jquery/dist/jquery",
        "loaded": "vendor/loaded/dist/loaded",
        "handlebars": "vendor/handlebars/handlebars"
    },
    shim: {
        "loaded": {
            deps: ["jquery", "handlebars"],
            exports: "loaded"
        }
    }
});

requirejs(["app"]);
您不需要(也不应该)垫片
把手
,因为库集成了,因此与兼容(其中
requirejs
是一个实现):

实际上,因为库在加载时会找到
define
函数,所以它不会将
handlebar
附加到根对象(即
window
)。 因此,很明显,您的垫片找不到它

现在你的问题是,你想使用手柄,一个AMD加载模块,与非AMD模块。不幸的是,这没有得到官方支持:

仅使用其他“垫片”模块作为填充脚本的依赖项,或没有依赖项的AMD库,并在创建全局(如jQuery或lodash)后调用define()。否则,如果在生成后将AMD模块用作垫片配置模块的依赖项,则在执行生成中的垫片代码之前,可能不会评估该AMD模块,并且会发生错误。最终的修复方法是升级所有填充代码,使其具有可选的AMD define()调用

没有好的解决办法。以下是一些想法:

(1)我仍然通过创建一个
globalHandlebar
模块使其工作,该模块具有:

define(["handlebars"], function(Handlebars){
    window.Handlebars = Handlebars;
});
但这是非常黑客的,没有官方支持。事实上,似乎无法保证在加载非AMD脚本之前调用dep的
define
。但我的笔记本电脑上从未发生过

(2)另一种方法是在
requirejs
之前将
把手作为脚本包含在html文件中(因此
定义
)。
仍然非常粗糙,如果你也使用带有
requirejs
的把手,它将被加载两次

(3)显然,最好的方法是将
加载的
脚本包装在
定义
调用中,但我想这可能是不可能的

(4)如果您使用Optimizer,也有一个选项,尽管它并不总是有效,这取决于填充代码的内容

我没有任何其他解决方案,但可能
requirejs
的人有一个。我很惊讶在你之前没有人偶然发现这个问题

您还可以考虑切换到RealJavaS或WebPACS(WebPACK本身支持AMD模块,还有一个用于BRESYLIST)。


此外,这两种方法都可以让您预先构建模板(用于webpack或用于browserify),并避免包含整个
把手
库,这一直是一种很好的做法。

感谢您的回复。我有Handlebar v4.0.4,我可以在文件中看到它确实有
if。。否则。。否则
您发布的条件。我匹配了您提供的配置(移除了车把垫片),但仍然得到相同的错误。看来main.js(带有配置的文件)也并没有被缓存。因此,如果没有将把手附加到窗口对象,您知道我应该在DOM中的何处找到它吗?我尝试在DOM检查器中搜索,但没有找到任何结果。还有什么我可以看的吗?我将使用newmain.js更新我的操作。再次感谢。在全局上下文中可能根本不会追加它(变量永远不会追加到dom中,dom用于节点,例如div,而不是变量)。使用requirejs,您可以检索模块作为define函数的参数:
define([“handlebar]”,function(handlebar){/*stuff*/}
。我目前没有电脑,但稍后会仔细查看。我编辑了我的答案。不幸的是,这还远远不够完美,但我认为你不能做得更好。事实上,我从Handlebar(可选AMD define)中复制了你的代码并为我加载的库调整了它。这样,我也不必填充加载的库,因为手柄是一种正确的依赖关系。而且,我猜手柄也设置为一个模块,现在没有任何东西被修改为全局名称空间。我猜这是首选方法,可能是我为第三方librari尝试的方法不支持定义调用的es。无论如何,这对您的帖子非常有帮助,因为我对requirejs还是新手,正在尝试学习最佳实践。再次感谢。
if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
else if(typeof define === 'function' && define.amd)
    define([], factory);
else if(typeof exports === 'object')
    exports["Handlebars"] = factory();
else
    root["Handlebars"] = factory();
define(["handlebars"], function(Handlebars){
    window.Handlebars = Handlebars;
});