10

I have my bootstrap file which defines the require.js paths, and loads the app and config modules.

// Filename: bootstrap

// Require.js allows us to configure shortcut alias
// There usage will become more apparent futher along in the tutorial.
require.config({
    paths: {
        bfwd: 'com/bfwd',
        plugins: 'jquery/plugins',
        ui: 'jquery/ui',
        jquery: 'jquery/jquery.min',
        'jquery-ui': 'jquery/jquery-ui.min',
        backbone: 'core/backbone.min',
        underscore: 'core/underscore.min'
    }
});
console.log('loading bootstrap');
require([
    // Load our app module and pass it to our definition function
    'app',
    'config'
], function(App){
    // The "app" dependency is passed in as "App"
    // Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function
    console.log('initializing app');
    App.initialize();
});

app.js is loaded like it should, and it's dependencies are loaded. it's define callback is called, with all the correct dependencies passed as arguments. No error is thrown. HOWEVER, in the bootstrap's callback, App is undefined! no arguments are passed. What can be causing this? Here's my app file ( modified for space)

// Filename: app.js
define(
    'app',
    [
        'jquery',
        'underscore',
        'backbone',
        'jquery-ui',
        'bfwd/core',
        'plugins/jquery.VistaProgressBar-0.6'
    ], 
    function($, _, Backbone){
        var initialize = function()
        {
            //initialize code here
        }
        return 
        {
            initialize: initialize
        };
    }
);
LordZardeck
  • 7,953
  • 19
  • 62
  • 119
  • Can you check if more than one version of the `define` function is declared? Also, it's generally better to use anonymous defines. So maybe remove the `'app', ` code from the module. – Paul Grime Mar 20 '12 at 21:55
  • how do i check if more than one version of `define` is declared? Also, i've tried with and without the 'app' declaration – LordZardeck Mar 20 '12 at 22:57
  • Not sure to be honest! But if there are two competing define functions, then the state of the modules may be undetermined, even if they appear to be working (i.e. the 'factory' function passed to define is executed). Can you try stripping your app to the bare bones and gradually add dependencies? – Paul Grime Mar 20 '12 at 23:55
  • i've stripped it of all dependencies and it still doesn't get passed – LordZardeck Mar 20 '12 at 23:59
  • I can not generate the same error using the code in your question ... have any more information that you can provide? A page where the error can be reproduced is a good start... – Marcelo De Zen Aug 24 '12 at 17:16

5 Answers5

12

As far as I am aware you should probably just drop the 'app' string in your app.js define method.

// Filename: app.js
define([
    'jquery',
    'underscore',
    'backbone',
    'jquery-ui',
    'bfwd/core',
    'plugins/jquery.VistaProgressBar-0.6'
], function($, _, Backbone){
    ...
);
phawk
  • 1,321
  • 1
  • 13
  • 12
  • Dropping the app string would work. This pattern works for me: 'require(["app"], function(App) { App.initialize(); });' with app.js written as define(['jquery'], function($){ function initialize() {}; return { initialize: initialize }; }); – widged Aug 31 '12 at 10:14
  • When using the app string, your defined modules should return a reference to the library. Libraries like jQuery will define themselves as: 'define( "jquery", [], function () { return jQuery; } );' – widged Aug 31 '12 at 10:19
5

Ok I had the same problem, the key is the jquery path alias you define. It turns out that RequireJS has some special handling for jquery. If you use the jquery module name it will do a little bit of magic there.

Depending on what you have in jquery.min.js it may cause some problems, also the jquery plugin you have there may be a problem. Here are the relevant lines of code from the RequireJS source:

    if (fullName) {
        //If module already defined for context, or already loaded,
        //then leave. Also leave if jQuery is registering but it does
        //not match the desired version number in the config.
        if (fullName in defined || loaded[id] === true ||
            (fullName === "jquery" && config.jQuery &&
                config.jQuery !== callback().fn.jquery)) {
            return;
        }

        //Set specified/loaded here for modules that are also loaded
        //as part of a layer, where onScriptLoad is not fired
        //for those cases. Do this after the inline define and
        //dependency tracing is done.
        specified[id] = true;
        loaded[id] = true;

        //If module is jQuery set up delaying its dom ready listeners.
        if (fullName === "jquery" && callback) {
            jQueryCheck(callback());
        }
    }

For me I have it setup such that I have a file called /libs/jquery/jquery.js which returns the jquery object (just a wrapper for RequireJS). What I ended up doing was simply changing the path alias from jquery to $jquery. This helps avoid the undesired magic behavior.

In the original tutorial I read they use jQuery which also works.

Michael Yagudaev
  • 6,049
  • 3
  • 48
  • 53
3

This is a simple example that might help get you started:

I've created a very simple module:

https://gist.github.com/c556b6c759b1a41dd99d

define([], function () {
  function my_alert (msg) {
    alert(msg);
  }
  return {
    "alert": my_alert
  };
});

And used it in this fiddle, with only jQuery as an extra dependency:

http://jsfiddle.net/NjTgm/

<script src="http://requirejs.org/docs/release/1.0.7/minified/require.js"></script>
<script type="text/javascript">
  require.config({
    paths: {
        "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min",
        "app": "https://gist.github.com/raw/c556b6c759b1a41dd99d/20d0084c9e767835446b46072536103bd5aa8c6b/gistfile1.js"
    },
    waitSeconds: 40
  });
</script>

<div id="message">hello</div>

<script type="text/javascript">
  require( ["jquery", "app"],
    function ($, app) {
      alert($.fn.jquery + "\n" + $("#message").text());
      app.alert("hello from app");
    }
  );
</script>
Paul Grime
  • 14,970
  • 4
  • 36
  • 58
1

This is how I do it with requirejs and backbone:

first, define main or bootstrap file with config:

// bootstrap.js
require.config({
    paths: {
        text: 'lib/text',
        jQuery: 'lib/jquery-1.7.2.min',
        jqueryui: 'lib/jquery-ui-1.8.22.custom.min',
        Underscore: 'lib/underscore-1.3.3',
        Backbone: 'lib/backbone-0.9.2'
    },

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

        'jQuery': {
            exports: 'jQuery'
        },

        'jqueryui': {
            exports: 'jqueryui'
        },

        'Zepto': {
            exports: '$'
        },

        'Backbone': {
            deps: ['Underscore', 'Zepto'],
            exports: 'Backbone'
        }
});

define(function (require) {
    'use strict';

    var RootView = require('src/RootView');
    new RootView();
});

Then, I use this syntax to load my scripts. I find it easier than the array notation to just define my depencies via var declarations.

// rootview.js
define(function (require) {

    'use strict';

    var $ = require('Zepto'),
    Backbone = require('Backbone'),
    LoginView = require('./LoginView'),
    ApplicationView = require('./ApplicationView'),
    jQuery = require('jQuery').noConflict();



    return Backbone.View.extend({

        // append the view to the already created container
        el: $('.application-container'),

        initialize: function () {
            /* .... */
        },

        render: function () {
                        /* .... */
        }
    });
});

Hope it helps!

tmaximini
  • 8,403
  • 6
  • 47
  • 69
-1

This is a bit late, but I just had this problem. My solution can be found here: https://stackoverflow.com/questions/27644844/can-a-return-statement-be-broken-across-multiple-lines-in-javascript

I posted that question for a different reason, to ask why my fix worked in the first place. Elclanrs provided the perfect answer. To make a long story short, the undefined is probably appearing due to javascript's automatic semicolon insertion: Automatic semicolon insertion & return statements

If you try changing the position of the curly bracket from underneath to directly after the return statement, I think your problem will disappear.

// Filename: app.js
define(
.
.
.

    function($, _, Backbone){
        var initialize = function()
        {
            //initialize code here
        }
        return {
            initialize: initialize
        };
    }
);
Community
  • 1
  • 1
MingShun
  • 287
  • 3
  • 11
  • The position of the curly brackets has no affect what so ever. The existence of brackets do. – Design by Adrian Dec 09 '16 at 11:27
  • @Design by Adrian. It's disgusting downvoting me and then leaving a comment with wrong information. Before misleading future programmers, be aware of the gotchas of a language. The automatic semicolon insertion feature of javascript ends the return statement immediately instead of including the code in the curly braces on the next line. The Original Poster was getting undefined for app. This was why. I even said this in my answer, did you even try to read it? – MingShun Dec 21 '16 at 08:42