JSMin+ version 1.3

By crisp on Sunday 17 May 2009 00:57
Category: JSMin+, Views: 4126

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
Volgende: JSMin+ version 1.2 04-'09

Comments


By T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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 T.net 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. ;)

Comment form
(required)
(required, but will not be displayed)
(optional)

Please enter the code from the image below: