Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Underscore.string with RequireJS

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
like image 768
Mirzhan Irkegulov Avatar asked Apr 17 '13 06:04

Mirzhan Irkegulov


4 Answers

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.

like image 52
Mirzhan Irkegulov Avatar answered Nov 05 '22 16:11

Mirzhan Irkegulov


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'

like image 27
Pascal Avatar answered Nov 05 '22 15:11

Pascal


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(_) {
    // --
});
like image 1
Alfishe Avatar answered Nov 05 '22 15:11

Alfishe


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! :)

like image 1
Playnox Avatar answered Nov 05 '22 14:11

Playnox