【问题标题】:How to require one file, but load one or more with it如何要求一个文件,但加载一个或多个文件
【发布时间】:2014-02-27 13:01:01
【问题描述】:

我刚刚开始使用 Require.js。我有基本的工作。

这是我要解决的问题:我正在使用 KnockoutJs 和 Knockout.validation。我总是一起使用这些文件。所以我想做一些我只需要引用 knockout 的事情,它将包括 knockout.validation。

这个:(加载敲除和敲除.validation)

define(["knockout"],
    function (ko) {     
        return {
            name: ko.observable();
        };
    }
);

而不是这个:

define(["knockout", "kovalidation"],
    function (ko) {     
        return {
            name: ko.observable();
        };
    }
);

我需要对 ko 的引用,我只需要加载其他的。

更新:

根据下面的答案,我正在尝试捆绑配置选项。不幸的是,我无法让它工作。

我的理解是配置应该是这样的:

<script>
    var require = {
        baseUrl: "/Scripts",
        bundles: {
            'knockout-3.0.0': ['knockout.validation']
        }
    };
</script>
<script src="~/Scripts/require.js" data-main="views/home"></script>

然后在我的 home.js 中:

require(["knockout-3.0.0"], function (ko) {
   ...
});

在 home.js 中,我希望看到 knockout 和 knockout.validation 都已加载,但仅加载了 knockout。

更新:

似乎配置中的 bundle 选项应该可以满足我的需要,但至少在这一点上,根据我所掌握的信息,这不是正确的解决方案。 @daedalus28 提供了一些很好的信息和一个很好的例子,帮助我提出了一个可以接受的解决方案。我已经接受了这个答案,如果有更好的答案很长,请投票,这样我们都会知道它更好。

【问题讨论】:

    标签: knockout.js requirejs knockout-validation


    【解决方案1】:

    我经常有一个LibraryPlugins 模块,我会在我最初的require 调用中加载它。在那个模块中,我加载了所有我想要在任何地方都可用的插件——比如淘汰赛绑定、下划线混合、jquery 插件等。由于这是我的第一个 require 调用之一,我知道它添加的扩展通常在我的整个应用程序中都可用

    有时我会采用更模块化的方法,并为每个库添加一个额外的模块,该模块返回它正在运行的库(即一个用于带有返回 ko 的自定义绑定的淘汰赛和一个用于带有返回修改下划线的自定义 mixins 的下划线) .这种方法最终看起来很像 Louis 的答案,但没有额外的 map:* 配置。一些模块将自己暴露为一个命名模块,这使得使用它有点困难——这就是你在路易斯的解决方案中使用 map:* 别名的时候。对于我不使用大量不同库的项目,我倾向于只使用一个 LibraryPlugins 模块,因为当依赖项数量较少时更容易管理。

    这是jsfiddle,我展示了这两种方法。

    为方便起见,我还将代码粘贴在这里:

    require.config({
        paths: {
            'knockout':'//cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min',
            'knockout.validation': '//cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.min',
            'underscore.core': 'http://underscorejs.org/underscore-min',
            'underscore.string': 'http://epeli.github.com/underscore.string/lib/underscore.string'
        },
        shim: {
            'underscore.core': {exports:'_'}
        }
    });
    
    // Approach 1: One module to load everything in advance
    define('LibraryPlugins', ['knockout', 'knockout.validation'], function(ko){ });
    
    // Approach 2: One module for each library
    define('underscore', ['underscore.core', 'underscore.string'], function (_, _string) {
        _.mixin(_string.exports());
        return _;
    });
    
    require(['knockout', 'underscore', 'LibraryPlugins'], function(ko, _) {
        console.log(ko.validation);
        console.log(_.humanize);
    });
    

    【讨论】:

    • 是“_.mixin(_string.exports());”具体到下划线?如果是常用功能,您会给出一个简短的解释或提供一个链接吗?
    • _.mixin(_string.exports()) 特定于 underscore.string 库 (github.com/epeli/underscore.string)。它将库的字符串操作函数添加到_ 对象。重点是演示如何为任何库执行任意插件/mixin 的操作,所以我想要一个除了淘汰赛之外的示例来证明这个想法对于一般的 requirejs 应用程序来说是有用的模式。对于特定于 ko 的示例,您可以很容易地要求剔除,将绑定添加到 ko.bindingHandlers,然后返回 ko 对象。您的应用程序的其余部分不需要知道其中的区别。
    • 附带说明 - 对于像 ko.validation 这样修改核心库对象本身的任何库(在本例中为 ko),您不需要做任何事情,但需要在敲除和 ko.validation然后返回 ko。如果您的大多数库插件/mixin 都遵循该模式并注册自己,那么您可能最好使用方法 1,因为它更简单一些,涉及的代码更少。
    • 我实际上将方法 1 用于一个库,将方法 2 用于另一个库。似乎这应该是 Require 配置中内置的东西。在此之前,此解决方案对我有用。
    • 我今天遇到的与此相关的链接:github.com/Knockout-Contrib/Knockout-Validation/issues/259
    【解决方案2】:

    你查看过bundle property of require.config吗?

    在 RequireJS 2.1.10 中引入:允许将多个模块 ID 指向 包含一组模块的模块 ID。

    【讨论】:

    • 从文档来看,这似乎是正确的方法,不幸的是我无法让它工作。我已经用我尝试过的方法更新了问题。
    • 如果我理解正确,bundles 配置用于包含多个命名模块声明的脚本文件(例如先前构建的输出),因此您可以在其他地方直接引用这些模块。跨度>
    • 我认为您真正要寻找的是类似于 shim:deps 配置,但它适用于与 AMD 兼容的模块 - 文档 (requirejs.org/docs/api.html#config-shim) 说“仅使用其他 'shim ' 模块作为填充脚本的依赖项,或没有依赖项并在创建全局后调用 define() 的 AMD 库"
    • @max,这似乎是我想要的,但它太新了,我找不到任何工作示例。如果你有,请分享...
    【解决方案3】:

    您可以使用noConflict 调整用于加载jQuery 的方法。我正在从that method 的文档中改编以下内容:

    require.config({
        // Add this map config in addition to any baseUrl or
        // paths config you may already have in the project.
       map: {
          // '*' means all modules will get 'knockout-private'
          // for their 'knockout' dependency.
          '*': { 'knockout': 'knockout-private' },
    
          // 'knockout-private' wants the real knockout module
          // though. If this line was not here, there would
          // be an unresolvable cyclic dependency.
         'knockout-private': { 'knockout': 'knockout' }
       }
    });
    

    knockout-private 模块是这样的:

    define(['knockout', 'kovalidation'], function (ko) {
        return ko;
    });
    

    您可以向knockout-private 添加任意数量的其他模块。

    【讨论】:

      猜你喜欢
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多