Reputation: 88
I have a problem with scopes (global variables/namespaces) that i just can't fix. The thing is that I have some legacy code on a project in which i added new functionalities using Require.js. This legacy code is loaded using standard <script>
tags, but the new code is loaded with Require. The problem occurs when I add the Ractive.js in Require as AMD. Because legacy code loads Prototype.js, it has some clashes with Ractive.js.
The main problem is when observing the array for changes. Specifically, when i observe the array with pattern observer.
ractive.observe('dataArray.*', function(newValue, oldValue, keypath) {
alert(' status changed from ' + oldValue + ' to ' + newValue);
}, {debug: true, init: false});
If i don't add observer to array, everything works, but if I add it, i get an error undefined is not a function
in prototype.js (this doesn't happen when I remove prototype.js from globals).
Another this is that it actually works when i don't use the pattern observer.
So, my question is, is there a way to configure Require.js to use only the scripts that are loaded as AMD-s? Or, in other words, restrict the scope of AMD scripts to only each other so it ignores global scripts?
Thanks in advance.
Upvotes: 0
Views: 221
Reputation: 29615
I was able to create a similar error by adding an old version of Prototype.js to a page. I suspected it was because Prototype.js adds non-standard methods to Array.prototype
(among other things). This is generally regarded as a Bad Thing, because it makes these sorts of clashes fairly likely in large codebases.
Specifically, the error was that Ractive calls Array.prototype.map
on a string when dealing with pattern observers. The map
function is standard in ES5, but not in older browsers (such as IE8), so Prototype adds a polyfill - but in older versions of Prototype it's a broken polyfill. That broken polyfill throws an error when you call it with a string instead of an error (because it uses its own this.each()
method) - an unusual but perfectly acceptable operation in ES5.
Fortunately, it looks as though more recent versions of Prototype aren't broken in the same way. I was able to reproduce the error with 1.6.1 (the version on their docs site, which is from 2009), but not with the latest 1.7.2 version.
So you have two possible options:
map()
method. You could use this polyfill from MDN (make sure you omit the if (!Array.prototype.map){...}
check).Of these, the second is probably least likely to break code that depends on Prototype!
Upvotes: 1