3

我有兴趣为我网站上的所有 JavaScript 代码创建一个单一的配置对象。我找到了https://github.com/requirejs/example-multipage-shim,这是此设置的一个示例。

来自https://github.com/requirejs/example-multipage-shim(重点是我的):由于 shim 配置要求依赖项位于页面中,而不是对 page1.html 使用 data-main="js/page1",此示例内联 HTML 页面中的 require 调用。如果改为使用 data-main,则 'js/page1' 不能有任何内联依赖项,而是仍然依赖 'common' 和 'app/main1' 构建层来保存模块,因为 shim 配置位置的限制在构建上。

我不明白加粗的句子。这是否意味着“js/page1”如果存在就不能声明依赖关系?内联依赖是什么意思?内联成什么?HTML 文件还是 JavaScript 文件?

我阅读了有关 shim config 的 API 文档,但它对优化器的限制尚不清楚。

https://github.com/requirejs/example-multipage-shim/blob/master/www/page1.html

    <script src="js/lib/require.js"></script>
    <script>
        //Load common code that includes config, then load the app
        //logic for this page. Do the require calls here instead of
        //a separate file so after a build there are only 2 HTTP
        //requests instead of three.
        require(['./js/common'], function (common) {
            //js/common sets the baseUrl to be js/ so
            //can just ask for 'app/main1' here instead
            //of 'js/app/main1'
            require(['app/main1']);
        });
    </script> 

为什么以下错误?为什么“app/main1”必须与引导(数据主)代码位于单独的模块中?

    <script src="js/lib/require.js"></script>
    <script>
        require(['js/common'], function (common) {
            var underscore = require('underscore');
            // ...
        });
    </script> 
4

3 回答 3

1

我认为避免复制 shim 的唯一真正解决方案可能是结合服务器端模板和 grunt.js 之类的构建处理器。

如果您想在优化的 require.js 加载和非优化模式之间切换(例如用于开发目的),则只需要服务器端模板部分。

  1. 定义一个包含共享 shim 的 JavaScript 文件。
  2. 如果使用 grunt.js 使用节点export语法来导出您的 shim 和路径。
  3. 要求它作为你的 grunt 配置的一部分。要么编写 require.js 配置文件,要么根据 grunt 插件,你可能能够require在你的 require.js 构建中重用内存中的 'ed 配置。
  4. 作为 grunt 构建的一部分,编写后端架构使用的服务器模板文件。例如,如果您使用的是 django,请编写一个未检入存储库的部分 django 模板。如果您使用 .git,可能在 .gitignore 中包含输出路径。
  5. 在您的 index.html 或初始加载部分作为全局变量之前您的 require.js 脚本标记与 data-main 时不使用优化垫片。在您的调用集中或使用您从模板加载到 Javascriptrequirejs的数据扩展您的 requirejs.config 。

一个不太理想但更简单的解决方案可能是简单地设置一个定义执行上下文的全局变量,然后加载一个共享条目requirejs脚本,然后根据上下文在运行时使用switch上下文变量调用。require这可能更难以优化。更糟糕的是,您可能总是需要所有页面所需的一切,并使用此上下文来确定要运行什么而不是需要什么,但显然您总是在加载所有 JavaScript。这可能在浏览器扩展的上下文中起作用,尽管在处理所有不必要的 JavaScript 时仍然可能会减慢速度。

说了这么多,如果 requirejs 提供了一种方法来加载与requirejsordefine调用分开的配置,那将是很好的,只是为了避免在整个地方声明相同的 shims 的情况。

于 2013-09-11T13:19:09.310 回答
0

在单独的 javascript 文件中定义(使用定义)每个模块是一个很好的做法。否则异步加载几个模块是没有意义的,因为它们位于相同的物理位置。在大多数情况下,您只需要使用函数定义。只有在您的引导模块中,您才需要使用函数 require。

当我使用 require.js 时,我有 1 个模块 (bootstrap.js),其中包含我的 require.config 对象和初始引导。在 html 页面中,您只需要包含 1 个脚本:require.js,其中 bootstrap 作为 data-main 属性值:

HTML:

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

引导程序:

require.config = {
   baseUrl: 'js',
   paths: {
     ...
   },
   shim: {
   }
   ...
};

// initial bootstrap
require(['jquery', 'angular', 'app'], function($, angular) {
   // do bootstrap
});

模块:

define(['jquery'], function($) {
   // do sth with app
});

编辑:有点误解了这个问题。

使用 data-main 属性时不能在 html 页面中使用内联依赖项的原因是它可能无法加载它们。哪个代码块将首先执行?数据主引导 js 或内联代码?如果您的引导 js 文件将首先加载并将 设置baseUrl'js',则应使用内联代码require('common')而不是require('js/common'). 但如果内联代码首先加载,它必须是require('js/common').

在另一个 require 块内的原因require('app/main1')是相同的:模块 'common' 会将 baseUrl 更改为'js'. 'app/main'也可能需要来自'common' 的一些 shim 配置。这是确保首先加载公共模块(带有 shim 配置)的唯一方法。

于 2012-12-29T17:48:55.833 回答
0

当您使用shim配置时,为您希望异步加载的每个 shim添加匹配的路径配置属性:

requirejs.config({
    paths: {
        backbone: 'lib/backbone',
        jquery: 'lib/jquery',
        underscore: 'lib/underscore'
    },
    shim: {
        backbone: {
            deps: ['jquery', 'underscore'],
            exports: 'Backbone'
        },
        underscore: {
            exports: '_'
        },
        jquery: {
            exports: '$'
        }
    }
});

define()然后,shim 模块可以像任何其他真实模块一样用作依赖项。(至少这是我的经验!)

于 2012-12-29T23:09:32.950 回答