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