Domanda

I'd like to know how to load Underscore and Backbone using RequireJS and be able to configure Underscore before it's passed to Backbone.

I've seen this popular question on StackOverflow about this similar topic, but I haven't been able to figure out how to get Underscore to be configured for both of the following situations:

  • Underscore is required by itself
  • Underscore is loaded by Backbone

So my question is the following:

How can I configure Underscore using RequireJS when required by itself, and when required with Backbone in a module?

Here's what I've tried:

Approach that should work, but DOESN'T:

My first idea (as suggested here) was to define a requireJS module named (e.g.) rawUnderscore which returns Underscore without any configuration. Then, create a new module named underscore which requires rawUnderscore and configures it before returning its value. This causes loading problems (couldn't load backbone)

Configure Require.js modules

// When you initially setup require.js, add a new module to configure underscore
// Make it a dependency of backbone, so it'll always be loaded whenever 
// backbone is used.
require.config({
    paths: {
        'underscore': 'underscoreConfig',
        'rawUnderscore': 'underscoreOriginal'
    },
    shim: {
        underscore: {
            deps: ['rawUnderscore', 'jquery'],
            exports: '_'
        },
        backbone: {
            deps: ['underscore'],
            exports: 'Backbone'
        },
        jquery: {
            exports: 'jQuery'
        }
    }
});

underscoreConfig.js

define(['rawUnderscore'], function (_) {
    'use strict';

    _.templateSettings = 
    {
        evaluate    : /<%([\s\S]+?)%>/g,
        interpolate : /<%cleanHtml([\s\S]+?)%>/g,
        escape      : /<%[=-]([\s\S]+?)%>/g
    };
       
    return _;
});

Approach that works - Edit Underscore and remove AMD ability:

This works if I remove the AMD lines from Underscore.js (ie force Underscore to not be AMD compliant). I'd prefer not to do this as I like to keep libraries as they are, to ease future maintenance.

Configure Require.js to use the underscore patch

  require.config({
          shim: {
          underscore: {
            deps: ['underscorePatch'],
              exports: '_',
              init: function(patchIt){
                  return patchIt(this._);
              }
          }
      }
  });

underscorePatch.js

  define('underscorePatch', [], function(){
      'use strict';

      function patch(_){
          _.templateSettings = {
              evaluate    : /<%([\s\S]+?)%>/g,
              interpolate : /<%cleanHtml([\s\S]+?)%>/g,
              escape      : /<%[=-]([\s\S]+?)%>/g
          };
          return _;
      }

      return patch;
  });

Approach that works when loaded with Backbone:

This approach works, but only in the context of when Backbone being loaded as well. Not when Underscore is required by itself.

Configure Require.js modules

// When you initially setup require.js, add a new module to configure underscore
// Make it a dependency of backbone, so it'll always be loaded whenever 
// backbone is used.
require.config({
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['underscoreConfig', 'underscore', 'jquery'],
            exports: 'Backbone'
        },
        jquery: {
            exports: 'jQuery'
        }
    }
});

underscoreConfig.js

define(['underscore'], function (_) {
    'use strict';

    _.templateSettings = 
    {
       evaluate    : /<%([\s\S]+?)%>/g,
       interpolate : /<%cleanHtml([\s\S]+?)%>/g,
       escape      : /<%[=-]([\s\S]+?)%>/g
    };
       
    return _;
});
È stato utile?

Soluzione

I think your first example was on the right track. The following seems to work:

main.js

requirejs.config({
    paths: {
        'underscore': 'underscoreConfig',
        'originalUnderscore': 'underscore'
    },
    shim: {
        'originalUnderscore': {
            exports: '_'
        }
    }
});

underscoreConfig.js

define(['originalUnderscore'], function(_) {
    _.templateSettings =
    {
        evaluate    : /<%([\s\S]+?)%>/g,
        interpolate : /<%cleanHtml([\s\S]+?)%>/g,
        escape      : /<%[=-]([\s\S]+?)%>/g
    };
    return _;
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top