javascript RequireJS 错误地从 URL 加载脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22874664/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:56:49  来源:igfitidea点击:

RequireJS incorrectly loads scripts from URLs

javascriptrequirejs

提问by user1091733

I'm using RequireJS to load dependencies. This is how my config looks like:

我正在使用 RequireJS 加载依赖项。这是我的配置的样子:

'use strict';

require.config({
    paths: {
        jQuery: 'http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min',
        underscore: 'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min',
        backbone: 'http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min'
    }
    shim: {
        jQuery: {
            exports: '$'
        },
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: [
                'underscore',
                'jQuery'
            ],
            exports: 'Backbone'
        }
    }
});

When I run my static website, in the console there are messages like this:

当我运行我的静态网站时,在控制台中有这样的消息:

GET http://*myhost*/js/backbone.js 404 (Not Found) require.js:1896
Uncaught Error: Script error for: backbone
http://requirejs.org/docs/errors.html#scripterror require.js:166
GET http://*myhost*/js/jQuery.js 404 (Not Found) require.js:1896
Uncaught Error: Script error for: jQuery
http://requirejs.org/docs/errors.html#scripterror require.js:166
GET http://*myhost*/js/underscore.js 404 (Not Found) require.js:1896
Uncaught Error: Script error for: underscore
http://requirejs.org/docs/errors.html#scripterror require.js:166
Uncaught ReferenceError: jQuery is not defined 

As you can see, RequireJS ignores the fact that I'm providing URLs for CND and tries to look for modules locally.

如您所见,RequireJS 忽略了我为 CND 提供 URL 并尝试在本地查找模块的事实。

However, sometimes RequireJS works fine - it loads modules from URLs. Some kind of lottery over there. Worth to mention that it happens only on my remote development server - that is when I access my website over web. When I run my website locally, RequireJS always loads modules from CDN perfectly fine. Weird, any ideas why this is happening?

然而,有时 RequireJS 工作正常 - 它从 URL 加载模块。那里有某种彩票。值得一提的是,它只发生在我的远程开发服务器上——也就是我通过网络访问我的网站时。当我在本地运行我的网站时,RequireJS 总是完美地从 CDN 加载模块。奇怪,任何想法为什么会发生这种情况?

UPDATE

更新

This is how I start my application:

这是我开始我的应用程序的方式:

<script type="text/javascript" data-main="js/main" src="js/require.js"></script>

main.js (where config is loaded)

main.js(加载配置的地方)

define(['config', 'router'], function(Config, Router) {
    var router = new Router();
    Backbone.history.start();
});

回答by Louis

Your main module starts with this:

你的主模块从这个开始:

define(['config', 'router'], function(Config, Router) {

This tells RequireJS to load configand routerbut does not specify the orderin which they should be loaded. If routerdepends on modules that use the CDNs you've listed in your configuration and assuming that configis not among router's dependencies, then you would indeed get intermittent loading failures. When confighappens to load before routereverything is fine. If configloads after router, then all hell breaks loose. The simplest way to fix this problem would be to move your configuration into your main.jsfile. You could have the require.configcall before the definecall, and you'd obviously no longer list configamong the dependencies.

这告诉 RequireJS 加载configrouter但没有指定它们应该加载的顺序。如果router依赖于使用您在配置中列出的 CDN 的模块,并假设它config不在router的依赖项中,那么您确实会遇到间歇性加载失败。当config发生在router一切正常之前加载。如果config在 之后加载router,那么所有的地狱都会崩溃。解决此问题的最简单方法是将您的配置移动到您的main.js文件中。您可以在require.config调用之前进行define调用,并且显然不再config在依赖项中列出。

If moving the call to require.configdoes not work for you because (for instance) you need to share configamong multiple pages then this would also do the trick:

如果将调用移动到require.config对您不起作用,因为(例如)您需要config在多个页面之间共享,那么这也可以解决问题:

define(['config'], function () {
    require(['router'], function(Router) {
        var router = new Router();
        Backbone.history.start();
    });
});

The code above ensures that configis loaded before anything else.

上面的代码确保config在其他任何事情之前加载。

Your configuration is also wrong in the following ways:

你的配置也有以下几个方面的错误:

  1. You must always refer to jQuery as jquerybecause jQuery (for better or for worse) hardcodes its module name as jqueryall lower caps. I've run tests with using jQueryinstead of jqueryand got erratic results.

  2. jQuery 2.0.3 does not need a shim. Having a shim for it only confuses RequireJS.

  1. 您必须始终将 jQuery 称为jquery因为 jQuery(无论好坏)将其模块名称硬编码为jquery所有小写​​字母。我已经使用 usingjQuery而不是运行测试jquery并得到了不稳定的结果。

  2. jQuery 2.0.3 不需要垫片。为它添加垫片只会混淆 RequireJS。