0

RequireJS works for me about half the time. If I refresh the page, it randomly gets load issues.

I'm adapting a small MVC project to use it, and doing something like this: How does RequireJS work with multiple pages and partial views?

I've a common main.js that does the loading from my main _layout.cshtml. And other partial views in widgets and elsewhere that use the technique described above. The example below is from my SignIn page:

<script type="text/javascript">
    require(["jquery", "kendo", "domReady!"], function ($, kendo) {        

        $("#signInForm").kendoWindow({
            draggable: false,
            width: "500px",
            modal: true,
            title: "Sign In",
            resizable: false
         });        
    }); 
</script>

It appears that sometimes Chrome loads & processes the inline script before main.js (Where the path mapping and other config is defined). Requiring "domReady" makes no difference.

How do I force this script to wait until require.js & main.js has run?

A less than ideal fallback is to return jQuery to it's global scope and use some kind of custom event. Do you have a better idea? Or is there a way built into RequireJS?

UPDATE: This is the work around I'm using for now in my _layout.cshtml

<script src="@Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"></script>
<script type="text/javascript">
    function requireIt(requirements, callback) {
        if ($(document).data("requireReady") === true) {
            require(requirements, callback);
        } else {
            $(document).bind("requireReady", null, function () {
                $(document).data("requireReady", true); 
                require(requirements, callback);
            });
        }
    }
</script> 
<script data-main="/scripts/main" src="@Url.Content("~/Scripts/require.js")" type="text/javascript"></script>

jQuery returns to being a global fixture and my partial views with their inline scripts use this requireIt wrapper. And main.js triggers requireReady.

Community
  • 1
  • 1
Aaron
  • 579
  • 1
  • 4
  • 12
  • 2
    Simply get rid of inline scripts. – Alexander Beletsky Aug 09 '12 at 07:27
  • I also recently started a new web application with require.js. I like using it but I've noticed a similar behaviour, where scripts are something just not loaded at all. Haven't figured it out yet. Try not to use inline scripts but use data-main as noted on the require.js website. – Jonas Geiregat Aug 09 '12 at 07:32
  • something like this doesn't help as, it's more or less the same: – Aaron Aug 09 '12 at 08:03
  • And adding second script element referencing require.js and using data-main appears to be ignored – Aaron Aug 09 '12 at 08:05

2 Answers2

1

Found this on the require.js website:

Ideally the scripts you load will be modules that are defined by calling define(). However, you may need to use some traditional/legacy "browser globals" scripts that do not express their dependencies via define(). For those, you can use the shim config. To properly express their dependencies.

Link to the shim config documentation

If you do not express the dependencies, you will likely get loading errors since RequireJS loads scripts asynchronously and out of order for speed.

You can read more about it at require.js documentation, point 1: Load javascript files.

I'll experiment with it tonight, since I don't have time right now. But I can image it will solve my issues, so probably yours also.

Jonas Geiregat
  • 5,214
  • 4
  • 41
  • 60
  • I had to use the Shim config to get Kendo to work and the JQuery cookie extension. But I'm using it globally. Your comment got me to check the doco again and I saw this: _"Also, you can define the config object as the global variable require **before** require.js is loaded, and have the values applied automatically. This example specifies some dependencies to load as soon as require.js defines require():"_ It also has a callback, I'll give this a go. – Aaron Aug 09 '12 at 23:48
1

Following on from Jonas's answer, and messing around for days, I found the only way to do this from _Layout.cshtml was as follows (the script tag is in the header). I've also seen the script tag in the body in various tutorials, which doesn't seem to work.

<script type="text/javascript" src="~/js/lib/require.js"></script>
        <script type="text/javascript">
            require.config({
                baseUrl: 'js/lib',
                paths: {
                    jquery: 'jquery-1.8.2',
                    kendo: 'kendo.all-2012.2.913.min',
                    underscore: 'underscore.min',
                    backbone: 'backbone.min',
                    app: '../app'
                },
                shim: {
                    underscore: {
                        exports:'_'
                    },
                    Backbone: {
                        deps: ['jquery', 'underscore'],
                        exports: "Backbone"
                    }
                }
            });            
        </script>

I cannot understand why the reference to main.js doesn't work (so I removed it from _Layout.cshtml)

<script data-main="js/main.js" src="~/js/lib/require.js" type="text/javascript"></script>

I also simplified the layout of the js folder as per the dox:

website
.....js
.....js/lib
.....js/lib/jquery-1.8.2.js
.....js/lib/underscore.js
.....etc
.....js/app
.....js/app/myscript.js
.....etc

Hope this helps

Jeremy

Jeremy Holt
  • 987
  • 1
  • 9
  • 14
  • You should only have the script tag for loading main with require and let require load everything. Just move the require.config statement to the main.js file, then you have full control over loading order. – d4kris Apr 14 '14 at 06:24