javascript 使用 RequireJS 通过 shim 加载 Highcharts 并维护 jQuery 依赖
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10907519/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loading Highcharts via shim using RequireJS and maintaining jQuery dependency
提问by Jim Rubenstein
I'm attempting to load the Highcharts library using a shim in RequireJS. However, when Highcharts loads, it throws an exception because it can't access the jQuery methods it depends on.
我正在尝试使用 RequireJS 中的垫片加载 Highcharts 库。但是,当 Highcharts 加载时,它会抛出异常,因为它无法访问它所依赖的 jQuery 方法。
The require config looks like so:
require 配置如下所示:
require.config({
baseUrl: "js",
shim: {
'libs/highcharts/highcharts.src.js': {
deps: ['jquery'],
exports: function(jQuery)
{
this.HighchartsAdapter = jQuery;
return this.Highcharts;
}
}
}
});
The exception that is thrown is:
抛出的异常是:
Uncaught TypeError: undefined is not a function
and is in regards to this line:
和关于这条线:
dataLabels: merge(defaultLabelOptions, {
The issue is the merge
call, which eventually maps itself back to jQuery (or some other adapter that Highcharts supports; but I'm just using jQuery).
问题是merge
调用,它最终将自身映射回 jQuery(或 Highcharts 支持的其他一些适配器;但我只是使用 jQuery)。
I'm not sure exactly how to make sure Highcharts gets access to jQuery using RequireJS and shim.
我不确定如何确保 Highcharts 使用 RequireJS 和 shim 访问 jQuery。
Has anyone used RequireJS and Highcharts together before? I guess the issue isn't specific to highcharts, but any library that has other sorts of dependencies.
有没有人以前一起使用过 RequireJS 和 Highcharts?我想这个问题不是特定于 highcharts 的,而是任何具有其他类型依赖关系的库。
Thanks in advance for any advice or points to the correct direction!
在此先感谢您的任何建议或指向正确方向的点!
To add further context, in hopes that someone who is familiar with require.js or shims will be able to help without having to be too intimately familiar with highcharts, here's some source that sets up this merge
method in Highcharts
要添加更多上下文,希望熟悉 require.js 或 shims 的人能够提供帮助,而不必太熟悉 highcharts,这里有一些merge
在 Highcharts中设置此方法的来源
var globalAdapter = win.HighchartsAdapter,
adapter = globalAdapter || {},
// Utility functions. If the HighchartsAdapter is not defined,
// adapter is an empty object
// and all the utility functions will be null. In that case they are
// populated by the
// default adapters below.
// {snipped code}
merge = adapter.merge
// {snipped code}
if (!globalAdapter && win.jQuery) {
var jQ = win.jQuery;
// {snipped code}
merge = function () {
var args = arguments;
return jQ.extend(true, null, args[0], args[1], args[2], args[3]);
};
// {snipped code}
}
The win
object is a reference set up to window
at the beginning of the script. So, I thought adding window.jQuery = jQuery;
to the export method on the shim would result in highcharts picking up the jQuery reference; but it didn't.
该win
对象是window
在脚本开头设置的引用。所以,我认为window.jQuery = jQuery;
在 shim 上添加导出方法会导致 highcharts 获取 jQuery 参考;但它没有。
Again, any insight, info, advice, or heckles would be appreciated at this point - I'm at a complete loss, and starting to question whether trying to implement and AMD package system in browser javascript is even worth it.
同样,此时将不胜感激任何见解、信息、建议或诘问 - 我完全不知所措,并开始质疑尝试在浏览器 javascript 中实现和 AMD 包系统是否值得。
After accepting the answer from paberabelow I thought it appropriate to update my question to reflect how his answer helped my solution (though, it's basically his answer).
在接受下面pabera的答案后,我认为更新我的问题以反映他的答案如何帮助我的解决方案是合适的(尽管,这基本上是他的答案)。
RequireJS uses "paths" to find libs that aren't "AMD" supported and loads them on your page. the "shim" object allows you to define dependencies for the libraries defined in paths. The dependencies must be loaded before requirejs will try to load the dependent script.
RequireJS 使用“路径”来查找不支持“AMD”的库并将它们加载到您的页面上。“shim”对象允许您为路径中定义的库定义依赖项。必须先加载依赖项,然后 requirejs 才会尝试加载依赖脚本。
The exports property provides a mechanism to tell requirejs how to determine if the library is loaded. For core libs like jquery, backbone, socketio, etc they all export some window level variable (Backbone
, io
, jQuery
and $
, etc). You simply provide that variable name as the exports
property, and requirejs will be able to determine when the lib is loaded.
export 属性提供了一种机制来告诉 requirejs 如何确定库是否已加载。对于 jquery、backbone、socketio 等核心库,它们都导出一些窗口级变量(Backbone
、io
、jQuery
和$
等)。您只需提供该变量名称作为exports
属性,requirejs 将能够确定何时加载 lib。
Once your definitions are done, you can use requirejs
' define
function as expected.
定义完成后,您可以按预期使用requirejs
'define
函数。
Here's my example require.config
object:
这是我的示例require.config
对象:
require.config({
baseUrl: "/js/",
paths: {
jquery: 'jquery',
socketio: 'http://localhost:8000/socket.io/socket.io', //for loading the socket.io client library
highcharts: 'libs/highcharts/highcharts.src',
underscore: 'libs/underscore',
backbone: 'libs/backbone'
},
shim: {
jquery: {
exports: 'jQuery'
},
socketio: {
exports: 'io'
},
underscore: {
exports: '_'
},
backbone: {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
highcharts: {
deps: ['jquery'],
exports: 'Highcharts'
}
}
});
As paberamentioned before, this is for Require.JS
version 2.0.1
.
正如pabera之前提到的,这是针对Require.JS
version 的2.0.1
。
I hope someone gets some use out of this; I know it road blocked me for a little while; so hopefully we kept you from banging your head into the same spot in the wall that we did, by posting this.
我希望有人能从中得到一些好处;我知道这条路挡住了我一会儿;所以希望我们通过发布这个来防止你把你的头撞到我们做过的墙上的同一个地方。
回答by pabera
I had the exact same problem and I was struggling around many hours until I saw your entry here. Then I started over from scratch and now it works for me at least.
我遇到了完全相同的问题,我挣扎了好几个小时,直到我在这里看到您的条目。然后我从头开始,现在它至少对我有用。
requirejs.config({
baseUrl:'/js/',
paths:{
jquery:'vendor/jquery',
handlebars: 'vendor/handlebars',
text: 'vendor/require-text',
chaplin:'vendor/chaplin',
underscore:'vendor/underscore',
backbone:'vendor/backbone',
highcharts: 'vendor/highcharts'
},
shim: {
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
underscore: {
exports: '_'
},
highcharts: {
exports: 'Highcharts'
}
},
});
Since I use Chaplinon top of Backbone, I am including some more files in my paths attribute. Highcharts has a similar structure to Backbone so I thought I could load it the same way. It works for me now. As you can see, I am introducing highcharts in the paths attribute already to export it as a shim afterwords.
由于我在 Backbone 之上使用Chaplin,因此我在我的路径属性中包含了更多文件。Highcharts 的结构与 Backbone 相似,所以我想我可以用同样的方式加载它。它现在对我有用。如您所见,我已经在路径属性中引入了 highcharts,以便将其作为 shim 后记导出。
Maybe this helps, otherwise let's try to contribute on it even more to solve your problem.
也许这会有所帮助,否则让我们尝试为解决您的问题做出更多贡献。
回答by Simon Smith
Although jQuery can be used as an AMD module it will still export itself to the window anyway so any scripts depending on the global jQuery
or $
will still work as long as jQuery has loaded first.
尽管 jQuery 可以用作 AMD 模块,但它仍然会将自身导出到窗口中,因此任何依赖于全局的脚本jQuery
或$
只要 jQuery 已先加载就仍然可以工作。
Have you tried setting a path? jQuery is an interesting one because although you're encoruaged not to name your modules by the RequireJS documentation, jQuery actually does.
您是否尝试过设置路径?jQuery 很有趣,因为尽管 RequireJS 文档鼓励您不要命名模块,但 jQuery 确实做到了。
From the jQuery source
来自 jQuery 源
if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
define( "jquery", [], function () { return jQuery; } );
}
What that means is you will need to tell RequireJS where to find 'jquery'. So:
这意味着您需要告诉 RequireJS 在哪里可以找到“jquery”。所以:
require.config({
paths: {
'jquery': 'path/to/jquery'
}
});
If you're interested in why jQuery registers itself this way then there is a pretty large comment in the sourcewhich goes into more detail
如果您对 jQuery 为何以这种方式注册自己感兴趣,那么源代码中有一个非常大的注释,其中详细介绍了