如何在RequireJS中混合使用Underscore插件?

11

当Underscore被加载时,执行代码的正确方法是什么?我正在尝试执行以下代码,以便在模块需要时自动扩展导出的_命名空间:

_.mixin(_.str.exports());

文档有点模糊,但我认为我把它放在了shim init部分?我尝试了下面的代码,但是我甚至不能在init中打断点:

require.config({
    paths: {
        jquery: 'libs/jquery/jquery.min',
        underscore: 'libs/underscore/lodash.min',
        underscorestring: 'libs/underscore/underscore.string.min'
    },

    shim: {
        underscore: {
            exports: '_'
        }
        underscorestring: {
            deps: ['underscore'],
            init: function (_) {
                //Mixin plugin to namespace
                _.mixin(_.str.exports());

                return _;
            }
        }
    }
});

当我尝试这样做并使用underscorestring时,我遇到了以下错误:

Uncaught TypeError: Object function s(e){return new o(e)} has no method 'startsWith'

文档:

3个回答

19

我不知道这是否是正确的方法,但通过将下划线取决于underscore.string的方式反转,我使它工作了。此外,这样您就无需要求 underscore.string。

require.config({
  shim: {
    'backbone': {
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
    },
    'underscore': {
      deps: ['underscore.string'],
      exports: '_',
      init: function(UnderscoreString) {
        _.mixin(UnderscoreString);
      }
    }
  },
  paths: {
    'backbone'          : 'lib/backbone',
    'jquery'            : 'lib/jquery/jquery',
    'text'              : 'lib/require/text',
    'underscore'        : 'lib/underscore',
    'underscore.string' : 'lib/underscore.string'
  }
});

更新:2014年3月14日

Underscore.js v1.6.0已经恢复了AMD兼容性,并且从RequireJS中删除了init(),因此需要进行一些重构。为了继续使用预加载的Underscore和Underscore.string,我创建了一个混合模块来将它们组合在一起。

新的Require.js配置

requirejs.config({
  paths: {
    'backbone'            : '../lib/backbone/backbone',
    'backbone.base'       : '../lib/backbone/backbone.base',
    'backbone.extensions' : '../lib/backbone/backbone.extensions',
    'jquery'              : '../lib/jquery/jquery',
    'text'                : '../lib/require/text',
    'underscore'          : '../lib/underscore/underscore',
    'underscore.mixed'    : '../lib/underscore/underscore.mixed',
    'underscore.string'   : '../lib/underscore/underscore.string'
  },
  shim: {
    'backbone.base': {
      deps: ['underscore.mixed', 'jquery'],
      exports: 'Backbone'
    },
  }
});

下划线.混合

define([
  'underscore',
  'underscore.string'
], function(_, _s) {
  _.mixin(_s.exports());
  return _;
});

最后一步是将模块定义中所有'underscore'实例替换为'underscore.mixed'。我尝试将Underscore移动到名为underscore.base.js的文件中,并使常规的underscore成为混合器(类似于Backbone设置)以避免此步骤。作为一个具有命名的模块,Underscore不同意这个计划。


最新的RequireJS中似乎“init”在shim中不起作用。请查看此技术代替:http://blog.falafel.com/Blogs/basem-emara/2014/02/17/the-lo-dash-on-underscore.js-and-strings - TruMan1
你可以使用map属性将'underscore'有效地别名为你的'underscore.mixed'。请参见http://requirejs.org/docs/jquery.html#noconflictmap - Courtney Christensen

3

你是否需要在某个地方使用下划线字符串?因为如果没有必要,它将不会被加载。我使用了几乎与你发布的代码完全相同的代码,成功让它工作起来。

require.config({
    paths: {
        underscore: [
            '//raw.github.com/documentcloud/underscore/master/underscore-min'
        ,   'lib/underscore'
        ]
    ,   underscorestring: 'https://raw.github.com/epeli/underscore.string/master/dist/underscore.string.min'
    }
,   shim: {
        underscore: { exports: '_' },
        underscorestring: {
            deps: ['underscore'],
            init: function(_) { 
                _.mixin(_.str.exports());
                return _; // guess, this is not needed.
            }
        }
    }
,   exclude: ['underscore']
});

require(['underscore', 'underscorestring'], function(_) {
    console.log( _.chars("i'm a happy string.") );
});

0

在我理解自己错在哪里之前,我已经与这个问题斗争了数小时

这就是我的错误所在

你不应该在main.js中将文件underscore.string重命名

即使在我的库中我已经将文件重命名为其他名称,在路径中也要将其改回“underscore.string”

以下是您的main.js应该如何看起来

require.config({
paths: {
    underscore: 'lib/underscore', 
    'underscore.string' : 'lib/_string' ,
},
shim: { 
    underscore: {
        exports: '_', 
        deps: [ 'jquery', 'jqueryui' ]
    }, 
    'underscore.string': { 
        deps: [ 'underscore' ]
    },
} 
....

然后你可以像我在混入文件中所做的那样,在你的shim中将它添加为依赖项

shim: { 
    mixin : {
        deps: [ 'jquery',  'underscore', 'underscore.string' , 'bootstrap'  ] 
    },  

或者只需在不同的页面中定义它,如下:

/*global define */
define([    
    'underscore.string'
], function ( ) {   

现在它可以通过 _.str 或 _.string 访问,它只是工作了。

这就是为什么你应该这样做,而不是尝试给它取其他名字。

在 underscore.string.js 的第 663 行。

  // Register as a named module with AMD.
  if (typeof define === 'function' && define.amd)
    define('underscore.string', [], function(){ return _s; });

这意味着只有在定义“underscore.string”时,它才会在AMD require JS中注册它。
对于Mix in,您可以使用define进行简单定义。
 /*global define */
define([     
    'underscore',
    'underscore.string'
], function ( ) {   
  _.mixin(_.str.exports());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接