不需要访问配置文件,使用requirejs加载外部脚本

13

我正在编写一个插件,尝试加载datatables JavaScript库。问题是,在加载外部资源时,我遇到了冲突,因为当我调用require时,datatables与某些内容发生了冲突。

<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="//cdnjs.cloudflare.com/ajax/libs/datatables/1.9.4/jquery.dataTables.min.js"></script>
...
<script type="text/javascript">
    require(['forum/admin/footer']);  <-- crashes here, line 281
</script>

这是错误信息:

Uncaught Error: Mismatched anonymous define() module: function (h){var j=function(e){function o(a,b){var c=j.defaults.columns,d=a.aoColumns.length,c=h.extend({},j.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSor...<omitted>...ch require.js:8
B require.js:8
M require.js:15
d require.js:26
requirejs require.js:31
(anonymous function) (index):281

由于这是一个插件,我有一些限制需要解决,例如无法在开头调用 require.config() 来指定资源路径。我看到有人使用了 define 函数,像这样: define('resource', ['http://cdn.ajax.blah']); 在这篇博客中, 但它似乎不能以这种方式使用,因为其他所有示例的第二个参数都是一个函数。

2个回答

13

这个问题中使用的方法不起作用,因为DataTables是AMD感知的。如果它检测到有一个AMD风格的加载程序(例如RequireJS),那么它将定义自己为一个模块。然而,使用<script>加载AMD模块是无效的,这也是出现错误消息的原因。

forum/admin/footer中的模块应该被定义为需要DataTables:

define([..., 
        '//cdnjs.cloudflare.com/ajax/libs/datatables/1.9.4/jquery.dataTables.min.js'], 
        function (...) {
});

由于DataTables是一个jQuery插件,所以不需要对应于DataTables模块的参数。

关于在已经配置RequireJS的网站中集成此插件的更广泛问题,有以下几点需要注意:

  1. require.config可以被多次调用以添加配置。然而,如果不期望插件和主要代码之间进行协调,则可能会被认为是不可接受的。

  2. RequireJS有一个名为context的概念。文档讨论了它用于加载多个版本,但也许可以成功地改编它来允许插件特定的配置。


我可以在 require 调用中命中函数参数内部,并加载所有脚本(jquery.js、jquery-ui.js、code.jquery.com/jquery-1.7.2.min.js、jquery.min.js、jquery.datatables.js),但是现在我仍然遇到了问题,即 dataTable() 不是一个可从 jQuery 对象调用的函数。 - BrDaHa
jQuery是否被多次加载?你提到的这种设置很容易发生这种情况。例如,如果主代码加载了jQuery并将其作为“jquery”模块可访问,而您的插件加载了jQuery但是从CDN加载它,那么DataTables插件将安装在由主代码加载的jQuery模块上,而不是由插件加载的模块上。 - Louis
我会深入研究一下为什么所有这些都被加载。我实际上做了更多的尝试并使其工作,但你能告诉我为什么这个有效:http://jsfiddle.net/zMqZ3/7/ 而这个无效:http://jsfiddle.net/zMqZ3/5/ 吗? - BrDaHa
那个能工作的很大程度上是由于偶然性。RequireJS被加载,然后jQuery被加载并检测到RequireJS已经存在,因此调用define等。第二个不起作用,因为DataTables的开发人员决定版本1.10-dev将调用define("datatables", ...)。我的答案是根据最后发布的版本编写的,该版本不会这样做。结果是从1.10开始,您必须通过名称“datatables”请求DataTables,并设置路径以查找实际文件。之前的版本不需要这样做。 - Louis

11

你刚刚尝试了一个简单的方法吗:

require(['//cdnjs.cloudflare.com/ajax/libs/datatables/1.9.4/jquery.dataTables.min.js']);

毫无疑问,它适用于本地文件。


1
这个确实可以工作,只是不符合我的需求。它可以正常加载库,但由于它是异步的,$(document).ready()函数会在脚本加载之前触发(我在其中调用datatables插件)。 - BrDaHa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接