5

I'm trying to use both Underscore and Underscore.string with RequireJS.

Contents of main.js:

require.config({
    paths: {
        'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min',
        'underscore-string': '//cdnjs.cloudflare.com/ajax/libs/underscore.string/2.3.0/underscore.string.min',
    },
    shim: {
        'underscore': {
            exports: '_'
        },
        'underscore-string': {
            deps: ['underscore'],
            exports: '_s'
        },
    }
});

var modules = ['underscore-string'];

require(modules, function() {
    // --
});

Browser sees the _, but doesn't see the _s - it is undefined.

Ideally i want to have Underscore under _ and Underscore.string under _.str, but _ and _s are fine too. How can i do that?

Versions: RequireJS 2.1.5, Underscore 1.4.4, Underscore.string 2.3.0

Note: Thanks to @jgillich make sure, that paths have two slashes (//cdnjs.cloudfare.com/...), otherwise the browser would think that URL is relative to the server, and Firebug will throw:

Error: Script error
http://requirejs.org/docs/errors.html#scripterror
2
  • I think the issue is that requirejs assumes the paths are relative to your server directory. 'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min', 'underscore-string': '//cdnjs.cloudflare.com/ajax/libs/underscore.string/2.3.0/underscore.string.min' Commented Apr 17, 2013 at 6:30
  • possible duplicate of How to mixin Underscore plugins in RequireJS? Commented Oct 25, 2014 at 12:53

4 Answers 4

10

I found the error. For some reason RequireJS doesn't work with version of Underscore.string from cdnjs.com, so i replaced it with Github version. I guess it has something to do with the commit 9df4736.

Currently my code looks like the following:

require.config({
    paths: {
        'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min',
        'underscore-string': '//raw.github.com/epeli/underscore.string/master/dist/underscore.string.min',
    },
    shim: {
        'underscore': {
            exports: '_'
        },
        'underscore-string': {
            deps: ['underscore'],
        },
    }
});

var modules = ['underscore', 'underscore-string'];

require(modules, function(_) {
    // --
});

Underscore.string resides in _.str.

Edit: As of 16 July 2013 the CDNJS version is updated with the upstream.

Sign up to request clarification or add additional context in comments.

Comments

2

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'

Comments

1

works for my ONLY if I use exact "underscore.string" module name in shim. Seems related to hardcoded name in underscore.string itself

Exempt from underscore.string source code (this branch is executed when require used):

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

So for me the only working configuration is:

require.config({
    paths: {
        'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min',
        'underscore.string': '//raw.github.com/epeli/underscore.string/master/dist/underscore.string.min',
    },
    shim: {
        'underscore': {
            exports: '_'
        },
        'underscore.string': {
            deps: ['underscore'],
        },
    }
});

var modules = ['underscore', 'underscore.string'];

require(modules, function(_) {
    // --
});

Comments

1

Here's a working code using Requirejs "order" plugin, also includes Jquery, and everything loads without any conflict:

requirejs.config({
    baseUrl: "assets",
    paths: {
        order: '//requirejs.org/docs/release/1.0.5/minified/order',
        jquery: 'http://code.jquery.com/jquery-2.1.0.min',
        underscore: '//underscorejs.org/underscore-min',
        underscorestring: '//raw.githubusercontent.com/epeli/underscore.string/master/dist/underscore.string.min',
        underscoremixed: 'js/underscore.mixed' // Create separate file 
    },
    shim: {
        underscore: { exports: '_' },
        underscorestring: { deps: ['underscore'] }
    }
});
require(['order!jquery','order!underscoremixed'], function($,_) {
    // test
    console.log( _.capitalize('capitalized text') );
});

Inside js/underscore.mixed.js put the following...

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

Cheers! :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.