Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing AMD in JavaScript using RequireJS

I am totally new to RequireJS so I'm still trying to find my way around it. I had a project that was working perfectly fine, then I decided to use RequireJS so I messed it up :)

With that out of the way, I have a few questions about RequireJS and how it figures out everything. I have the file hierarchy inside the scripts folder:

enter image description here

I have the following line inside my _Layout.cshtml file:

<script data-main="@Url.Content("~/Scripts/bootstrap.js")" src="@Url.Content("~/Scripts/require-2.0.6.js")" type="text/javascript"></script>

And here's my bootstrap.js file:

require.config({
    shim: {
        'jQuery': {
            exports: 'jQuery'
        },
        'Knockout': {
            exports: 'ko'
        },
        'Sammy': {
            exports: 'Sammy'
        },
        'MD': {
            exports: 'MD'
        }
    },
    paths: {
        'jQuery': 'jquery-1.8.1.min.js',
        'Knockout': 'knockout-2.1.0.js',
        'Sammy': 'sammy/sammy.js',
        'MD': 'metro/md.core.js',
        'pubsub': 'utils/jquery.pubsub.js',
        'waitHandle': 'utils/bsynchro.jquery.utils.js',
        'viewModelBase': 'app/metro.core.js',
        'bindingHandlers': 'app/bindingHandlers.js',
        'groupingViewModel': 'app/grouping-page.js',
        'pagingViewModel': 'app/paging-page.js'
    }
});

require(['viewModelBase', 'bindingHandlers', 'Knockout', 'jQuery', 'waitHandle', 'MD'], function (ViewModelBase, BindingHandlers, ko, $, waitHandle, MD) {
    BindingHandlers.init();

    $(window).resize(function () {
        waitHandle.waitForFinalEvent(function () {
            MD.UI.recalculateAll();
        }, 500, "WINDOW_RESIZING");
    });

    var viewModelBase = Object.create(ViewModelBase);
    ko.applyBindings(viewModelBase);
    viewModelBase.initialize();
});

    require(['viewModelBase', 'bindingHandlers', 'Knockout'], function (ViewModelBase, BindingHandlers, ko) {
        BindingHandlers.init();

        var viewModelBase = new ViewModelBase();
        ko.applyBindings(viewModelBase);
        viewModelBase.initialize();
    });

Then I implemented my modules by using the define function. An example is the pubsub module:

define(['jQuery'], function ($) {
    var 
        publish = function(eventName) {
            //implementation
        },
        subscribe = function(eventName, fn) {
            //implementation
        }
    return {
        publish: publish,
        subscribe: subscribe
    }
});

I've basically done the same thing to all of my javascript files. Note that the actual file containing the pubsub module is jquery.pubsub.js inside the /Scripts/utils folder. This is also the case with other modules as well.

UPDATE:

Ok I updated my bootstrap file now that I think I understand what a shim is and why I should be using it. But it's still not working for me, although I've also declared all the paths that I think would've caused me trouble in getting them right. The thing is that it's not even going into my require callback inside the bootstrap file, so I guess I still have a problem in the way I'm configuring or defining my modules?

like image 884
Kassem Avatar asked Nov 13 '22 23:11

Kassem


1 Answers

Well, for one, if you are going to use a non-amd library, say jQuery, with require and have the jQuery function passed to the callback, you need to specify a shim with exports in your require config, like so:

require.config({
    shim: {
        jQuery: {
            exports: '$'
        }
    },
    paths: {
        jQuery: 'jquery-1.8.1.min.js',
    }
});

Other than that I'm not sure I understand what your issue is exactly.

like image 88
Ryan Lynch Avatar answered Nov 15 '22 11:11

Ryan Lynch