Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intermittent RequireJS Load Error

I have a rather large Backbone.js project that uses RequireJS. As the project size grew ("size" here referring to the number of separate module files), intermittent errors started cropping up. Most of the time, it's an object error:

Uncaught TypeError: object is not a function

Occasionally, it complains about a module not being loaded.

These errors disappear once the project is run through the r.js optimizer. They only happen when RequireJS is loading the individual modules.

Which brings me down to my question - does RequireJS start having issues with modules loading in time when the number of modules reach a certain number?

like image 406
redhotvengeance Avatar asked Jun 09 '12 07:06

redhotvengeance


People also ask

How do you fix mismatched anonymous definition module?

To fix the problem, you must update your JavaScript define methods within RequireJS, according to following documentation: https://requirejs.org/docs/api.html#define.

What is Shim RequireJS?

shim: Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value. Here is an example. It requires RequireJS 2.1. 0+, and assumes backbone. js, underscore.

Is RequireJS synchronous?

Is RequireJS synchronous? So, RequireJS doesn't support it. From your use case it seems that you don't need synchronous RequireJS, you need to return result asynchronously. AMD pattern allows to define dependencies and load them asynchronously, but module's factory function must return result synchronously.

Why do we need RequireJS?

RequireJS is a JavaScript library and file loader which manages the dependencies between JavaScript files and in modular programming. It also helps to improve the speed and quality of the code.


3 Answers

This Issue seems to be addressed in the forthcoming require.js 2.1 release. See here:

https://github.com/jrburke/requirejs/issues/478

like image 159
Brendan O'Brien Avatar answered Oct 03 '22 02:10

Brendan O'Brien


This is definitely a bug that I have encountered a lot over the last few days. Loading one module can cause a second completely unrelated module in a different part of the app to become undefined where it worked perfectly before. I have used RequireJS a lot - this is not a script loading or circular dependency issue. At first I encountered the error most often when requiring a text file in a 2nd-tier view that gets iterated quite a few times (1800+):

domReady -calls-> new View1() -iterates-> new SubView() -depends-> text!template
         -calls-> new View2() --> undefined!

This would cause a completely unrelated module elsewhere to become undefined. I worked around it for a while by integrating the SubView functionality into the View module.

domReady -calls-> new CombinedView1() -depends-> text!template
         -calls-> new View2() --> ... all good ...

As the project has grown I have hit the wall again and really need to find a way to fix it. Including more modules causes previously defined ones to become undefined at random. Require throws no errors and neither does the browser. I'm not using CoffeeScript or anything like that either.

I have taken some time create a version of my application that has the same module and dependency structure with the dependent Views, Models and Collections stubbed out. This works perfectly fine, so I can only assume there is some kind of memory issue? However Chrome never throws any errors either.

I think my next step will be to pad out my skeleton application with some memory-consuming loops and see what happens: I will let you know how it goes.

Using Require v2.0.1, so no order plugin - dependencies and packages are all configured using the shim config directive. Non-AMD modules loaded:

  • Backbone
  • Underscore
  • jQuery
  • Mustache
  • Leaflet
  • Bootstrap

P.S. Apologies if this is not in the right place. I thought it would be better as a comment but I honestly can't see the comment button anywhere.

Update: This dependency structure breaks consistently:

Main
  - View 1
      - text!...
      - View 2
         - text!...

Substituting the text with empty strings works fine every time:

Main
  - View 1
      - View 2

So why does waiting for the text to load cause View 1 to become undefined when it is explicitly set as a dependency in the Main module? Surely Main should not be called until everything it is dependent on is loaded?

like image 43
rthrfrd Avatar answered Oct 03 '22 02:10

rthrfrd


I've been fighting with the same issue the last days and this is what I found out:

Apparently, a nested dependency structure requiring templates via the text.js plugin can cause a race condition that lets the top level module not be ready when requirejs thinks it is. I only ran into this problem when I had several nested module dependency structures of this type:

Router
  -> View1
    -> text!.../view1.html
    -> View2
      -> text!.../view2.html
  -> View3
    -> text!.../view3.html
    -> View4
      -> text!.../view4.html
  -> View5
    -> text!.../view5.html
    -> View6
      -> text!.../view6.html
  -> View7
    -> text!.../view7.html
    -> View8
      -> text!.../view8.html

Having this structure, I got TypeErrors like 'View1 is not a constructor' when the router tries to instantiate the views.

Also requiring the templates of the nested views in the top level views solved the problem for me:

Router
  -> View1
    -> text!.../view1.html
    -> text!.../view2.html
    -> View2
      -> text!.../view2.html
  -> View3
    -> text!.../view3.html
    -> text!.../view4.html
    -> View4
      -> text!.../view4.html
  -> View5
    -> text!.../view5.html
    -> text!.../view6.html
    -> View6
      -> text!.../view6.html
  -> View7
    -> text!.../view7.html
    -> text!.../view8.html
    -> View8
      -> text!.../view8.html

I don't really know how require.js works, but this looks to me like those nested text! calls aren't regarded when some 'ready' flag for the parent module is set.

like image 39
Steve Beer Avatar answered Oct 03 '22 02:10

Steve Beer