JSMin+ version 1.3

By crisp on Sunday 17 May 2009 00:57 - Comments (29)
Category: JSMin+, Views: 11.967

Version 1.3 of JSMin+ is available for download. This version fixes some issues with empty bodies in if/else and loop-constructs, and it fixes precedence issues in nested ternaries (which actually is a Narcissus bug which has been reported here). Furthermore it has some minification improvements.

Changelog:Known issues:
  • JScript conditional compilation support is (still) not complete yet
  • Performance can be improved
  • No support yet for variable-name minification
Note that we *do* take patches for any of a.m. issues!

The latest version is available on http://files.tweakers.net/jsminplus/jsminplus.zip

You can read more about JSMin+ in the announcement post.

Volgende: IPv6 validation (and caveats) 06-'09 IPv6 validation (and caveats)
Volgende: JSMin+ version 1.2 04-'09 JSMin+ version 1.2

Comments


By Tweakers user Blaise, Sunday 17 May 2009 15:56

Thanks for the fix for the hook:colon issue!

By Gilles, Monday 08 June 2009 08:26

Hey Crisp, kan JSMIN ook gebruikt worden voor CSS te minifyen?

By Tweakers user crisp, Monday 08 June 2009 09:39

Gilles: nee, maar CSS minifyen is redelijk simpel en kan met een paar reguliere expressies. Misschien wijdt ik daar nog wel een keer een blogpost aan :)

By Gilles, Monday 08 June 2009 14:17

Probleem (in mijn ogen) bij het minifyen van CSS is dat je relatieve paden naar images goed moet herschrijven. Waar ik wel nieuwsgierig naar ben is hoe jullie dan jullie JS minifyen. Jullie werken natuurlijk met een OTAP (of iig een O & P omgeving) voor tweakers.net, ik minify momenteel met minify (en doe dat runtime). Op zich natuurlijk slecht (first-time users krijgen een loadtime op hun kiezen), maar ik weet even geen betere manier. Heb jij inzichten hoe je dat beter zou kunnen doen als je bijv. maar 1 P omgeving hebt?

By Tweakers user crisp, Monday 08 June 2009 14:43

Probleem (in mijn ogen) bij het minifyen van CSS is dat je relatieve paden naar images goed moet herschrijven.
Omdat wij in CSS enkel relatieve paden gebruiken is dat simpelweg:

PHP:

1
<?php
$css = preg_replace('/url\(\s*([^\s)]*)\s*\)/''url(../$1)'$css);
?>
Waar ik wel nieuwsgierig naar ben is hoe jullie dan jullie JS minifyen.
Wij minifyen naar een 'min'-subdir op het moment dat wij een checkout doen op de acceptatie-omgeving. Wij doen dat trouwens heel simpel door te kijken naar de modify-timestamp van alle *.js en *.css files en die te vergelijken met de timestamp van de minified versie.

By Gilles, Wednesday 10 June 2009 09:44

Hmm. Stel het volgende scenario;
Je hebt in je <head> een aantal css & js files staan. Deze kun je natuurlijk minifyen tot 1 file. Natuurlijk verplaats je alle JS code naar onderen, zodat je site sneller laad. Tot zo ver is het allemaal wel uit te doktoren.

Maar wat als je dynamisch gegenereerde JS hebt? Bijv. op basis van bepaalde ID's event selectors koppelen. Deze kun je gewoon printen onderaan de pagina, maar je kunt ook deze nog een keer minifyen. Ik vraag me alleen af of dat nog voordelen bied.. "custom" (server parse-time) gegenereerde css/js minifyen....

By Tweakers user crisp, Wednesday 10 June 2009 10:04

Ik vraag me alleen af of dat nog voordelen bied..
Ik betwijfel het. Sowieso als je je HTML toch al met HTTP compressie verstuurd zal de serverside parsetime voor het minifyen denk ik niet meer opwegen tegen de paar bytes die je er mogelijk nog mee wint. Het voordeel van statische files minifyen is natuurlijk dat je die gewoon op je filesystem kan cachen zodat je dat maar 1 keer hoeft te doen.

Je kan beter kijken of je je javascript toch niet statisch kan maken, bijvoorbeeld door slimmer gebruik te maken van bepaalde selectors om events te koppelen :)

By Tony, Tuesday 30 June 2009 04:54

It would be great if you could move your defines into the class as constants or static variables. :)

By Tweakers user brechtvhb, Saturday 01 August 2009 22:43

Prachtig scriptje. Lokaal werkt alles naar wens, maar eens ik het oplaad naar mijn shared hosting en dan naar een pagina surf, krijg ik gewoon een leeg browserscherm te zien, als ik naar mijn HTML code wil kijken is dit ook leeg.

Ik heb ff proberen te debuggen maar gezien dit op mijn live omgeving was kon ik dit niet zo heel lang doen. Ik geraakte nog tot in de functie parseTree, maar daar liep het ergens verkeerd. Wat er verkeerd loopt kan ik niet zien in de logs vanwege de shared hosting. De omgeving waar de shared hosting op draait is: http://tfl.be/info.php .

Misschien heeft iemand anders je al over dit probleem verteld?

By Tweakers user Kiphaas7, Sunday 02 August 2009 19:58

Krijg met drupal6 in combinatie met deze module (die dankbaar gebruik maakt van JSMIN+) een foutmelding:


code:
1
Parse error: Illegal token in file '[inline]' on line 4377

Regel 4377:
JavaScript:
1
;&#65279;// $Id: drupal.js,v 1.41.2.3 2008/06/25 09:06:57 goba Exp $


(teken is omgezet naar een entity door jullie filter, maargoed :P )

De situatie:
Drupal aggregeert alle losse js bestanden tot 1 grote. vervolgens gaat deze module erover heen en probeert te minifyen. Met JSMIN krijg ik geen foutmelding, met JSMIN+ dus de bovenstaande.

Ik heb geen idee hoe dat rare teken er tussen is gekomen, maar dat staat toch enigzins los hiervan denk ik, aangezien JSMIN hier wel goed mee omgaat. Dit teken bevindt zich niet in het losse bestand (drupal.js), dus waarschijnlijk gaat het tijdens aggregeren fout.

Als je het geaggregeerde bestand wil hebben voor verder onderzoek, laat maar weten. :)

[Comment edited on Sunday 02 August 2009 20:02]


By Tweakers user crisp, Sunday 02 August 2009 20:43

Kiphaas7: Da's een niet gestripte BOM (Byte Order Mark), dus dat probleem wordt veroorzaakt door het samenvoegen van de bestanden.

JSMin doet itt JSMin+ geen echte parsing en dus ook geen validatie. Volgens mij zou dit in een browser ook een JS-error opleveren. Ik denk dat je dit dus beter als bug bij Drupal kan melden.

[Comment edited on Sunday 02 August 2009 20:44]


By Tweakers user Kiphaas7, Monday 03 August 2009 00:57

Bedankt voor de snelle reactie, en ik zal kijken of dit een probleem van de module is, of van drupal core zelf.

By Tweakers user crisp, Monday 03 August 2009 01:21

Mja, ik ken Drupal niet wat dat betreft. Ik ben wel gevlijd door het feit dat ze JSMin+ zijn gaan gebruiken (net als TYPO3 overigens, en ook het minify project wil JSMin vervangen door JSMin+) :)

Ik hoop eerdaags wat tijd te vinden om variabele minification te gaan inbouwen; dat zou JSMin+ de eerste PHP-based tool maken die dat kan :)

By joey, Thursday 12 November 2009 13:59

Hi,
I think i found a bug with JQuery $ symbol and functions :
myFunc = function()
{
/* some code */
}
$(document).ready(function() {
/* some code */
})

is transformed to :

myFunc = function(){} $(document).ready(function() {})

which leads to a parse error. Apparently you can't have a block closure immediatly followed by a $ symbol.
The minifier should add a semi-column to prevent the error :
myFunc = function(){}; $(document).ready(function() {})

Yep, it's a bit weird...

By Tweakers user crisp, Thursday 12 November 2009 14:18

nice catch; I'll look into it. Luckily we use sensible names for our functions :P

By Tweakers user crisp, Thursday 19 November 2009 01:24

joey: I can't reproduce this error with the latest version of JSMin+ - a semicolon is added, so there is no parsing error as far as I can see...

[Comment edited on Thursday 19 November 2009 01:24]


By Steve Clay, Wednesday 16 December 2009 18:53

A Minify user was running out of memory while using JSMin+. I recommended he try removing the singleton pattern from JSMinPlus::minify(). (simplest was to replace "static $instance;" with "$instance = false;").

I got no reply as to if this helped, but I thought I might pass it along in case you'd like to do some testing and see if re-using the instance might be causing some objects not to be GCed. Again, I didn't confirm that JSMin+ was the direct cause, and the user never replied to let me know if my suggestion helped.

BTW, there's word that Google Code may be banning projects based on Crockford
s JSMin (for dumb licensing issues), so unless I move the project I may just switch to JSMin+ as the default. I'll let you know if I do.

By Tweakers user crisp, Saturday 19 December 2009 23:27

Hi Steve,

Yeah, I read about the JSMin license issue - it's a bit pathetic...

As for the memory issues; it's something that I am aware of. I don;t think the problem is in the singlton pattern, but more in the fact that the whole javascript file is being tokenized before being handed off to the minification routine. PHP just isn't quite efficient memory-wise handling large (and deep) tree-like objects/arrays, and the default 64MB memorylimit can quickly get exhousted when minifying rather large javascriptfiles (such as complete libraries/frameworks).

I think the only solution to that would be to handle the minification in the JS parser itself, minifying completed block-scopes so we can throw away those tokens when done. It might even speed up the whole process a bit.

Unfortunately I don't have much time on my hands to try to fix that since it's a rather drastic change. It's on my radar though...

By Tweakers user t.coenraad, Monday 01 March 2010 18:36

Hoe kan ik dit gebruiken?
Ik doe een

PHP:

1
2
<?php
$bestand = file_get_contents('http://static.devvr.tk/wrts/wrts.js');
echo $minified = JSMinPlus::minify($bestand);
?>

maar dat werkt kennelijk niet...

Vreemd nu half?
zie: http://devvr.tk/jsminplus.php
input: http://static.devvr.tk/wrts/wrts.js

Wat doet die 'file'-parameter dan eigenlijk?

[Comment edited on Monday 01 March 2010 19:01]


By Richard, Thursday 11 March 2010 12:29

Je zegt wel dat JSmin+ de eerste PHP-based tool zou kunnen worden die variabelen kan "minifyen", maar dit is niet helemaal waar. :-)

http://web.2point1.com/20...-obfuscator-and-minifier/

Ook gebaseerd op een volledige PHP-based JavaScript-parser waardoor dit best wil ja. :-)


Overigens: leuk werk! Toevallig zat ik met bijna hetzelfde idee, Narcissus porten, ook een leuk project. Ik ga er eens mee stoeien, als ik problemen tegenkom hoor je het wel. ;)

By Tweakers user Kiphaas7, Tuesday 13 April 2010 18:33

Aangezien ik zelf problemen had met BOM's, hier dan maar de oplossing voor drupal :P.


PHP:

1
<?php
$file = str_replace(pack("CCC",0xef,0xbb,0xbf), ""file_get_contents(file_directory_path() . $aggregated_file_name));
?>

By Tweakers user Wim Leers, Sunday 31 October 2010 18:12

There are memory consumption issues with JSMIN+: http://drupal.org/node/940342. I saw this happening too:

code:
1
2
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 17159 bytes) in 
/bleh/blah/modules/javascript_aggregator/jsminplus.php on line 1680


And this is happening on a site that has an average PHP memory consumption of between 5 and 10 MB per page, while the memory limit is set to 64 MB as you can see. So clearly, JSMIN+ is using *a lot* of memory.

This is likely happening because Drupal first aggregates JS files and JSMIN+ is then processing very large JS files, while it is not releasing memory properly. If it's not that, I don't know.

By Tweakers user crisp, Sunday 31 October 2010 23:58

It's actually PHP that consumes a lot of memory for array-like structures and the fact that JSMin+ first builds a full parse-tree before doing minification...

By Tweakers user Wim Leers, Monday 01 November 2010 21:30

I understand. Isn't there a way to work around this though?

By Tweakers user crisp, Monday 01 November 2010 22:39

Wim Leers wrote on Monday 01 November 2010 @ 21:30:
I understand. Isn't there a way to work around this though?
The only real solution I can think of is doing partial minification for each scoped block, but that means that the minifier should be integrated into the parser itself. Maybe there are other means to reduce the memory-footprint, but that would probably only have a marginal effect.

I hope I can find some time in near future to look into this...

By Tweakers user Kiphaas7, Wednesday 17 November 2010 05:42

Would be awesome to reduce memory footprint. Most shared hosting sites die with that kind of memory consumption...

By Samuel Krieg, Friday 19 November 2010 15:52

Hi,

I just downloaded the JSMin+ script and it is great! Thanks for your very useful work!

However I think it's a bad idea to catch exceptions (I'm talking about the min() function).

Let me explain:
I'm using your script over a command line and I can't see when an execption occurs: the error message goes to output instead of stderr. At the end the supposed minified file contains the error string.

There is no way to know when things went bad until I notice it browsing the site manually.

I think you should not catch the exception but just let it fly (to infinity and beyond!).

By Tweakers user Spider.007, Monday 21 March 2011 14:21

People having issues with memory_limits when compressing aggregated javascripts should move to a different usage of JSmin+ to work around this PHP issue.

Just minify each file separately and merge them afterwards, instead of beforehand. This will enable PHP to do proper GC

By mikeytown2, Sunday 03 April 2011 07:58

I noticed that jsmin+ eats LOTS of ram when compressing a file that is already compressed. Example file that it has trouble with: http://drupalcode.org/pro...2256:/misc/jquery.form.js

This file doesn't have the same issues: http://www.malsup.com/jquery/form/jquery.form.208.js

Thread with a bunch of info on this http://drupal.org/node/1107010 Long story short I blacklist all minified and packed js files.

Comments are closed