I'd like to be able to detect all the frameworks/libraries used by a page, to help understand when content is dynamically-generated etc.
I downloaded and unpacked the source for two Chrome extensions, Library Detector and Appspector. It looks like they simply call window.FUNCTION_NAME_HERE
, for example:
'Backbone.js': function () {
return window.Backbone && typeof(window.Backbone.sync) === 'function';
},
'Underscore.js': function () {
return window._ && typeof(window._.identity) === 'function' &&
window._.identity('abc') === 'abc';
},
'Spine': function () {
return window.Spine;
},
'Angular': function () {
return window.angular;
},
'Ning': function () {
return window.ning;
},
'Zepto': function () {
return window.Zepto;
}
etc.
I have a few questions:
- What are the identifiers for each framework (e.g. "Spine", "angular") called? Is there any way to retrieve this information via AJAX or otherwise, so I don't have to manually enter them?
- I don't really understand what
window.angular
means, besides that it returns either the angular object or None. I know that AngularJS has loaded if the angular function is accessible through the window object, but I'm not really sure what it even means to be a member function of the window. - Why is the procedure for Backbone and Underscore different than all the others? How do you know which one to use?
- I tried running both extensions on the Uber homepage, which uses React, and neither of them detected React. When I tried to
console.log(window)
, there wasn't a React object listed either. Why is this, and how can I still detect the framework in these cases?
I'd like to be able to detect all the frameworks/libraries used by a page, to help understand when content is dynamically-generated etc.
I downloaded and unpacked the source for two Chrome extensions, Library Detector and Appspector. It looks like they simply call window.FUNCTION_NAME_HERE
, for example:
'Backbone.js': function () {
return window.Backbone && typeof(window.Backbone.sync) === 'function';
},
'Underscore.js': function () {
return window._ && typeof(window._.identity) === 'function' &&
window._.identity('abc') === 'abc';
},
'Spine': function () {
return window.Spine;
},
'Angular': function () {
return window.angular;
},
'Ning': function () {
return window.ning;
},
'Zepto': function () {
return window.Zepto;
}
etc.
I have a few questions:
- What are the identifiers for each framework (e.g. "Spine", "angular") called? Is there any way to retrieve this information via AJAX or otherwise, so I don't have to manually enter them?
- I don't really understand what
window.angular
means, besides that it returns either the angular object or None. I know that AngularJS has loaded if the angular function is accessible through the window object, but I'm not really sure what it even means to be a member function of the window. - Why is the procedure for Backbone and Underscore different than all the others? How do you know which one to use?
- I tried running both extensions on the Uber homepage, which uses React, and neither of them detected React. When I tried to
console.log(window)
, there wasn't a React object listed either. Why is this, and how can I still detect the framework in these cases?
- Your code expects the libraries were exported to the global space, which is not necessary to be the case. And these days with bundlers it's likely to be not the case. – zerkms Commented Nov 6, 2015 at 2:41
- 1 "Why is this, and how can I still detect the framework in these cases?" --- automatically it's unlikely you can, at least easily and reliably. – zerkms Commented Nov 6, 2015 at 2:43
- While I could see the usefulness of this goal, I'm very much unsure if there is actually a simple way you could detect the presence of most of these libraries. Javascript libraries can now be "present" in a lot of different ways pared to before. Admittedly, doing this as a browser extension may provide some analysis capabilities a normal page script wouldn't have. – Katana314 Commented Nov 6, 2015 at 18:58
1 Answer
Reset to default 11It looks like you have misunderstood how that code detecting libraries work, and of course that relates to understanding the window
object.
In a browser javascript environment window
is the global object. All variables are defined as properties of the global window
object, unless they are defined within a function with the var
keyword.
Let's say you visit a page that uses jQuery library, open the browser console and type jQuery
. That should respond with a function, which jQuery is. Essentially jQuery
is a variable defined in the global scope, and it is available as a variable by it's name, and as a property of the window
object: window.jQuery
.
What libraries do by default if you include them with <script>
tag is define themselves as a global variable. So with Backbone.js you will have Backbone
global variable defined for you, and it will be available as window.Backbone
, because window
is the global object.
Similarly, Angular will define angular
global variable, Zepto will define Zepto
, and so on.
For this reason you should be able to detect any library by the global variables it defines.
A caveat however, is that in modern javascript applications, libraries do not necessarily register a global variable. They may be defined within a scope (a function) of that application. For this reason checking window.Libraryname
doesn't guarantee the page isn't using this library. And in fact it may be a very difficult task to detect a library in this case.
- There are too many frameworks/libraries, so it is up on you to create the list, or find anyone who maintains one. Then you would look into what global variables that framework defines, so you could look for them as the identifier of that framework.
- As I explained above,
angular
is the global variable, also available aswindow.angular
. If you create a scopedangular
variable, likefunction (){ var angular = "my angular"; }
, you will still be able to get the global one withwindow.angular
. - It is possible that the maintainers of that code became aware of two or more libraries that define
Backbone
global variable. And only the Backbone we know about, includes thesync
function. That might be the reason they additionally check thatBackbone.sync
is a function. They can't just check for theBackbone.sync
function without checking forBackbone
first, because on non-backbone pages that would cause error.
Similarly, with Underscore, there might be many libraries that define global_
variable, so we can know for sure it is the Underscore library by checking one of it's methods in work. - As I mentioned above, libraries will not necessarily define a global variable, in which case you will not be able to detect them automatically. As an example, in a modern javascript application, you could use a library as a dependency with Browserify, or RequireJS, in which case the library most likely will not register any global variables.