Frage

We've been using requirejs in our group to develop an internal UI widget library based on Backbone, Marionette, and Handlebars. We'd like to distribute this library to other groups in our organization whose applications don't use require, or any other kind of AMD-compliant module loading mechanism.

Goal

  • Use r.js to build a concated and minified JS file that includes only our library code, not dependencies like Backbone, Handlebars, etc., since the other applications are already including them.
  • Use almond so that require isn't necessary.

Based on everything I've read this seems like it should be possible, though I'm having a pretty hard time getting started with it.

Problem One

The 'empty:' designation is only working for Backbone, Marionette, and jQuery. If I re-introduce any of the lines that are currently commented out in the buildfile, I wind up getting errors. How do I go about removing dependencies from the final concated and minified file? Why are these errors occurring?

The error:

Tracing dependencies for: main
TypeError: string is not a function
In module tree:
    main
      modal
        Modal/javascript/controllers/modal.simple.controller
          Modal/javascript/views/modal.simple.views
            hbs

Error: TypeError: string is not a function
In module tree:
    main
      modal
        Modal/javascript/controllers/modal.simple.controller
          Modal/javascript/views/modal.simple.views
            hbs

My buildfile looks like this:

({
    baseUrl: '.',
    name: 'main',
    out: 'uitoolkit.js',    
    mainConfigFile: 'main.js',
    paths: {
        'jquery': 'empty:',
        'backbone': 'empty:',
        'marionette': 'empty:'
        /* ,
        'underscore': 'empty:',
        'handlebars': 'empty:',
        'hbs': 'empty:',
        'json2': 'empty:',
        'i18nprecompile': 'empty:'
        */
    }
})

and main.js looks like this:

require.config({
    locale : "en_us",

    // default plugin settings, listing here just as a reference
    hbs : {
        templateExtension : 'hbs',
        // if disableI18n is `true` it won't load locales and the i18n helper
        // won't work as well.
        disableI18n : true
    },

    paths: {
        'modal': 'Modal/javascript/widget',
        'notifications': 'Notifications/javascript/widget',
        'select': 'Select/javascript/widget',
        'wizard': 'Wizard/javascript/widget',
        'jquery': 'bower_components/jquery/jquery',
        'backbone': 'bower_components/backbone/backbone',
        'underscore': 'bower_components/underscore/underscore',
        'handlebars': 'bower_components/handlebars/handlebars',
        'marionette': 'bower_components/backbone.marionette/lib/backbone.marionette',
        'hbs' : 'bower_components/require-handlebars-plugin/hbs',
        'json2':'bower_components/json2/json2',
        'i18nprecompile' : 'bower_components/require-handlebars-plugin/hbs/i18nprecompile',
        'application': 'app'
},

shim: {
        underscore: {
            exports: '_'
        },

        backbone: {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        },

        marionette: {
            deps : ['jquery', 'underscore', 'backbone', 'handlebars'],
            exports: 'Marionette'
        },

        handlebars: {
            exports: 'Handlebars',
            init: function() {
                this.Handlebars = Handlebars;
                return this.Handlebars;
            }
        },

        json2: {
             exports: 'JSON'
        },

        application: {
            exports: 'Application'
        },
    },

    baseUrl : './'
});

require(
    [
        'application',
        'modal',
        'notifications',
        'select',
        'wizard'
    ], 

    function(Application, modal, notifications, select, wizard) {
        var uitoolkit = $.namespace('com.namespace.uitoolkit');

        uitoolkit.modal = modal;
        uitoolkit.notifications = notifications;
        uitoolkit.select = select;
        uitoolkit.wizard = wizard;

        return uitoolkit;
    }
);

Problem Two

I'm not even sure where to begin introducing almond. Is this something I would include in main.js? And will this allow what I think it will, i.e., giving us the option of distributing a library to developers who aren't using require/AMD?

Thank you very, very much in advance.

War es hilfreich?

Lösung

Wound up getting an answer on the requirejs list from a real nice feller over there.

Since I can't include jQuery, Backbone, etc. in my own build, I wound up creating a bunch of 'stub' modules that look like this:

// stubs/jquery:
define(function() {
    return window.jQuery;
}

// stubs/underscore:
define(function() {
    return window._;
}

// stubs/backbone:
define(function() {
    return window.Backbone;
}

Then I reference those in my build file. They're inlined by r.js, and I can then ship a library that uses require (well, almond) in an environment that doesn't have require handy. Plus, it's trivial to change the buildfile so it points to the real versions of the modules. So now the buildfile looks like this:

({
    baseUrl: '.',

    name: 'bower_components/almond/almond',

    include: ['main'],

    out: 'uitoolkit.js',    

    mainConfigFile: 'main.js',

    // optimize: 'none',

    wrap: true,

    paths: {
        'jquery': './js/stubs/jquery',
        'backbone': './js/stubs/backbone',
        'marionette': './js/stubs/marionette',
        'underscore': './js/stubs/underscore',
        'handlebars': './js/stubs/handlebars', 
        'json2': './js/stubs/json2'
    }
})
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top