How to mixin Underscore plugins in RequireJS?

后端 未结 3 687
自闭症患者
自闭症患者 2020-12-28 09:28

What is the right way to execute code on Underscore when it gets loaded? I am trying to execute the below code to extend the _ exported namespace automatically when modules

相关标签:
3条回答
  • 2020-12-28 10:18

    Do you require underscorestring somewhere? Because if it isn't required, it won't be loaded. I managed to get it working with almost exactly the same code you posted:

    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 讨论(0)
  • 2020-12-28 10:22

    Battling with this for hours before i understand what i was doing wrong

    This is what i did wrong

    You should not rename the file underscore.string in main.js

    even though in my library i did rename the file in paths i name it back to 'underscore.string'

    This is how your main.js should look like

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

    You could then either add it as dependency with in your shim like i did for my mixin file

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

    Or just define it in your different pages like

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

    it just work now you can access it through _.str or _.string

    This is why you should do it this way and not try to name it something else

    on line 663 of underscore.string.js

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

    Which means that it will only register it with AMD require JS if you are defining 'underscore.string'

    For Mix in you could just with define

     /*global define */
    define([     
        'underscore',
        'underscore.string'
    ], function ( ) {   
      _.mixin(_.str.exports());
    
    0 讨论(0)
  • 2020-12-28 10:25

    I don't know if it's the correct way, but I got it working by inverting things so that underscore depends on underscore.string. Also, this way you don't have to require 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'
      }
    });
    

    .

    Update: 3/14/2014

    Underscore.js v1.6.0 brought back AMD compatibility and init() has been removed from RequireJS, so some refactoring is in order. To continue getting Underscore preloaded with Underscore.string I made a mixer module to pull them together.

    New Require.js config

    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'
        },
      }
    });
    

    underscore.mixed

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

    The final step is to replace all instances of 'underscore' with 'underscore.mixed' in module definitions. I attempted moving Underscore into a file named underscore.base.js and making the regular underscore the mixer (like the Backbone setup) to avoid this step. Underscore, being a named module, disagreed with the plan.

    0 讨论(0)
提交回复
热议问题