【问题标题】:RequireJS, Shim doesn't work correct when CDN failover occursRequireJS,发生 CDN 故障转移时 Shim 无法正常工作
【发布时间】:2015-04-16 04:30:47
【问题描述】:

我有网站,它使用 intranet(小份额)以及 internet(大份额)。内网环境,不能上网。我计划为互联网用户从 CDN 加载 JavaScript,同时为 Intranet 用户使用本地版本。我正在使用 RequireJS 库来动态加载脚本,并在无法从 CDN 检索时使用故障转移。

我正在使用以下 requireJS 配置从 CDN 加载 jQuery 库或使用本地库。

出现问题,当 RequireJS 无法从 CDN 加载时,它会在加载本地版本的 jquery 之前加载引导库。这会导致两个错误,来自 bootstrap 的“Bootstrap 需要 jQuery”和来自 requireJS 的超时错误。

我的问题,如何避免这种情况?我希望引导程序等到加载任何(CDN 或本地)版本的 jQuery。我已经使用 Shim 来定义对 jQuery 库的引导依赖。但是,它并没有按预期工作。这是 requireJS 中的已知错误吗?

这里是我的配置代码

require.config({
    paths: {
        jquery: ['https://code.jquery.com/jquery-1.10.2'
            , '/Scripts/_Ref/jquery-1.10.2'],
        async: '/Scripts/_Ref/async',
        propertyParser: '/Scripts/_Ref/propertyParser',
        goog: '/Scripts/_Ref/goog',
        bootstrap: '/Scripts/_Ref/bootstrap'
    },
    shim: {
        'bootstrap': {
            deps: ['jquery']
        }
    }
});

require.onError = function (err) {
    console.log('RSC JS Error: ' + err.requireType);
    if (err.requireType === 'timeout') {
        var errorMessage = 'Following modules timeout: ' + err.requireModules;
        console.log(errorMessage);
        MyNamespace.ShowErrorMessage(errorMessage);        
    }    
};

为了演示这个问题,我创建了一个示例网站,我在其中阻止了 Internet 并促使发生故障转移。 这是视频链接http://www.screencast.com/t/gcQ2I9aUdBY,我在其中展示了实际问题

【问题讨论】:

  • 这绝对不是 RequireJS 的错误。您使用的是最新版本的 RequireJS 吗?
  • 是的,我使用的是 RequireJS 2.1.14

标签: requirejs


【解决方案1】:

听起来 CDN javascripts 和 RequireJS shims 不能很好地配合使用。来自RequireJS documentation

不要在构建中混合使用 CDN 加载和 shim 配置。示例场景: 您从 CDN 加载 jQuery,但使用 shim 配置加载某些内容 就像依赖 jQuery 的 Backbone 的股票版本一样。当你这样做 构建,确保在构建文件中内联 jQuery 并且不要加载 它来自 CDN。否则,Backbone 将内联在构建的文件中 它将在加载 CDN 的 jQuery 加载之前执行。这是 因为 shim 配置只是延迟加载文件,直到 依赖项已加载,但不会对定义进行任何自动包装。 构建后,依赖项已经内联,垫片配置 不能延迟执行未定义()的代码,直到以后。 构建后定义()的模块确实可以与 CDN 加载的代码一起工作,因为 他们正确地将源代码包装在定义工厂函数中 在加载依赖项之前不执行。所以教训:垫片配置 是非模块化代码、遗留代码的权宜之计。定义() 模块更好。

更容易理解的解释见this StackOverflow question

我们似乎很幸运没有使用 RequireJS 加载 Bootstrap;相反,我们在<head> 中使用脚本标签:

<script type="text/javascript" sync src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
   // Load jQuery if CDN fails
   window.jQuery || document.write('<script src="scripts/libs/jquery.min.js">\x3C/script>')
</script>
<script type="text/javascript" sync src="//maxcdn.bootstrapcdn.com/bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript">
   // Load bootstrap if CDN fails
   window.jQuery.fn.dropdown || document.write('<script src="scripts/libs/bootstrap.min.js">\x3C/script>')
</script>
<script type="text/javascript">
   var require = {
      baseUrl: "scripts/",
      deps: ['main']
   };
</script>
<script type="text/javascript" src="scripts/libs/require/require.js"></script>

jQuery 和 Bootstrap 从 CDN 加载,带有本地后备 per Hanselman

【讨论】:

    猜你喜欢
    • 2016-06-12
    • 2011-10-27
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 1970-01-01
    相关资源
    最近更新 更多