Using closure compiler in advanced mode


#1

Hi,

My game uses Cocos2d HTML5 2.1. I was using the default jsloader to load all scripts. Today I tried the closure compiler and compiled the cocos2d sources along with my source code into a single js file. When I used the compiler in “simple” mode, it worked fine and the single file was around 600 KB. I tried using advanced mode and the file turns out to around 350 KB, which is great. However, my app fails with an error.

I’ve narrowed the error onto the _super invocation in the Application constructor (In what used to be my main.js). If I comment this line, the app goes a little further, but then fails since the super constructor was not initialized.

var cocos2dApp = cc.Application.extend({ config:document['ccConfig'], ctor:function () { this._super(); cc.COCOS2D_DEBUG = this.config.COCOS2D_DEBUG;

The error says “this.e is not a function”. (this.e being the closure compiler translated notation of this._super)

Anyone ever faced this kind of an issue before?

Regards
Hari G


#2

I’ve fixed this issue. Seems I was having trouble with advanced mode due to the following two reasons

  1. I had multiple elements in my build.xml. I unified everything into one
  2. I get a lot of data using ajax and was using dot notation to access properties within this data. Now changed to obj[“prop”] notation wherever I have external data and the code works fine after compiling.

#3

Good work.

Sorry for replying late.

The word of “_super” is not a key word of javascript. So it was hacked in cocos2d_externs.js file to avoid obfuscating.


#4

can you post your build.xml for closure compiler?


#5

Hello Jose,

Here’s my compile target. It works as of now.
@































































































@

#6

Thank’s Hari.


#7

Hi Jose

I accidentally missed the CocosDenshion part in the build file I pasted. You might most probably need to add this as well.

<sources dir="${basedir}/../js/ext/CocosDenshion"> <file name="SimpleAudioEngine.js" /> </sources>


#8

I’m gettin an error, maybe you can help me.

Uncaught TypeError: undefined is not a function


#9

Hello Jose,

Sorry for the late reply. Are you using whitespace mode or advanced mode for compilation?
One thing I notice in your file is that you are missing any extern declarations.
You need to specify all js files that you refer, but is not included in as . Plus cocos2d has an extern file that you would need to include. However, if you use whitespace compilation mode, I don’t think this will be an issue

.. Any other files you refer, but not part of compiled js

Another thing that comes to mind is that the order in which source files are mentioned is important. So, if you refer some javascript function or variable defined in another file, it should ideally come earlier in the tags.

Looking at your error, you are trying to invoke a function in some part of your code, but it cannot be resolved and is substituted by “undefined”. So if you are using whitespace mode, it could get fixed just by changing the order of files correctly. If it’s in advance mode, then the problem could be that externs are missing (In advanced mode most symbols are replaced).

The most common problem for me was that I was using some data defined elsewhere. I have an object I get from a REST service.
data = {firstName “Hari”, lastName “G”}; console.log(data.firstName);
This had to be replaced with
data[“firstName”]

Another possible problem is that you are passing some data as a javascript object and don’t quote the keys, so they get replaced
i.e. {firstName: “Hari”} might need to be {firstName “Hari”}. Closure compiler will retain quoted names.

One way of debugging would be to use a debugger like firebug and say “Break on all exceptions”. Then you can possible find the area where your code is breaking and perhaps see the callstack. Another option is to put in console.log() statements in your code to identify where the problem exactly lies.

Hope you are able to fix the problem quickly. :slight_smile:


#10

thank’s for your tips Hari, but I’m think there is a bug with cocos2d-html5.

I cannot test the HelloHTML5World example included on the cocos2d-html5 source.

I attach my demo that works without pack, but have errors packing with closure.


#11

I found a problem in the build.xml.

I’m using whitespace for finding problems.

I found that I must import file CCGeometry before CCEGLView or it doesn’t work.

Now my game works with “simple” compilationLevel, on “advanced” it throws an error.

“Uncaught TypeError: Cannot call method ‘lastIndexOf’ of undefined”

I will try to find a solution and solve it.


#12

Problem Solved.

You cannot mix [“variable”] with .variable

As you saud in a previous post, I was declaring a variable as show

Music={
    bgMusic:"bgMusic.mp3",
};

and accessing the variable as shown here

var test=Music["bgMusic"];

I need to access the variable as show here

var test=Music.bgMusic;

Or declare Music as

Music={
    "bgMusic":"bgMusic.mp3",
};

I hope this can help people solve their problems with advanced compilation.
Thank’s for your help Hari.


#13

Nice work Jose :). Yes closure compiler can fry your head when it throws errors at you. :slight_smile:


#14

Hi,

I am totally new to closure-compiling cocos2d-HTML5 game…

I do get an obfuscated file using closure compiler but when I try to run my game, I get an error saying ‘cc is undefined’…

I see that you guys have been working on obfuscation and thought that you might be able to help…

Thanks…

Hari G wrote:

Nice work Jose :). Yes closure compiler can fry your head when it throws errors at you. :slight_smile:


#15

I usually obfuscate everytime I add functions or change significant code, because I usually have errors.

For example

This have errors when obfuscating
Music={
bgMusic,
};

The “,” must be removed before obfuscate or it won’t work.

My recomendation.

Get HelloWorld obfuscated fine, and begin adding your code and obfuscating until you get an error, found the problem and solve it.

And use “ant” for obfuscating and deploying automatically on you server, because this will increase your productivity.


#16

Thanks Jose for you prompt reply,

Actually the compilation seems to be fine… The problem is that it is unable to identify ‘cc’ when it is referred for the first time in the obfuscated code…

For example,

LevelInfo.prototype.ShooterPosition=new cc.Point(452,353)

gives error saying ‘cc is not defined’ but cc.Point should be defined in cocos2d right? (I am not adding all the cocos2d js files in my build.xml…)


#17

can you post your build.xml, it seems that you have a problem with your externs.

this is my build.xml


#18

I excluded the js file that holds all the configuration parameters for cocos2d-HTML5 and also adds an event listener to initiate the loading of all the js files of the game. Then I added the obfuscated js file (game.js) as the only element in appFiles array.

This solved the issue of ‘cc is not defined’ but now, I got “Assertion failed: CCApplication ctor”

I have attached my build xml below…

Thanks


#19

I need declare in my resource.js the font file and I’m gettin a runtime error in advanced mode

My declaration

{fontName:“MarkerFelt”,
src:[
{src:“res/MarkerFelt.eot”, type:“embedded-opentype”},
{src:“res/MarkerFelt.ttf”, type:“truetype”}]}

Error:
Uncaught cocos2d:unknown filename extension: undefined

When I remove the declaration my game works fine, but I need this font on my game. =(

EDIT:

I fix this by removing the declaration and put it in my index.php:

@font-face { font-family: ‘MarkerFelt’; src: url(“res/MarkerFelt.ttf”) format(“truetype”), url(“res/MarkerFelt.eot”) format(“embedded-opentype”); }