Merge lp:~tveronezi/juju-gui/uglify into lp:juju-gui/experimental

Proposed by Thiago Veronezi
Status: Merged
Merged at revision: 235
Proposed branch: lp:~tveronezi/juju-gui/uglify
Merge into: lp:juju-gui/experimental
Diff against target: 664 lines (+398/-115)
11 files modified
.bzrignore (+1/-0)
Makefile (+21/-3)
app/index.html (+3/-3)
app/modules-debug.js (+131/-0)
app/modules.js (+7/-104)
bin/merge-files (+75/-0)
grunt.js (+1/-1)
lib/merge-files.js (+137/-0)
lib/server.js (+19/-2)
package.json (+2/-1)
test/index.html (+1/-1)
To merge this branch: bzr merge lp:~tveronezi/juju-gui/uglify
Reviewer Review Type Date Requested Status
Benji York (community) code Approve
Review via email: mp+133116@code.launchpad.net

Description of the change

Resource minification/aggregation js

* We should aggregate and minimize the js sources in order to improve the load speed of the application;
* We dont want to use the yui combo loader feature;
* The final product will provide three js files: one for the YUI dependencies, one for our custom js code and one for third part js like d3.

https://codereview.appspot.com/6821090/

To post a comment you must log in.
Revision history for this message
Thiago Veronezi (tveronezi) wrote :

Reviewers: mp+133116_code.launchpad.net,

Message:
Please take a look.

Description:
Resource minification/aggregation js

* We should aggregate and minimize the js sources in order to improve
the load speed of the application;
* We dont want to use the yui combo loader feature;
* The final product will provide three js files: one for the YUI
dependencies, one for our custom js code and one for third part js like
d3.

https://code.launchpad.net/~tveronezi/juju-gui/uglify/+merge/133116

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/6821090/

Affected files:
   M .bzrignore
   M Makefile
   A [revision details]
   M app/index.html
   A app/modules-debug.js
   M app/modules.js
   M grunt.js
   M lib/server.js
   A merge-files.js
   M package.json
   A properties-dev.js
   A properties-prod.js
   M test/index.html

lp:~tveronezi/juju-gui/uglify updated
233. By Thiago Veronezi

using yui loop functions

Revision history for this message
Thiago Veronezi (tveronezi) wrote :

https://codereview.appspot.com/6821090/diff/1/merge-files.js
File merge-files.js (right):

https://codereview.appspot.com/6821090/diff/1/merge-files.js#newcode25
merge-files.js:25: function loop(arr, callback) {
Please ignore this method. I am using the Y.each version of it.

https://codereview.appspot.com/6821090/

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
lp:~tveronezi/juju-gui/uglify updated
234. By Thiago Veronezi

generated combined files should go under /app/Error: listen EADDRINUSE

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
lp:~tveronezi/juju-gui/uglify updated
235. By Thiago Veronezi

the combine code should go under the combine directory

236. By Thiago Veronezi

the combine code should go under the combine directory

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
Revision history for this message
Thiago Veronezi (tveronezi) wrote :

Thanks, Benji!

https://codereview.appspot.com/6821090/diff/7001/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode12
Makefile:12: node_modules/grunt node_modules/node-spritesheet
node_modules/node-minify
This line does not have more than 80 chars, but I changed it anyway.

On 2012/11/07 17:05:18, benji wrote:
> This line is too long.

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode75
Makefile:75: @cp app/assets/combine/properties-dev.js
app/assets/javascripts/generated/properties.js
On 2012/11/07 17:05:18, benji wrote:
> This line is too long.

Done.

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode80
Makefile:80: @cp app/assets/combine/properties-prod.js
app/assets/javascripts/generated/properties.js
On 2012/11/07 17:05:18, benji wrote:
> This line is too long.

Done.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js
File app/assets/combine/merge-files.js (right):

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode1
app/assets/combine/merge-files.js:1: 'use strict';
This is entirely ours.

On 2012/11/07 17:05:18, benji wrote:
> Is this code we wrote or was it imported from somewhere? If it was
written
> elsewhere, we need to specify its license and it would be nice to know
where it
> came from.

> I will forgo reviewing the code until I know the answers to the above.

https://codereview.appspot.com/6821090/diff/7001/app/index.html
File app/index.html (right):

https://codereview.appspot.com/6821090/diff/7001/app/index.html#newcode72
app/index.html:72: <script src="/source/yui.js"></script>
What about '/assets/yui.js'? Id this ok?

On 2012/11/07 17:05:18, benji wrote:
> We have been calling these things "assets". If the change to "source"
was a
> considered one, then I am fine with it. If not, we should continue to
use the
> same terminology that we have been using.

https://codereview.appspot.com/6821090/diff/7001/lib/server.js
File lib/server.js (right):

https://codereview.appspot.com/6821090/diff/7001/lib/server.js#newcode50
lib/server.js:50: server.get('/source/all-third.js', function(req, res)
{
I want to hide the real path.
I can change it to '/assets/all-third.js', would it be ok?

On 2012/11/07 17:05:18, benji wrote:
> Why should the path exposed via HTTP ("source") be different than the
path on
> disk ("assets")?

https://codereview.appspot.com/6821090/

lp:~tveronezi/juju-gui/uglify updated
237. By Thiago Veronezi

code review

Revision history for this message
Gary Poster (gary) wrote :
Download full text (6.1 KiB)

Hi Thiago. Thank you for this nice step forward: it will be great when
we have this functionality, and the debug/developer story you've
arranged is nicer than I expected.

This is a preliminary review. As I mention, I want to review
merge-files.js more later, but I'm going to let Benji take a first pass
and send my notes so far to you sooner.

Gary

https://codereview.appspot.com/6821090/diff/7001/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode64
Makefile:64: combinejs: $(NODE_TARGETS)
As I mentioned on IRC, this has the same problem we talked about with
sprite generation: every time you run the target it will try to compress
the files. Since install depends on this, and just about everything
depends on install, this can affect most make targets and be pretty
annoying.

One approach to solving this is http://pastebin.ubuntu.com/1340722/

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode89
Makefile:89: @rm -Rf app/assets/javascripts/generated/
Good.

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode107
Makefile:107: combinejs
Good.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js
File app/assets/combine/merge-files.js (right):

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode1
app/assets/combine/merge-files.js:1: 'use strict';
I don't think this file belongs in app/assets. This is a build
component, and we never want to serve it as part of the application. I
suggest that we put it in the top directory, or in bin. I lean towards
bin.

This is as good a time as any to mention that I think this branch is a
great example of something that could have probably benefitted from a
pre-implementation call (and maybe a prototyping).

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode3
app/assets/combine/merge-files.js:3: //
http://stackoverflow.com/questions/5348685/node-js-require-inheritance
Nice that you gave attribution. I personally don't think it is
necessary in this case. It was good to see as a reviewer, but it would
have been even better as part of your "cover letter" introduction to
your branch.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode6
app/assets/combine/merge-files.js:6: var Y = YUI(),
Why did you choose to do this rather than "YUI().use(..., function(Y)
{...});"?

You could even remove line 4. One approach:

require('yui').YUI().use(...);

another approach:

var Y = require('yui').YUI(),

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode27
app/assets/combine/merge-files.js:27: (function() {
I have a number of comments I already suspect I want to make about this
file--here, for instance, I think I will request that you add a lot more
comments, and possibly refactor, and possibly reconsider your approach
to compartmentalizing the various parts of the file. However, I
conferred with Benji, and I am going to be lazy and see what he has to
say first, and then follow along afterwards. That way I can get my
other comments to you faster.

https://code...

Read more...

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
Download full text (7.3 KiB)

Thanks Gary.

https://codereview.appspot.com/6821090/diff/7001/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode64
Makefile:64: combinejs: $(NODE_TARGETS)
On 2012/11/07 20:49:31, gary.poster wrote:
> As I mentioned on IRC, this has the same problem we talked about with
sprite
> generation: every time you run the target it will try to compress the
files.
> Since install depends on this, and just about everything depends on
install,
> this can affect most make targets and be pretty annoying.

> One approach to solving this is http://pastebin.ubuntu.com/1340722/

Done.

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode75
Makefile:75: @cp app/assets/combine/properties-dev.js
app/assets/javascripts/generated/properties.js
On 2012/11/07 17:05:18, benji wrote:
> This line is too long.

Done.

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode89
Makefile:89: @rm -Rf app/assets/javascripts/generated/
On 2012/11/07 20:49:31, gary.poster wrote:
> Good.

Done.

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode107
Makefile:107: combinejs
On 2012/11/07 20:49:31, gary.poster wrote:
> Good.

Done.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js
File app/assets/combine/merge-files.js (right):

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode1
app/assets/combine/merge-files.js:1: 'use strict';
On 2012/11/07 20:49:31, gary.poster wrote:
> I don't think this file belongs in app/assets. This is a build
component, and
> we never want to serve it as part of the application. I suggest that
we put it
> in the top directory, or in bin. I lean towards bin.

> This is as good a time as any to mention that I think this branch is a
great
> example of something that could have probably benefitted from a
> pre-implementation call (and maybe a prototyping).

This branch had a pre-implementation call. I moved this file here
because Ben asked me to do it.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode3
app/assets/combine/merge-files.js:3: //
http://stackoverflow.com/questions/5348685/node-js-require-inheritance
On 2012/11/07 20:49:31, gary.poster wrote:
> Nice that you gave attribution. I personally don't think it is
necessary in
> this case. It was good to see as a reviewer, but it would have been
even better
> as part of your "cover letter" introduction to your branch.

This is not part of the global solution. This is here just to explain
why I use the "global" object.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode6
app/assets/combine/merge-files.js:6: var Y = YUI(),
On 2012/11/07 20:49:31, gary.poster wrote:
> Why did you choose to do this rather than "YUI().use(..., function(Y)
{...});"?

> You could even remove line 4. One approach:

> require('yui').YUI().use(...);

> another approach:

> var Y = require('yui').YUI(),

I did it because I dont require any internal yui code. I use it to get
the Y.Object, Y.Array and Y.Loader objects.

I cannot remove the line 4. It is used by the line 82. When node
executes...

Read more...

lp:~tveronezi/juju-gui/uglify updated
238. By Thiago Veronezi

code review

239. By Thiago Veronezi

trunk merge

240. By Thiago Veronezi

code review

241. By Thiago Veronezi

code review

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
Download full text (5.1 KiB)

Tkx Benji.

https://codereview.appspot.com/6821090/diff/7001/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/7001/Makefile#newcode12
Makefile:12: node_modules/grunt node_modules/node-spritesheet
node_modules/node-minify
On 2012/11/07 22:00:47, benji wrote:
> On 2012/11/07 18:59:19, thiago wrote:
> > This line does not have more than 80 chars, but I changed it anyway.

> Correct, it has fewer than 80 characters but one of those characters
is a tab,
> which in most editors displays as 8 spaces, pushing the line over 80
displayed
> characters.

Ok

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js
File app/assets/combine/merge-files.js (right):

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode1
app/assets/combine/merge-files.js:1: 'use strict';
On 2012/11/07 22:00:47, benji wrote:
> On 2012/11/07 18:59:19, thiago wrote:
> > This is entirely ours.

> Top-posting makes replying to comments difficult. Please reply below
the
> previous comment.

Ok

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode3
app/assets/combine/merge-files.js:3: //
http://stackoverflow.com/questions/5348685/node-js-require-inheritance
On 2012/11/07 22:00:47, benji wrote:
> Even after reading the page at the other end of this link I don't know
what it
> has to do with the code here. Additional comments would help.

Done.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode5
app/assets/combine/merge-files.js:5:
On 2012/11/07 22:00:47, benji wrote:
> I am surprised that we had to write this script. I would have
expected someone,
> somewhere to have already done this for us.

Not really. People usually use the comboloader for yui applications. I
had a lot of fun writing it though.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode14
app/assets/combine/merge-files.js:14: var execution = new
compressor.minify({
On 2012/11/07 22:00:47, benji wrote:
> object literal style

How should it be?

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode88
app/assets/combine/merge-files.js:88: var reqs = (function() {
On 2012/11/07 22:00:47, benji wrote:
> This function would benefit from a name.

This is not a function. This is an object: a list of all the yui
requirements we need to load.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode105
app/assets/combine/merge-files.js:105: // Using the example
http://yuilibrary.com/yui/docs/yui/loader-resolve.html
On 2012/11/07 22:00:47, benji wrote:
> I am not sure what this comment is trying to communicate. Is it that
I can find
> an explanation of the YUI loader mechanism at the given URL?

Nop. It uses the reqs object that we created in the previous block and
figures out the js files that contain it.

I will add it as comment here.

https://codereview.appspot.com/6821090/diff/7001/app/assets/combine/merge-files.js#newcode111
app/assets/combine/merge-files.js:111: loader = new Y.Loader({
On 2012/11/07 22:00:47, benji wrote:
> object literal sty...

Read more...

lp:~tveronezi/juju-gui/uglify updated
242. By Thiago Veronezi

making lint happy

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
lp:~tveronezi/juju-gui/uglify updated
243. By Thiago Veronezi

missing commit

Revision history for this message
Thiago Veronezi (tveronezi) wrote :

https://codereview.appspot.com/6821090/diff/3002/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/3002/Makefile#newcode12
Makefile:12: node_modules/grunt node_modules/node-spritesheet
node_modules/node-minify
Missing commit. You should see this line break in the next commit.

https://codereview.appspot.com/6821090/

lp:~tveronezi/juju-gui/uglify updated
244. By Thiago Veronezi

code review

245. By Thiago Veronezi

code review

246. By Thiago Veronezi

moving the functions to the lib directory

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
Revision history for this message
Thiago Veronezi (tveronezi) wrote :

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files
File bin/merge-files (right):

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files#newcode20
bin/merge-files:20: global.YUI = require('yui').YUI;
Please ignore this entry. I moved it to the lib/merge-files.js file.

=== modified file 'bin/merge-files'
--- bin/merge-files 2012-11-09 12:54:56 +0000
+++ bin/merge-files 2012-11-09 13:00:19 +0000
@@ -14,12 +14,7 @@

  'use strict';

-// We need the yui name to be available in all modules (as a global
variable).
-// This only happens if we remove the 'var' keyword or add it to the
"global"
-// variable.
-global.YUI = require('yui').YUI;
-
-YUI().use(['yui'], function(Y) {
+require('yui').YUI().use(['yui'], function(Y) {
    var merge = require('../lib/merge-files.js'),
        syspath = require('path'),
        paths,

https://codereview.appspot.com/6821090/

lp:~tveronezi/juju-gui/uglify updated
247. By Thiago Veronezi

code review

Revision history for this message
Gary Poster (gary) wrote :
Download full text (4.2 KiB)

This is looking good, Thiago. Thank you!

As we discussed, I'm OK with holding off on tests. The last non-trivial
thing I'd like to see is removing the code that writes properties. I
give two possible approaches below.

I'm happy to have a call if it helps, or leave it to you, as you prefer.

Thanks!

Gary

https://codereview.appspot.com/6821090/diff/15005/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/15005/Makefile#newcode82
Makefile:82: @./bin/write-properties true
I really would like to see this (and the corresponding line in 87 and
the corresponding "write-properties" script) go.

My preferred approach, which we talked about yesterday, would be to make
the server always have both the debug version (debug.html?) and the
production version (index.html) available, by having the server
dynamically change the js files that index.html points to.

Alternatively, server.js would accept an argument to turn on debug mode.
  By default, it would run in prodcution mode.

https://codereview.appspot.com/6821090/diff/15005/app/modules-debug.js
File app/modules-debug.js (right):

https://codereview.appspot.com/6821090/diff/15005/app/modules-debug.js#newcode1
app/modules-debug.js:1: GlobalConfig = {
An idea (as in, do this if you agree): it would be nice to have a
comment at the top of this file saying that it is only used for the
debug (developer) views of the application, and pointing to the
mechanism that is used (e.g., in server.js) to serve this file rather
than the other one.

Maybe it's overkill. I'd do it, but I'd be fine with accepting
disagreement.

https://codereview.appspot.com/6821090/diff/15005/app/modules.js
File app/modules.js (right):

https://codereview.appspot.com/6821090/diff/15005/app/modules.js#newcode4
app/modules.js:4: ignoreRegistered: true,
Is there a setting we can use to say "never download anything from the
internet, ever"? If so, I suggest we use that both for this and the
debug modules file.

Is it bootstrap: false? Or is this already handled somehow?

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files
File bin/merge-files (right):

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files#newcode1
bin/merge-files:1: #!/usr/bin/env node
These changes look great to me. Thanks.

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files#newcode4
bin/merge-files:4: * We should aggregate and minimize the js sources in
order to improve the load
suggestion: delete "should". (We are doing it. :-) )

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files#newcode8
bin/merge-files:8: * to run from only static files and we want to be
able to run behaind a
"behind" (I realize these are probably my fault. sorry :-) )

https://codereview.appspot.com/6821090/diff/15005/bin/write-properties
File bin/write-properties (right):

https://codereview.appspot.com/6821090/diff/15005/bin/write-properties#newcode1
bin/write-properties:1: #!/usr/bin/env node
As I said, I'd like to delete.

https://codereview.appspot.com/6821090/diff/15005/lib/merge-files.js
File lib/merge-files.js (right):

https://codereview.appspot.com/6821090/diff/15005/lib/merge-files.js#newcode14
lib...

Read more...

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
Download full text (4.2 KiB)

https://codereview.appspot.com/6821090/diff/15005/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/15005/Makefile#newcode82
Makefile:82: @./bin/write-properties true
On 2012/11/09 13:57:38, gary.poster wrote:
> I really would like to see this (and the corresponding line in 87 and
the
> corresponding "write-properties" script) go.

> My preferred approach, which we talked about yesterday, would be to
make the
> server always have both the debug version (debug.html?) and the
production
> version (index.html) available, by having the server dynamically
change the js
> files that index.html points to.

> Alternatively, server.js would accept an argument to turn on debug
mode. By
> default, it would run in prodcution mode.

Using the server approach for now.
Thanks for this idea. Really good.

https://codereview.appspot.com/6821090/diff/15005/app/modules-debug.js
File app/modules-debug.js (right):

https://codereview.appspot.com/6821090/diff/15005/app/modules-debug.js#newcode1
app/modules-debug.js:1: GlobalConfig = {
On 2012/11/09 13:57:38, gary.poster wrote:
> An idea (as in, do this if you agree): it would be nice to have a
comment at the
> top of this file saying that it is only used for the debug (developer)
views of
> the application, and pointing to the mechanism that is used (e.g., in
server.js)
> to serve this file rather than the other one.

> Maybe it's overkill. I'd do it, but I'd be fine with accepting
disagreement.

Done.

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files
File bin/merge-files (right):

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files#newcode1
bin/merge-files:1: #!/usr/bin/env node
On 2012/11/09 13:57:38, gary.poster wrote:
> These changes look great to me. Thanks.

Done.

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files#newcode4
bin/merge-files:4: * We should aggregate and minimize the js sources in
order to improve the load
On 2012/11/09 13:57:38, gary.poster wrote:
> suggestion: delete "should". (We are doing it. :-) )

Done.

https://codereview.appspot.com/6821090/diff/15005/bin/merge-files#newcode8
bin/merge-files:8: * to run from only static files and we want to be
able to run behaind a
On 2012/11/09 13:57:38, gary.poster wrote:
> "behind" (I realize these are probably my fault. sorry :-) )

Done.

https://codereview.appspot.com/6821090/diff/15005/bin/write-properties
File bin/write-properties (right):

https://codereview.appspot.com/6821090/diff/15005/bin/write-properties#newcode1
bin/write-properties:1: #!/usr/bin/env node
On 2012/11/09 13:57:38, gary.poster wrote:
> As I said, I'd like to delete.

Done.

https://codereview.appspot.com/6821090/diff/15005/lib/merge-files.js
File lib/merge-files.js (right):

https://codereview.appspot.com/6821090/diff/15005/lib/merge-files.js#newcode14
lib/merge-files.js:14: // end.
On 2012/11/09 13:57:38, gary.poster wrote:
> Another option (up to you): remove this comment, and do the export of
each
> function as you define it ("expose.minify = function(file) {...}" for
instance)
> or immediately after you define it.

Done.

https://codereview.appspot.com/6821090/diff/15005/lib/merge-files.js#newc...

Read more...

lp:~tveronezi/juju-gui/uglify updated
248. By Thiago Veronezi

code review

249. By Thiago Veronezi

add comments about 'bootstrap=false'

Revision history for this message
Thiago Veronezi (tveronezi) wrote :

https://codereview.appspot.com/6821090/diff/15005/app/modules.js
File app/modules.js (right):

https://codereview.appspot.com/6821090/diff/15005/app/modules.js#newcode4
app/modules.js:4: ignoreRegistered: true,
On 2012/11/09 13:57:38, gary.poster wrote:
> Is there a setting we can use to say "never download anything from the
internet,
> ever"? If so, I suggest we use that both for this and the debug
modules file.

> Is it bootstrap: false? Or is this already handled somehow?

We agreed that it wont be possible to use it. I've added comments about
this know issue in the "merge-files" file.

https://codereview.appspot.com/6821090/

lp:~tveronezi/juju-gui/uglify updated
250. By Thiago Veronezi

add comments about 'bootstrap=false'

Revision history for this message
Thiago Veronezi (tveronezi) wrote :
Revision history for this message
Gary Poster (gary) wrote :

Hi Thiago. This looks good to me.

Per our discussions:

- We are foregoing tests on the lib functions. You can see now how you
would do them. You might do a follow-up branch with tests or might not.
  I would be happy to see that change. However, I won't stop you from
landing this without them.

- We are foregoing the "bootstrap=false" change that forces us to keep
from downloading files. It would be a nice seatbelt but it had problems
that you documented.

Thank you!

Gary

https://codereview.appspot.com/6821090/diff/2005/Makefile
File Makefile (right):

https://codereview.appspot.com/6821090/diff/2005/Makefile#newcode83
Makefile:83: @node server.js debug
yay, much nicer, thanks

https://codereview.appspot.com/6821090/diff/2005/app/modules-debug.js
File app/modules-debug.js (right):

https://codereview.appspot.com/6821090/diff/2005/app/modules-debug.js#newcode3
app/modules-debug.js:3: // "lib/server.js".
Great.

https://codereview.appspot.com/6821090/

Revision history for this message
Benji York (benji) :
review: Approve (code)
lp:~tveronezi/juju-gui/uglify updated
251. By Thiago Veronezi

trunk merge

Revision history for this message
Thiago Veronezi (tveronezi) wrote :

*** Submitted:

Resource minification/aggregation js

* We should aggregate and minimize the js sources in order to improve
the load speed of the application;
* We dont want to use the yui combo loader feature;
* The final product will provide three js files: one for the YUI
dependencies, one for our custom js code and one for third part js like
d3.

R=benji, gary.poster
CC=
https://codereview.appspot.com/6821090

https://codereview.appspot.com/6821090/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2012-10-31 09:16:13 +0000
3+++ .bzrignore 2012-11-09 20:53:21 +0000
4@@ -20,3 +20,4 @@
5 yuidoc
6 app/assets/manifest.appcache
7 app/assets/sprite
8+app/assets/javascripts/generated/
9
10=== modified file 'Makefile'
11--- Makefile 2012-11-06 13:16:34 +0000
12+++ Makefile 2012-11-09 20:53:21 +0000
13@@ -9,10 +9,15 @@
14 node_modules/mocha node_modules/d3 node_modules/graceful-fs \
15 node_modules/should node_modules/jshint node_modules/expect.js \
16 node_modules/express node_modules/yui node_modules/yuidoc \
17- node_modules/grunt node_modules/node-spritesheet
18+ node_modules/grunt node_modules/node-spritesheet \
19+ node_modules/node-minify
20 TEMPLATE_TARGETS=$(shell bzr ls -k file app/templates)
21 SPRITE_SOURCE_FILES=$(shell bzr ls -R -k file app/assets/images)
22 SPRITE_GENERATED_FILES=app/assets/sprite/sprite.css app/assets/sprite/sprite.png
23+COMPRESSED_FILES=app/assets/javascripts/generated/all-app-debug.js \
24+ app/assets/javascripts/generated/all-app.js \
25+ app/assets/javascripts/generated/all-third.js \
26+ app/assets/javascripts/generated/all-yui.js
27 DATE=$(shell date -u)
28 APPCACHE=app/assets/manifest.appcache
29
30@@ -37,7 +42,7 @@
31 @ln -sf `pwd`/node_modules/yui ./app/assets/javascripts/
32 @ln -sf `pwd`/node_modules/d3/d3.v2* ./app/assets/javascripts/
33
34-install: appcache $(NODE_TARGETS) app/templates.js yuidoc spritegen
35+install: appcache $(NODE_TARGETS) app/templates.js yuidoc spritegen combinejs
36
37 gjslint: virtualenv/bin/gjslint
38 @virtualenv/bin/gjslint --strict --nojsdoc --jslint_error=all \
39@@ -61,11 +66,22 @@
40
41 spritegen: $(SPRITE_GENERATED_FILES)
42
43+$(COMPRESSED_FILES): node_modules/yui node_modules/d3/d3.v2.min.js $(JSFILES)
44+ @rm -Rf app/assets/javascripts/generated/
45+ @mkdir app/assets/javascripts/generated/
46+ @./bin/merge-files
47+
48+combinejs: $(COMPRESSED_FILES)
49+
50 prep: beautify lint
51
52 test: install
53 @./test-server.sh
54
55+debug: install
56+ @echo "Customize config.js to modify server settings"
57+ @node server.js debug
58+
59 server: install
60 @echo "Customize config.js to modify server settings"
61 @node server.js
62@@ -75,6 +91,7 @@
63 @make -C docs clean
64 @rm -Rf bin/sprite/
65 @rm -Rf app/assets/sprite/
66+ @rm -Rf app/assets/javascripts/generated/
67
68 $(APPCACHE): manifest.appcache.in
69 @cp manifest.appcache.in $(APPCACHE)
70@@ -91,4 +108,5 @@
71 appcache-force: appcache-touch appcache
72
73 .PHONY: test lint beautify server install clean prep jshint gjslint \
74- appcache appcache-touch appcache-force yuidoc spritegen yuidoc-lint
75+ appcache appcache-touch appcache-force yuidoc spritegen yuidoc-lint \
76+ combinejs
77
78=== modified file 'app/index.html'
79--- app/index.html 2012-11-01 13:21:53 +0000
80+++ app/index.html 2012-11-09 20:53:21 +0000
81@@ -69,9 +69,9 @@
82 <div id="vp-right-border"></div>
83 </div>
84 <!-- javascript away -->
85- <script src="/juju-ui/assets/javascripts/yui/yui/yui-debug.js"></script>
86- <script src="/juju-ui/modules.js"></script>
87- <script src="/config.js"></script>
88+ <script src="/assets/yui.js"></script>
89+ <script src="/assets/all-third.js"></script>
90+ <script src="/assets/modules.js"></script>
91 <script>
92 YUI(GlobalConfig).use(["juju-gui"], function(Y) {
93 app = new Y.juju.App(juju_config);
94
95=== added file 'app/modules-debug.js'
96--- app/modules-debug.js 1970-01-01 00:00:00 +0000
97+++ app/modules-debug.js 2012-11-09 20:53:21 +0000
98@@ -0,0 +1,131 @@
99+// This file is used for development only. In order to use it you should call
100+// the "make debug" command. This command passes the "debug" argument to the
101+// "lib/server.js".
102+GlobalConfig = {
103+ filter: 'debug',
104+ // Set "true" for verbose logging of YUI
105+ debug: false,
106+
107+ // Use Rollups
108+ combine: false,
109+
110+ groups: {
111+ d3: {
112+ modules: {
113+ 'd3': {
114+ 'fullpath': '/juju-ui/assets/javascripts/d3.v2.min.js'
115+ }
116+ }
117+ },
118+ juju: {
119+ modules: {
120+ // Primitives
121+
122+ 'svg-layouts': {
123+ fullpath: '/juju-ui/assets/javascripts/svg-layouts.js'
124+ },
125+
126+ 'reconnecting-websocket': {
127+ fullpath: '/juju-ui/assets/javascripts/reconnecting-websocket.js'
128+ },
129+
130+ // Views
131+ 'juju-view-utils': {
132+ fullpath: '/juju-ui/views/utils.js'
133+ },
134+
135+ 'juju-charm-panel': {
136+ fullpath: '/juju-ui/views/charm-panel.js'
137+ },
138+
139+ 'juju-notifications': {
140+ fullpath: '/juju-ui/views/notifications.js'
141+ },
142+
143+ 'juju-view-environment': {
144+ fullpath: '/juju-ui/views/environment.js'
145+ },
146+
147+ 'juju-view-service': {
148+ fullpath: '/juju-ui/views/service.js'
149+ },
150+
151+ 'juju-view-unit': {
152+ fullpath: '/juju-ui/views/unit.js'
153+ },
154+
155+ 'juju-view-charm-collection': {
156+ fullpath: '/juju-ui/views/charm.js'
157+ },
158+
159+ 'juju-view-charm': {
160+ fullpath: '/juju-ui/views/charm.js'
161+ },
162+
163+ 'juju-templates': {
164+ fullpath: '/juju-ui/templates.js'
165+ },
166+
167+ 'juju-views': {
168+ use: [
169+ 'juju-templates',
170+ 'juju-notifications',
171+ 'juju-view-utils',
172+ 'juju-view-environment',
173+ 'juju-view-service',
174+ 'juju-view-unit',
175+ 'juju-view-charm',
176+ 'juju-view-charm-collection'
177+ ]
178+ },
179+
180+ // Models
181+ 'juju-endpoints': {
182+ fullpath: '/juju-ui/models/endpoints.js'
183+ },
184+
185+ 'juju-charm-models': {
186+ requires: ['juju-charm-id'],
187+ fullpath: '/juju-ui/models/charm.js'
188+ },
189+
190+ 'juju-models': {
191+ requires: [
192+ 'model', 'model-list', 'juju-endpoints', 'juju-charm-models'],
193+ fullpath: '/juju-ui/models/models.js'
194+ },
195+
196+ // Connectivity
197+ 'juju-env': {
198+ requires: ['reconnecting-websocket'],
199+ fullpath: '/juju-ui/store/env.js'
200+ },
201+
202+ 'juju-notification-controller': {
203+ fullpath: '/juju-ui/store/notifications.js'
204+ },
205+
206+ 'juju-charm-store': {
207+ requires: ['juju-charm-id'],
208+ fullpath: '/juju-ui/store/charm.js'
209+ },
210+
211+ 'juju-controllers': {
212+ use: ['juju-env', 'juju-charm-store',
213+ 'juju-notification-controller']
214+ },
215+
216+ // App
217+ 'juju-gui': {
218+ fullpath: '/juju-ui/app.js',
219+ requires: [
220+ 'juju-controllers',
221+ 'juju-views',
222+ 'juju-models',
223+ 'juju-view-charm-search'
224+ ]
225+ }
226+ }
227+ }
228+ }
229+};
230
231=== modified file 'app/modules.js'
232--- app/modules.js 2012-11-01 13:30:58 +0000
233+++ app/modules.js 2012-11-09 20:53:21 +0000
234@@ -1,69 +1,11 @@
235 GlobalConfig = {
236- // Uncomment for debug versions of YUI.
237- filter: 'debug',
238- // Uncomment for verbose logging of YUI
239 debug: false,
240-
241- // Use Rollups
242- combine: false,
243+ // YUI will not download the modules. They are supposed to be already loaded.
244+ ignoreRegistered: true,
245
246 groups: {
247- d3: {
248- modules: {
249- 'd3': {
250- 'fullpath': '/juju-ui/assets/javascripts/d3.v2.min.js'
251- }
252- }
253- },
254 juju: {
255 modules: {
256- // Primitives
257-
258- 'svg-layouts': {
259- fullpath: '/juju-ui/assets/javascripts/svg-layouts.js'
260- },
261-
262- 'reconnecting-websocket': {
263- fullpath: '/juju-ui/assets/javascripts/reconnecting-websocket.js'
264- },
265-
266- // Views
267- 'juju-view-utils': {
268- fullpath: '/juju-ui/views/utils.js'
269- },
270-
271- 'juju-charm-panel': {
272- fullpath: '/juju-ui/views/charm-panel.js'
273- },
274-
275- 'juju-notifications': {
276- fullpath: '/juju-ui/views/notifications.js'
277- },
278-
279- 'juju-view-environment': {
280- fullpath: '/juju-ui/views/environment.js'
281- },
282-
283- 'juju-view-service': {
284- fullpath: '/juju-ui/views/service.js'
285- },
286-
287- 'juju-view-unit': {
288- fullpath: '/juju-ui/views/unit.js'
289- },
290-
291- 'juju-view-charm-collection': {
292- fullpath: '/juju-ui/views/charm.js'
293- },
294-
295- 'juju-view-charm': {
296- fullpath: '/juju-ui/views/charm.js'
297- },
298-
299- 'juju-templates': {
300- fullpath: '/juju-ui/templates.js'
301- },
302-
303 'juju-views': {
304 use: [
305 'juju-templates',
306@@ -77,51 +19,12 @@
307 ]
308 },
309
310- // Models
311- 'juju-endpoints': {
312- fullpath: '/juju-ui/models/endpoints.js'
313- },
314-
315- 'juju-charm-models': {
316- requires: ['juju-charm-id'],
317- fullpath: '/juju-ui/models/charm.js'
318- },
319-
320- 'juju-models': {
321- requires: [
322- 'model', 'model-list', 'juju-endpoints', 'juju-charm-models'],
323- fullpath: '/juju-ui/models/models.js'
324- },
325-
326- // Connectivity
327- 'juju-env': {
328- requires: ['reconnecting-websocket'],
329- fullpath: '/juju-ui/store/env.js'
330- },
331-
332- 'juju-notification-controller': {
333- fullpath: '/juju-ui/store/notifications.js'
334- },
335-
336- 'juju-charm-store': {
337- requires: ['juju-charm-id'],
338- fullpath: '/juju-ui/store/charm.js'
339- },
340-
341+ // 'juju-controllers' is just an alias for the modules defined by 'use'
342+ // If we use "requires: ['juju-controllers']" that means
343+ // "requires: ['juju-env', 'juju-charm-store',
344+ // 'juju-notification-controller']"
345 'juju-controllers': {
346- use: ['juju-env', 'juju-charm-store',
347- 'juju-notification-controller']
348- },
349-
350- // App
351- 'juju-gui': {
352- fullpath: '/juju-ui/app.js',
353- requires: [
354- 'juju-controllers',
355- 'juju-views',
356- 'juju-models',
357- 'juju-view-charm-search'
358- ]
359+ use: ['juju-env', 'juju-charm-store', 'juju-notification-controller']
360 }
361 }
362 }
363
364=== added file 'bin/merge-files'
365--- bin/merge-files 1970-01-01 00:00:00 +0000
366+++ bin/merge-files 2012-11-09 20:53:21 +0000
367@@ -0,0 +1,75 @@
368+#!/usr/bin/env node
369+
370+/**
371+ * We aggregate and minimize the js sources in order to improve the load speed
372+ * of the application.
373+ *
374+ * We don't want to use the yui combo loader feature because we want to be able
375+ * to run from only static files and we want to be able to run behind a
376+ * firewall without access to the internet.
377+ *
378+ * The final product will provide three js files: one for the YUI dependencies,
379+ * one for our custom js code and one for third party js like d3.
380+ *
381+ * Known issues:
382+ * (1) If we set "bootstrap=false" in the GlobalConfig object, yui disables the
383+ * loader object. It means it wont even try to download modules. We cannot
384+ * do it because the loader also manages the "use" property which defines
385+ * aliases for some of your modules ('juju-views' and 'juju-controllers').
386+ * (2) During development, we've noticed that some of the yui modules weren't
387+ * included in the list of yui files (lang/datatype-date-format_en-US,
388+ * parallel, app-transitions-native, gallery-markdown, loader-base). For
389+ * some reason, the loader does not resolve the names of the files for
390+ * these modules. We need to add them manually in this file.
391+ */
392+
393+'use strict';
394+
395+require('yui').YUI().use(['yui'], function(Y) {
396+ var merge = require('../lib/merge-files.js'),
397+ syspath = require('path'),
398+ paths,
399+ reqs;
400+
401+ // First we find all of the paths to our custom Javascript in the app
402+ // directory. We need to tell the function to ignore the "assets" directory
403+ // and the debug version of the modules file. I need to use
404+ // "syspath.join(process.cwd(), ...)" or else I have... "Error: Cannot find
405+ // module './app/config.js'" from node's internal module.js file.
406+ paths = merge.readdir(syspath.join(process.cwd(), './app'),
407+ [syspath.join(process.cwd(), './app/assets'), './app/modules-debug.js']);
408+
409+ // Get the name of all the YUI modules that our custom js files use directly.
410+ reqs = merge.loadRequires(paths);
411+
412+ // For some reason the loader does not get these requirements.
413+ // (Known issue #2)
414+ reqs.push('lang/datatype-date-format_en-US');
415+ reqs.push('parallel');
416+ reqs.push('app-transitions-native');
417+ reqs.push('gallery-markdown');
418+ reqs.push('loader-base');
419+
420+ // Get all of the YUI files and their dependencies, and combine them.
421+ merge.combine(merge.getYUIFiles(reqs),
422+ './app/assets/javascripts/generated/all-yui.js', true);
423+
424+ // Combine third party js libraries
425+ merge.combine([ './app/assets/javascripts/d3.v2.min.js',
426+ './app/assets/javascripts/reconnecting-websocket.js',
427+ './app/assets/javascripts/svg-layouts.js' ],
428+ './app/assets/javascripts/generated/all-third.js', true);
429+
430+ // Now we only need to generate the file that is used to tell YUI where all
431+ // the dependencies are. We either use a debug version or the production
432+ // version. The debug version is simply pointers to the individual files.
433+ // The production version aggregates all of the files together.
434+
435+ // Creating the combined file for the modules-debug.js and config.js files
436+ merge.combine([ './app/modules-debug.js', './app/config.js' ],
437+ './app/assets/javascripts/generated/all-app-debug.js', false);
438+
439+ // Creating the combined file for all our files. Note that this includes
440+ // app/modules.js in the rollup, which is why that file still needs exist.
441+ merge.combine(paths, './app/assets/javascripts/generated/all-app.js', true);
442+});
443\ No newline at end of file
444
445=== modified file 'grunt.js'
446--- grunt.js 2012-10-30 11:36:00 +0000
447+++ grunt.js 2012-11-09 20:53:21 +0000
448@@ -11,7 +11,7 @@
449
450 },
451 files: {
452- 'bin' : 'app/assets/images/*'
453+ 'bin': 'app/assets/images/*'
454 }
455 }
456 }
457
458=== added file 'lib/merge-files.js'
459--- lib/merge-files.js 1970-01-01 00:00:00 +0000
460+++ lib/merge-files.js 2012-11-09 20:53:21 +0000
461@@ -0,0 +1,137 @@
462+'use strict';
463+
464+// We need the yui name to be available in all modules (as a global variable).
465+// This only happens if we remove the 'var' keyword or add it to the "global"
466+// variable.
467+global.YUI = require('yui').YUI;
468+
469+YUI().use(['yui'], function(Y) {
470+ var fs = require('fs'),
471+ syspath = require('path'),
472+ compressor = require('node-minify');
473+
474+ function minify(file) {
475+ var execution = new compressor.minify(
476+ { type: 'uglifyjs',
477+ fileIn: file,
478+ fileOut: file,
479+ callback: function(err) {
480+ if (err) {
481+ console.log(err);
482+ }
483+ }});
484+ }
485+ exports.minify = minify;
486+
487+ // It combines the files defined by "files" into a single (compressed or not)
488+ // js file.
489+ function combine(files, outputFile, shouldMinify) {
490+ var str = [];
491+ Y.Array.each(files, function(file) {
492+ console.log('file -> ' + file);
493+ str.push(fs.readFileSync(file, 'utf8'));
494+ });
495+ fs.writeFileSync(outputFile, str.join('\n'), 'utf8');
496+ if (shouldMinify) {
497+ minify(outputFile);
498+ }
499+ }
500+ exports.combine = combine;
501+
502+ // It gets the name of all the files under 'path', recursively. It ignores
503+ // files and directories included in the "ignore" array. These will
504+ // typically be set to ignore our assets and our module file.
505+ function readdir(path, ignore) {
506+ var result = [], // These are the filenames we will return.
507+ dirs = [], // These are the directories into which we will recurse.
508+ files = fs.readdirSync(path);
509+
510+ Y.Array.each(files, function(value) {
511+ var fileName, file;
512+ fileName = path + '/' + value;
513+ file = fs.statSync(fileName);
514+ if (file.isFile()) {
515+ if (syspath.extname(fileName).toLowerCase() === '.js') {
516+ if (ignore && ignore.indexOf(fileName) >= 0) {
517+ console.log('SKIPPING FILE -> ' + fileName);
518+ } else {
519+ result.push(fileName);
520+ }
521+ }
522+ } else if (file.isDirectory()) {
523+ console.log('DIRECTORY -> ' + fileName);
524+ if (ignore && ignore.indexOf(fileName) >= 0) {
525+ console.log('SKIPPING DIRECTORY -> ' + fileName);
526+ } else {
527+ dirs.push(fileName);
528+ }
529+ }
530+ });
531+ // We have read all the filenames and all the directory names. Now
532+ // it is time to recurse into the directories that we have collected.
533+ Y.Array.each(dirs, function(directory) {
534+ // This is the best Javascript offers for appending one array to
535+ // another.
536+ result.push.apply(result, readdir(directory));
537+ });
538+ return result;
539+ }
540+ exports.readdir = readdir;
541+
542+ // It reads the YUI 'requires' attribute of all our custom js files
543+ // (as assembled by readdir) and returns the YUI modules on which we
544+ // directly depend.
545+ function loadRequires(paths) {
546+ var originalAdd, modules, yuiReqs;
547+ modules = {};
548+
549+ originalAdd = YUI.add;
550+ // This is a trick to get the 'requires' value from the module
551+ // definition.
552+ YUI.add = function(name, fn, version, details) {
553+ if (details && details.requires) {
554+ modules[name] = details.requires;
555+ }
556+ };
557+
558+ Y.Array.each(paths, function(path) {
559+ // It triggers the custom 'add' method above
560+ require(path);
561+ });
562+ YUI.add = originalAdd;
563+
564+ // Getting all the YUI dependencies that we need
565+ yuiReqs = [];
566+ Y.Object.each(modules, function(requires) {
567+ Y.Array.each(requires, function(value) {
568+ if (!modules[value]) {
569+ // This is not one of our modules but a yui one.
570+ if (yuiReqs.indexOf(value) < 0) {
571+ // avoid duplicates
572+ yuiReqs.push(value);
573+ }
574+ }
575+ });
576+ });
577+ return yuiReqs;
578+ }
579+ exports.loadRequires = loadRequires;
580+
581+ // Using the example http://yuilibrary.com/yui/docs/yui/loader-resolve.html
582+ // Given a list of direct YUI requirements, return the filenames of these
583+ // modules and their dependencies (indirect and direct).
584+ function getYUIFiles(reqs) {
585+ var loader, out;
586+ // The loader automatically handles following our dependencies.
587+ loader = new Y.Loader({
588+ // The base tells the loader where to look for the YUI files. We
589+ // look directly in the npm YUI package, but we could just as well look
590+ // in the symbolic link app/assets/javascripts/yui.
591+ base: './node_modules/yui/',
592+ ignoreRegistered: true,
593+ require: reqs});
594+ out = loader.resolve(true);
595+ return out.js;
596+ }
597+ exports.getYUIFiles = getYUIFiles;
598+});
599
600=== modified file 'lib/server.js'
601--- lib/server.js 2012-10-02 11:29:56 +0000
602+++ lib/server.js 2012-11-09 20:53:21 +0000
603@@ -5,6 +5,7 @@
604 fs = require('fs'),
605 path = require('path'),
606 config = require('../config').config.server,
607+ debugMode = (String(process.argv[2]).toLowerCase() === 'debug'),
608 public_dir = config.public_dir,
609 Templates = require('./templates.js'),
610 view = require('./view.js');
611@@ -46,8 +47,24 @@
612 });
613 });
614
615-server.get('/config.js', function(req, res) {
616- res.sendfile('app/config.js');
617+server.get('/assets/all-third.js', function(req, res) {
618+ res.sendfile('app/assets/javascripts/generated/all-third.js');
619+});
620+
621+server.get('/assets/modules.js', function(req, res) {
622+ if (debugMode) {
623+ res.sendfile('app/assets/javascripts/generated/all-app-debug.js');
624+ } else {
625+ res.sendfile('app/assets/javascripts/generated/all-app.js');
626+ }
627+});
628+
629+server.get('/assets/yui.js', function(req, res) {
630+ if (debugMode) {
631+ res.sendfile('app/assets/javascripts/yui/yui/yui-debug.js');
632+ } else {
633+ res.sendfile('app/assets/javascripts/generated/all-yui.js');
634+ }
635 });
636
637 server.get('*', function(req, res) {
638
639=== modified file 'package.json'
640--- package.json 2012-10-30 11:33:21 +0000
641+++ package.json 2012-11-09 20:53:21 +0000
642@@ -30,7 +30,8 @@
643 "graceful-fs": "1.1.x",
644 "rimraf": "2.0.x",
645 "grunt": ">=0.2.0",
646- "node-spritesheet": ">=0.2.3"
647+ "node-spritesheet": ">=0.2.3",
648+ "node-minify": "0.5.0"
649 },
650 "optionalDependencies": {}
651 }
652
653=== modified file 'test/index.html'
654--- test/index.html 2012-11-01 13:12:28 +0000
655+++ test/index.html 2012-11-09 20:53:21 +0000
656@@ -4,7 +4,7 @@
657 <meta charset="utf-8">
658 <link rel="stylesheet" href="assets/mocha.css">
659 <script src="../app/assets/javascripts/yui/yui/yui-debug.js"></script>
660- <script src="../app/modules.js"></script>
661+ <script src="../app/modules-debug.js"></script>
662 <script src="assets/chai.js"></script>
663 <script src="assets/mocha.js"></script>
664 <script src="utils.js"></script>

Subscribers

People subscribed via source and target branches