RequireJS在加载所需模块之前不运行数据主脚本

Aar*_*ron 2 requirejs

我的项目包括以下文件:

./index.html
./js/main.js
./js/vendor/require.js
./js/viewmodel/vm.js
Run Code Online (Sandbox Code Playgroud)

index.html具有以下相关片段:

<script data-main="js/main.js" src="js/vendor/require.js"></script>
<script type="text/javascript">
    require(['viewmodel/vm', 'ko'], 
        function(viewmodel, ko) {
            ko.applyBindings(viewmodel);
        }
    );
</script>
Run Code Online (Sandbox Code Playgroud)

js/main.js文件如下:

var root = this;
define('jquery', ['http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.js'], function () { return root.$; });
define('ko', ['http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js'], function (ko) { return ko; });
Run Code Online (Sandbox Code Playgroud)

js/viewmodel/vm.js文件...

define(['jquery', 'ko'], 
    function($, ko) {
        return {
            subject: 'world',
            greeting: 'hello'
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

当您打开浏览器到index.html时,浏览器会尝试加载一个名为js/ko.js而不是使用中定义的模块的文件main.js.似乎data-main属性指向的js文件不能保证在依赖项解析之前运行.这对我来说似乎不正确,因为data-main js文件的一个目的是定义require配置(即path,shim等).我使用的是必需的v2.1.2.

如果我将我的main.js文件的内容复制到脚本块中,这完全正常index.html.通过"完全正常"我的意思是它解决了ko作为一个模块并找到适当的CDN链接来解析ko而不是尝试下载./js/ko.js.

neo*_*art 12

要使用该data-main属性来配置整个应用程序,必须将它作为所有代码的单一入口点.

您的第二个脚本块通过提供第二个入口点来破坏此要求.由于这些入口点将彼此独立地(并且异步地)解决,因此您不能依赖一个入口点来影响另一个入口点.

要解决它,请以一种为应用程序提供单一入口点的方式重构代码,并通过此入口点进行配置.


Ste*_*fan 7

那是因为requirejs设置了异步.脚本上的属性.

脚本元素上的布尔异步属性允许外部JavaScript文件在可用时运行,而不会首先延迟页面加载.

这意味着两个脚本都是并行加载和评估的,因此这两个脚本都不能从另一个脚本访问方法或函数.如果要在一个脚本中定义requirejs变量,则不能使用require js加载该脚本.

对我来说,有三种可能性可以解决这个问题:

  • 将main.js的内容添加到您的页面(如您所述)
  • 加载main.js文件而不使用requirejs作为普通脚本
  • 在加载脚本之前定义require配置(链接到requirejs文档)