douglascrockford / jsmin Goto Github PK
View Code? Open in Web Editor NEWJavaScript Minification Filter
Home Page: http://javascript.crockford.com/jsmin.html
JavaScript Minification Filter
Home Page: http://javascript.crockford.com/jsmin.html
JSMin, The JavaScript Minifier Douglas Crockford [email protected] 2013-02-25 JSMin is a filter that removes comments and unnecessary whitespace from JavaScript files. It typically reduces filesize by half, resulting in faster downloads. It also encourages a more expressive programming style because it eliminates the download cost of clean, literate self-documentation. What JSMin Does JSMin is a filter that omits or modifies some characters. This does not change the behavior of the program that it is minifying. The result may be harder to debug. It will definitely be harder to read. JSMin first replaces carriage returns ('\r') with linefeeds ('\n'). It replaces all other control characters (including tab) with spaces. It replaces comments in the // form with linefeeds. It replaces comments in the /* */ form with spaces. All runs of spaces are replaced with a single space. All runs of linefeeds are replaced with a single linefeed. It omits spaces except when a space is preceded and followed by a non-ASCII character or by an ASCII letter or digit, or by one of these characters: \ $ _ It is more conservative in omitting linefeeds, because linefeeds are sometimes treated as semicolons. A linefeed is not omitted if it precedes a non-ASCII character or an ASCII letter or digit or one of these characters: \ $ _ { [ ( + - and if it follows a non-ASCII character or an ASCII letter or digit or one of these characters: \ $ _ } ] ) + - " ' No other characters are omitted or modified. JSMin knows to not modify quoted strings and regular expression literals. JSMin does not obfuscate, but it does uglify. Before: // is.js // (c) 2001 Douglas Crockford // 2001 June 3 // is // The -is- object is used to identify the browser. Every browser edition // identifies itself, but there is no standard way of doing it, and some of // the identification is deceptive. This is because the authors of web // browsers are liars. For example, Microsoft's IE browsers claim to be // Mozilla 4. Netscape 6 claims to be version 5. // Warning: Do not use this awful, awful code or any other thing like it. // Seriously. var is = { ie: navigator.appName == 'Microsoft Internet Explorer', java: navigator.javaEnabled(), ns: navigator.appName == 'Netscape', ua: navigator.userAgent.toLowerCase(), version: parseFloat(navigator.appVersion.substr(21)) || parseFloat(navigator.appVersion), win: navigator.platform == 'Win32' } is.mac = is.ua.indexOf('mac') >= 0; if (is.ua.indexOf('opera') >= 0) { is.ie = is.ns = false; is.opera = true; } if (is.ua.indexOf('gecko') >= 0) { is.ie = is.ns = false; is.gecko = true; } After: var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'} is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;} if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;} Character Set JSMin requires, but does not verify, that the character set encoding of the input program is either ASCII or UTF-8. It might not work correctly with other encodings. Caution Be sure to retain your original source file. JSMin is a one-way trip: Once done, it cannot be undone. Do not put raw control characters inside a quoted string. That is an extremely bad practice. Use \x<i>hh</i> notation instead. JSMin will replace control characters with spaces or linefeeds. Command Line Options Optional parameters will be listed at the beginning of the output as comments. This is a convenient way of replacing copyright messages and other documentation. Example: jsmin <jslint.js >jslint.min.js "(c)2001 Douglas Crockford" Errors JSMin can produce three error messages to stderr: Unterminated comment. Unterminated string constant. Unterminated regular expression. It ignores all other errors that may be present in your source program. Use of JSLint is strongly recommended. Copyright 2001 Douglas Crockford. All Rights Reserved Wrrrldwide.
I needed a quick and dirty implementation to clean .json files from comments and created a streambuf based version of jsmin. The code is not nice nor clean and it is not very well tested as we are not using it in production but maybe someone will find the implementation useful as a starting point.
We're experiencing a new issue installing jsmin as a dependency for azure-cli:
#11 130.2 Collecting jsmin==2.2.2
#11 130.2 Downloading jsmin-2.2.2.tar.gz (12 kB)
#11 130.4 ERROR: Command errored out with exit status 1:
#11 130.4 command: /usr/local/bin/python -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-poyif1fk/jsmin_cbd1c10d3c314dd28f81bc98eb1cc7c2/setup.py'"'"'; __file__='"'"'/tmp/pip-install-poyif1fk/jsmin_cbd1c10d3c314dd28f81bc98eb1cc7c2/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-i4jrcuyg
#11 130.4 cwd: /tmp/pip-install-poyif1fk/jsmin_cbd1c10d3c314dd28f81bc98eb1cc7c2/
#11 130.4 Complete output (1 lines):
#11 130.4 error in jsmin setup command: use_2to3 is invalid.
#11 130.4 ----------------------------------------
I've tried explicitly installing 2to3
and explicitly invoking pip and python with 3, but no dice. Any help would be appreciated!
Found this today when trying to minify the d3.js library (http://d3js.org/). Here's one of the two lines in question where the author is using the unary operator to convert a boolean value into a one or zero to be added to another value:
function arc(r, p, a) {
return "A" + r + "," + r + " 0 " + +(a > Math.PI) + ",1 " + p;
}
JSMin converts this code to:
function arc(r,p,a){return"A"+r+","+r+" 0 "++(a>Math.PI)+",1 "+p;}
Which causes the Javascript syntax error: "SyntaxError: invalid increment operand"
Perhaps not recommended (I see that JSLint complains about the confusing plusses), but possible to make JSMin handle these better? (leave the space?)
Thanks
Hi,
We are using the PHP version of your script (https://github.com/rgrove/jsmin-php/) on our open-source project, the problem is Debian team doesn't accept our project because the licence of JSMin is void because of the sentence "The Software shall be used for Good, not Evil."
This is a modification of the license text which is not allowed, thus JSMin is actually not OpenSource.
Is it possible you correct that ?
http://www.opensource.org/licenses/mit-license.php
The link to "jsmin.exe: JSMin prebuilt for MS-DOS" ( http://www.https//www.crockford.com/javascript/jsmin.zip ) on https://www.crockford.com/jsmin.html is broken
A string such as this:
var subUrl = prompt("hi"),
myVar = `https://example.com/${subUrl}/moreurlstuff`
console.log(myVar)
Is turned into something like this:
var subUrl=prompt("hi"),myVar=`https:console.log(myVar)
In other words it causes a syntax error (unterminated backtick string starting at char 31. The double forward slash in the original string is treated as a single-line comment). For other people having this exact issue, a temporary workaround was to change the code to this untill jsMin can handle backtick strings, but I can't say for sure if this would cause other problems as I have yet to try it in prod with more compicated strings.
var subUrl = prompt("hi"),
myVar = `https:/${"/"}example.com/${subUrl}/moreurlstuff`
console.log(myVar)
Hi,
We are currently experiencing problems with using JSMin. The javascript code that causes us problems is this:
var pattern=/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/;
The usage is this:
$jsmin_php = JSMin::minify(file_get_contents("error.js"));
echo $jsmin_php;
The error thrown is this:
Fatal error: Uncaught exception 'JSMin_UnterminatedStringException' with message 'Unterminated String: ''+/=?^`{|}~-]+)|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\[\x01-\x09\x0b\x0c\x0e-\x7f])")@(?:(?:a-z0-9?.)+a-z0-9?|[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]_[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\[\x01-\x09\x0b\x0c\x0e-\x7f])+)])$/;'' in /home/kasper/kaspergrubbe.dk/htdocs/JSMin.php:151 Stack trace: #0 /home/kasper/kaspergrubbe.dk/htdocs/JSMin.php(123): JSMin->action(1) #1 /home/kasper/kaspergrubbe.dk/htdocs/JSMin.php(80): JSMin->min() #2 /home/kasper/kaspergrubbe.dk/htdocs/JSMin.php(53): JSMin::minify('var pattern=/^(...') #3 {main} thrown in /home/kasper/kaspergrubbe.dk/htdocs/JSMin.php on line 151
In the majority of cases any whitespace following the closing curly brace can be removed but since the introduction of template literals this is no longer a safe assumption. Spaces following interpolated values in a template literal need to be preserved. For example,
Unexpected ${token} encountered
gets incorrectly minified to Unexpected ${token}encountered
so when the token is 'comma' the minified version outputs 'Unexpected commaencountered'.
JSMin should preserve important comments e.g. copyright or license info.
Otherwise webmasters could unknowingly be infringing on copyright when including 3rd party code.
YUI compressor gets around this by checking for important comments e.g:
/*!
Something very important
*/
See more about this issue:
http://zoompf.com/blog/2009/11/jsmin-important-comments-and-copyright-violations
And a fork of JSmin that has solved this problem:
http://fmarcia.info/jsmin/test.html
I'm using django-pipeline with the JS Compressor set to JSMinCompressor.
This is wrong and leads to an error..
The code which it minifies wrongly is here:
https://github.com/metajack/strophejs/blob/master/src/core.js#L732
For some of the files I merge, and then minify as well as pack/compress, I had a friend note that (as an example) JQuery requires there license header be left in for commercial uses of it.
/*! jQuery v1.7 jquery.com | jquery.org/license */
I don't know if its widely supported to ignore this type of comment or not, or subsequently put it back in. Just thought I'd toss it out there since currently this script removes all comments.
Given this if statement, the following snippets aren't seen as regex literals by JSMin:
if (theB == '/' && (theA == '(' || theA == ',' || theA == '=' ||
theA == ':' || theA == '[' || theA == '!' ||
theA == '&' || theA == '|' || theA == '?' ||
theA == '{' || theA == '}' || theA == ';' ||
theA == '\n')) {
Snippet #1:
var ex = +/w$/.test(resizing),
ey = +/^n/.test(resizing);
In this case, when "theB" == "/", "theA" == "+" which isn't one of the conditions defined.
Snippet #2:
return /[",\n]/.test(text)
? "\"" + text.replace(/\"/g, "\"\"") + "\""
: text;
In this case, "theA" == " " because of the return.
Consider this legal JS (found in highcharts 4.1.4, already apparently minified by Closure Compiler):
{dSetter:function(a,b,c){a&&a.join&&(a=a.join(" "));/(NaN| {2}|^$)/.test(a)&&(a="M 0 0");c.setAttribute(b,a);this[b]=a}}
JSMin outputs:
{dSetter:function(a,b,c){a&&a.join&&(a=a.join(" "));/(NaN|{2}|^$)/.test(a)&&(a="M 0 0");c.setAttribute(b,a);this[b]=a}}
The RegExp literal has been modified (| {
--> |{
, which also happens to be invalid syntax).
Seems to be distinct from #11 because testing across history indicates the problem was only introduced by cec896f (which is newer than #11).
๐ It looks like right now, there is no release tagged on specific commit for the project. Thanks!
Hey there,
I'm using JSMin for a few minutes and have a problem:
If my Javascript Code contains a string like
"I am a string\n"
JSMin places a Linefeed in the output instead of just leaving the \n in the String. So it is not replacing it, it outputs it which causes the line feed, which itself causes a Javascript-Error in the Browser "not terminating string literal"
subj
Currently when using a litteral in a string, for example in a query selector, the spaces are removed after the }.
document.querySelector(`${id} .read-more-elip`).classList.toggle('d-none');
complies to
document.querySelector(`${id}.read-more-elip`).classList.toggle('d-none');
which breaks the querySelector.
With the latest update to JSMin I was able to get it to minify the d3.js library correctly, thanks again for that. So I decided to do a little work on the PHP port of JSMin to get it up to date with the latest release, however I ran into an inconsistency that I thought I would point out.
Once again, the d3 author(s) are doing something that JSLint doesn't recommend:
// Compute the angular scale factor: from value to radians.
var k = ((typeof endAngle === "function"
? endAngle.apply(this, arguments)
: endAngle) - startAngle)
/ d3.sum(values);
Running JSMin on just this snippet will cause it to spit up the "Unterminated Regular Expression literal." due to the division operator being on its own line. Which made me question why/how it's getting through the whole d3.js file without encountering the same error. It appears to be because the next line in the file is a comment:
// Compute the angular scale factor: from value to radians.
var k = ((typeof endAngle === "function"
? endAngle.apply(this, arguments)
: endAngle) - startAngle)
/ d3.sum(values);
// Optionally sort the data.
I believe that JSMin sees that first character of the comment line as the ending regex token, so doesn't complain in this situation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.