2
votes

I created an externs file to be able to compile the jQuery Star Rating Plugin fyneworks.com/jquery/star-rating/#tab-Testing with Google Closure Compiler's ADVANCED_OPTIMIZATIONS.

But, even though I reference the standard jQuery extern, the '$' is getting renamed which breaks the plugin.

Perhaps related: if I use the unmodified plugin, 'rating' also gets renamed. I can fix that part with:

$.fn['rating'] = function(opts) {

from google closure compile jQuery Plugin ... but that doesn't fix '$' (and it would be nice to use the unmodified plugin if possible).

from my attempt at an extern (which is probably wrong and/or incomplete):

// ??? for '$'

// this one does NOT prevent 'rating' from being renamed
function rating(arg1) {}

// the following seem to work: they prevent the functions from being renamed
rating.focus = function() {}
rating.blur = function() {}
rating.fill = function() {}
... etc.

command line (and rating.sh in the download):

java -jar ../compiler-latest/compiler.jar --formatting pretty_print --compilation_level ADVANCED_OPTIMIZATIONS --externs externs/jquery-1.7.js --externs externs/jquery.rating-extern.js --js original/jquery.rating.js --js_output_file jquery.rating.gcc.js

error messages:

Firefox:
$(".star1").rating is not a function
callback: function (value) {
jquery.ratingSampleCode.js (line 9)

Chrome:
Uncaught TypeError: Object [object Object] has no method 'rating'
jquery.ratingSampleCode.js:8

from my sample code:

$('.star1').rating({
    callback: function (value) {

To test: http://prefabsoftware.com/test/rating-july15/

To download: prefabsoftware.com/test/rating-july15.zip

Some useful links: (which I'm not allowed to specify as markdown since I couldn't login with my old reputation points...)

  • Advanced Compilation and Externs: developers.google.com/closure/compiler/docs/api-tutorial3#externs
  • sample externs: contrib: code.google.com/p/closure-compiler/source/browse/#svn%2Ftrunk%2Fcontrib%2Fexterns) including jQuery itself, but not the rating plugin
  • more externs: code.google.com/p/closure-compiler/source/browse/#svn%2Ftrunk%2Fexterns

Is there a simple fix for the extern? Or a better solution?

Thanks!


Ok, this works for the externs file:

$.prototype.rating = function(arg1) {}
jQuery.prototype.rating = function(arg1) {}

$.prototype.rating.focus = function() {}
... etc.
2
I see: I should actually compile everything except the plug-in, and just reference that in the usual way. And, thanks much for the extern tips; I added working code above since I can't add in this comment.Scott Lawton

2 Answers

1
votes

From your description, you appear to be using an extern file improperly. An extern file for your plugin would allow other users to compile code referencing your plugin. It shouldn't be used to compile your actual plugin code at all. To compile your code, you would only need the jQuery extern file.

jQuery code styles have known issues with Closure-compiler. In particular, you would need to avoid the following:

  • Any use of the $ alias. Use the full jQuery namespace. The compiler doesn't handle aliased namespaces well.
  • The jQuery.fn alias. Instead use jQuery.prototype.
  • Use of the jQuery.extend method to add function prototypes or public methods. Instead, add them directly to the prototype. (example: jQuery.fn.extend({a: 'foo'}); would become jQuery.prototype.a = 'foo';);

With ADVANCED_OPTIMIZATIONS, keep in mind that you will still have to export or quote any public methods and prototypes. This may mean that SIMPLE_OPTIMIZATIONS turn out to be a better fit for your project.

For more information, see http://blogs.missouristate.edu/web/2011/02/14/jquery-plugins-and-closure-compiler/