我已经加载了带有凉亭的把手,因此它位于供应商目录中。看来我已经配置了所有内容,我可以在检查器中看到handlebars.js文件被加载,它没有给出404 ...但据我所知,以下内容应该将它附加到全局命名空间(窗口)。正如您所看到的,我的模块已经“加载”并且工作正常,但在该模块中它依赖于把手 - ReferenceError: Handlebars is not defined
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配置加载):
if(typeof loaded === "undefined") loaded = {};
loaded.dispatch = (function() {
// ...
return {
render: function () {
// ...
// gets this far, but error as the library is missing
var template = Handlebars.compile(_template);
// ...
}
}
})();
如上所述,我可以在检查器中看到Handlebars不是全局命名空间(窗口)的属性。从我读过的其他帖子中,我看不出我配错了什么。此外,由于需要加载,我不确定把手的问题是什么。
更新
作为把手版本的新main.js不需要它,它似乎:
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"]);
答案 0 :(得分:1)
您不需要(也不应该)垫片handlebars
,因为库集成了UMD wrapper,因此与AMD pattern兼容(其中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
附加到根对象(window
)。
结果,显然,你的垫片无法找到它。
现在你的问题是你想要使用Handlebars,一个AMD加载的模块,非AMD模块。不幸的是,这不受官方支持:
仅使用其他" shim"模块作为shimmed脚本的依赖项,或者没有依赖项的AMD库,在它们创建全局(如jQuery或lodash)之后调用define()。否则,如果您使用AMD模块作为shim配置模块的依赖项,则在构建之后,可能不会在构建中的填充代码执行之后评估该AMD模块,并且将发生错误。最终的解决方法是将所有已调整的代码升级为可选的AMD define()调用。
没有好的解决方案。以下是一些想法:
(1)我仍然设法通过创建globalHandlebars
模块来实现:
define(["handlebars"], function(Handlebars){
window.Handlebars = Handlebars;
});
但这非常hacky并且没有得到官方支持。实际上,似乎无法保证在加载非AMD脚本之前调用dep define
。我的笔记本电脑上从未发生过......
(2)另一种使其有效的方法是将handlebars
作为脚本添加到您的html文件之前 requirejs
(以便define
尚未定义)。
仍然非常hacky,如果你也使用requirejs
的把手,它将加载两次......
(3)显然,如果您可以将loaded
脚本包裹在define
电话中,那么效果最好,但我想这可能是不可能的。
(4)如果您使用优化工具,则还有一个wrapShim
选项,但它并不总是有效,具体取决于您的填充代码的内容。
我没有任何其他解决方案,但requirejs
人可能有一个解决方案。我很惊讶没有人在你面前绊倒这个问题。
您也可以考虑切换到browserify或webpack而不是requirejs(webpack本身支持AMD模块,而且有AMD loader用于browserify)。
此外,它们都可以让您预先构建模板(使用this loader表示webpack,或使用transform表示browserify),并避免包含整个handlebars
库,这始终是一个好习惯。