【问题标题】:Difference Between data-main and normal script loading数据主要和普通脚本加载之间的区别
【发布时间】:2017-07-22 00:16:26
【问题描述】:

在使用 RequireJS 时,包含您的脚本与

有什么区别
<script data-main="scripts/main" src="scripts/require.js"></script>

<script src="scripts/require.js"></script>

data-main 属性在加载脚本时有何变化?我有 read through the docs on this,但我并不完全清楚不同之处。

您通常会使用数据主脚本来设置配置选项,然后加载第一个应用程序模块。注意:为您的 data-main 模块生成的脚本标签 require.js 包含 async 属性。这意味着您不能假设数据主脚本的加载和执行将在同一页面后面引用的其他脚本之前完成。

文档提到您将通常使用数据主脚本来设置配置选项并加载第一个应用程序模块 - 但您不能也通过普通的旧 script 来做到这一点标签?使用data-main 属性进行配置加载应用程序模块是否有好处?

data-main唯一不同的是异步加载吗?或者还有什么?

【问题讨论】:

  • 是的,文档不是很好,“您通常会使用 ...”,但他们没有解释原因。

标签: javascript requirejs


【解决方案1】:

data-main 是 require.js 将处理的脚本。正如文档所说,在该脚本中设置配置选项是很常见的。但是还有其他方法可以做到这一点。在许多情况下,它是最简单和最有效的地方。但不总是。

data-main 指向的脚本还将列出文件定义的代码的依赖关系。依赖关系是肉在哪里。加载第一个模块并执行最终的实际应用程序是典型的,但不是必需的。

回应评论的附录:

您需要了解一些有助于理解这种方法的概念。

首先是没有一个(或几个,甚至几个)脚本。这种类型的加载器旨在处理大量非常小的脚本。每个都有一个非常具体且通常(最好)单一的目的。调用这些脚本模块(或单元)。

任何给定的模块都可能依赖于任意数量的其他模块才能发挥作用。 AMD 模式允许在该模块的定义中列出每个模块的依赖关系。

RequireJS 会整理出谁需要什么以及按什么顺序,并且在它们所依赖的所有模块都加载并准备好之前不让脚本执行。

所以这根本不像我们长大后在页面中放置一个脚本链接(或多个链接)。这是一种非常不同的 javascript 开发方法。一旦你了解它并弄清楚如何将你的代码分解为谨慎的功能单元,它确实非常巧妙。

【讨论】:

  • 感谢您的回复,我很感激,但这与手册一样令人困惑。很明显,你已经内化了一些我没有得到的知识,因为我没有你的背景。如果 require.js 处理 data-main 以加载它与仅通过普通浏览器方式加载文件,为什么会有所不同。 asyc 正在加载它吗?或者还有更多的东西? (我在实现层面对此感兴趣,不一定只是用户程序员)
  • 查看扩展答案。希望我已经泄露了一点内化的知识。
【解决方案2】:

data-main 用于当您希望有一个单一入口点 到您的应用程序时。该单个脚本行将加载 RequireJS 以及 scripts/main.js 并启动您的应用程序。

结果

<script data-main="scripts/main" src="scripts/require.js"></script>

&lt;script async src="scripts/main.js"&gt;&lt;/script&gt;在运行时附加到文档中;这是包含您的require.config() 块并拉入您的第一个应用程序脚本的脚本。如果您没有指定 data-main,那么您只会加载 Require 而不会加载任何应用脚本,除非您明确加载配置文件和第一个模块。

如果你不告诉它加载任何东西,你认为 Require 会加载什么?


如果你使用data-main,你必须提供一个入口点加载Require(这是我一直这样做的方式,没有其他理由)而不是我是这样学习的。)阅读configuration options,看看你会如何做到这一点。

我在开发中使用this pattern

<script src="js/lib/require.js"></script>
<script src="js/config.js"></script>
<script>
  // same as data-main
  require.config({baseUrl : 'js'});
  require(['js/main']);
</script>

作为单个入口点,config.js 和随后的 require(['js/main']) 调用的内容将在引用为 data-main 的任何脚本中。


如果您使用静态优化器构建生产包,这些都不重要,因为您只需加载包。

【讨论】:

    【解决方案3】:

    data-main 只是执行应用程序初始require 调用的另一种方式。为了说明......这个:

    <script data-main="scripts/main" src="scripts/require.js"></script>
    

    等价于:

    <script src="scripts/require.js"></script>
    <script>require(["scripts/main"])</script>
    

    这两种形式都是异步的。这就是它的全部内容。关于你有多少入口点或 RequireJS 配置将位于何处的考虑与data-main 的使用完全正交。换句话说,这些注意事项在您使用 data-main 时所起的作用与它们在您使用 require(["scripts/main"]) 时所起的作用完全相同。

    您引用的文档部分只是通过提及使用data-main 加载的脚本在具有head 属性集的script 元素中创建了一个script 元素来掩盖事情,因为这是与通过 RequireJS 加载任何脚本没有什么不同。 RequireJS 加载的每个脚本都会在head 中为其创建一个script 元素,并设置async 属性。

    对于只有一个入口点的应用程序,通常使用data-main,并将RequireJS的配置放在data-main指定的模块中,但无论如何都不是必需的。例如,这是一个完全有效的用法:

    <script>
        require = {
            // RequireJS config here...
        };
    </script>
    <script data-main="scripts/main" src="scripts/require.js"></script>
    <script>
        require(["foo"], function (foo) {
            foo.something();
        });
    </script>
    

    在加载RequireJS之前,通过在全局空间中设置require给RequireJS配置。 (如果在加载RequireJS之前定义了require,它将把require的值作为它的配置。)除了通过加载scripts/main来启动应用程序之外,这段代码还加载了foo并在其上调用了一个方法: 两个入口点。

    【讨论】:

    • 谢谢@Louis——正是我想要的澄清!
    【解决方案4】:
    <script data-main="scripts/main.js" src="scripts/vendor/requirejs/require.js"></script>
    

    src 将首先加载“scripts/vendor/requirejs/require.js”。然后 data-main 属性将执行“scripts/main.js”。

    【讨论】:

      猜你喜欢
      • 2019-12-31
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      • 2019-02-10
      • 2015-01-06
      • 2015-07-26
      • 2015-07-24
      相关资源
      最近更新 更多