require.js与内联js

时间:2013-08-06 01:39:51

标签: requirejs web-analytics

我正在开发一个使用require.js的网络应用。我对应用程序和requirejs都很陌生,并且想知道对于我遇到的问题,最佳解决方案是什么。我们一直在使用PHP包含文件中的脚本标记加载第三方用户分析/跟踪库。我们不使用requirejs,因为php正在设置一些js运行时值。

以下是一个这样的块的例子:

<script src="//js.revsci.net/gateway/gw.js?csid=A08723"></script>
<script type="text/javascript">
    <?php
        global $base_url;
        $host = parse_url( $base_url, PHP_URL_HOST );
    ?>
    if( typeof DM_cat != 'undefined' ) {
        DM_cat('Track');
        DM_tag();
    }
</script>

现在我同意,将js和php结合起来并不理想,但是所有的分析代码都是用这种方式编写的,并且有很多。我没有时间(或知识)来重构所有requirejs方式,所以我暂时坚持这个结构。现在我被要求将这些第三方脚本设为“异步”或“延迟”。如果可能的话,我更喜欢异步,但要么是可接受的解决方案。所以我想改变这个:

<script src="//js.revsci.net/gateway/gw.js?csid=A08723"></script>

到此:

<script src="//js.revsci.net/gateway/gw.js?csid=A08723" defer></script>

我的问题是,如何在加载脚本之前使用Require加载第三方脚本并阻止内联javascript块执行?从我试图编写的代码中,我不断收到“不匹配的匿名define()模块”错误。我已经阅读了错误,但我无法理解它。即使我粘贴一个基本的例子,我仍然会收到该错误。例如,我甚至无法使用此测试代码:

define(["testcode"], function(testcode){
  window.foo = "bar";
});

define(["foo"], function(){
  alert(window.foo);  // "bar"
});

错误讯息:

Uncaught Error: Mismatched anonymous define() module: function
(testcode){   window.foo = "bar"; }

我不明白这个错误,任何人都可以帮我指出正确的方向吗?提前谢谢!

2 个答案:

答案 0 :(得分:2)

派对晚了,但是这个错误是由于在单个文件中有2个define语句而没有命名它们引起的。这是区分您在单个文件中声明的两个模块所必需的。您需要添加如下名称参数:

define('Name1', ["testcode"], function(testcode){
  window.foo = "bar";
});

define('Name2', ["foo"], function(){
  alert(window.foo);  // "bar"
});

见这两个: - Documentation - Related Stackoverflow Article

答案 1 :(得分:1)

nopuck4you建议您将模块名称添加为define调用的第一个参数。 如果这些模块是在HTML内部的<script>标记内创建的,那就没关系。这是罕见例外之一,您可以将模块名称作为define的第一个参数。实际上,在这种情况下,你来命名模块,否则RequireJS找不到它们。所以你有:

<script>
define("foo", ["testcode"], function(testcode){
  window.foo = "bar";
});

define("test", ["foo"], function(){
  alert(window.foo);  // "bar"
});
</script>

(我假设第二个模块依赖于第一个和相应的命名。我不知道testcode是什么,所以我把它保留原样。)

但是,通常,您不应通过在define调用中添加名称来为模块命名。 RequireJS文档对此非常清楚。如果您 define中为您的模块命名,由于RequireJS的工作方式,这可能会导致问题。事情不会起作用,或者它们无法正常工作除非你解决问题。例如,如果您将模块foobar放在foo.js中并将其名称作为define的第一个参数,那么RequireJS将无法解决该模块{ {1}}位于foo,但foo.jsbar {<1}}。 根据您加载模块的顺序,您可能需要进行其他配置,告知RequireJS foo.js位于bar

将模块的名称放在foo.js电话中会导致失败,意外,并发症等。不要这样做。保留名称,让RequireJS弄明白。然后,在优化时,让define将名称放入。

注意:您可能已经看到第三方的一些代码,这些代码将模块名称放在r.js中。 jQuery是一个突出的案例。我上面所说的有例外,但是如果你不能清楚地说明为什么你需要把这个名字放进去,那么你就不需要这么做了。 (事实上​​,在查看jQuery案例时,我认为没有充分的理由将该名称放在define那里,在我看来他们犯了一个错误。)