Rails assets precompilation removes functions from global scope (TypeError: object is not a function). How to get them back?

StackOverflow https://stackoverflow.com/questions/16364749

Pergunta

I have such a js code:

function Global(params) {
    ...
}

var g = {
   onDocLoad: function() {

      // on DOM load I instantiate the Global function-constructor
      // which is above this line, so it is already in scope
      var global = new window.Global(params);
}

window.addEventListener("load", g.onDocLoad, false);

If I use this file as a static, without precompilation, everything works fine.

If I precompile it:

rake assets:precompile:all RAILS_ENV=development

and then refresh the page I get:

Uncaught TypeError: object is not a function

right exactly on the line with new window.Global(params);. It says that Global is not a function. But it cannot be true. It is a function.

I debugged that line and found that at the time when this line is reached the Global is null in global scope. There is no such a function with such a name.

My issue is similar to these questions:

Javascript "Uncaught TypeError: object is not a function" associativity question

After running rake assets precompile, getting undefined in not a function

but their solutions are not applicable in my case.

What may be the problem? Why precompitation breaks down working code?

Foi útil?

Solução

So, I've learned how to avoid it. But don't know why it happens however.

In development mode, assets are served as separate files in the order they are specified in the manifest file. This manifest:

//= require core
//= require projects
//= require tickets

would generate this HTML, three require - three separate tags:

<script src="/assets/core.js?body=1" type="text/javascript"></script>
<script src="/assets/projects.js?body=1" type="text/javascript"></script>
<script src="/assets/tickets.js?body=1" type="text/javascript"></script>

But Sprocket with concatenation is not a Sprocket without concatenation (the one as above). If you want to concatenate files you have to turn debug mode off:

config.assets.debug = false

When debug mode is off, Sprockets concatenates and runs the necessary preprocessors on all files. With debug mode turned off the manifest above would generate instead:

<script src="/assets/application.js" type="text/javascript"></script>

Three separate files now are in one.

SOLUTION:

So I tried

config.assets.debug = false
// and then
rake assets:precompile:all RAILS_ENV=development

and the error disappeared.

I think the reason is in the sequence of files. With debug = true precompilation loses right sequence of files in spite of the fact that the right sequence is denoted in my manifest (which is nothing more then a simple js file, somefile.js, that you add to your page; they just call it manifest).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top