Intermittent RequireJS Load Error

2019-03-11 03:03发布

问题:

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?

回答1:

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

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



回答2:

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?



回答3:

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.



回答4:

Verify that you have

  • shim configured http://requirejs.org/docs/api.html#config-shim
  • 'waitSeconds' property and
  • http://requirejs.org/docs/errors.html#timeout

Hope this helps