GithubHelp home page GithubHelp logo

jsmin's Introduction

Who is this Tikitu guy anyway?

As far as things that end up in git go, mostly it's the Swift I write for my day job. Outside of version control I play mandola and take macro photographs of insects. I have a long-untouched homepage and as of late 2022 I'm on Mastodon as @[email protected].

jsmin's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jsmin's Issues

Double slash in URL in HTML is treated as JS comment.

The following code isn't being minified correctly. This:

$("#some_element").html(`
<div class="menu">
    <!-- make sure to use right iso 3166-2 code.
    See also http://example.com/some-url.html -->
    <div class="item">item 1</div>
    <!--
    <div class="item">item 2</div>
    -->
    <div class="item">item 3</div>
</div>
`);

becomes this:

$("#some_element").html(`<div class="menu"><!--
make sure to use right iso 3166-2 code.See also http:<div class="item">item 1</div><!--<div class="item">item 2</div>--><div class="item">item 3</div></div>`);

Apparently, the double slash in the URI inside the HTML comment is being treated as an opening JS comment tag. Thus, this line is dropped by minification together with the closing HTML comment tag.

This in turn creates an opening HTML comment tag with no (intentionally) related closing tag, in this case putting the first item inside of a HTML comment instead of into the menu. This can get arbitrarily worse depending on the HTML comments in the document - if there is no other comment after this, the whole rest of the document will disappear inside of a comment.

This happens with jsmin 2.2.1 on Python 2 as well as Python 3.

ModuleNotFoundError: No module named 'jsmin'

Traceback (most recent call last):
File "./server.py", line 13, in
from jsmin import jsmin
ModuleNotFoundError: No module named 'jsmin'

error comes from running a python 3 script.

ES6 Compatibility?

According to the readme:

jsmin makes no attempt to be compatible with ECMAScript 6 / ES.next / Harmony

However, you also include:

If you're using jsmin on ES6 code, though, you might find the quote_chars parameter useful:
from jsmin import jsmin with open('myfile.js') as js_file: minified = jsmin(js_file.read(), quote_chars="'\"")

I'm a bit puzzled. Can jsmin handle ES6 by using the referenced quote_chars parameter? Or is it always dangerous to use jsmin on any ES6 code?

I tested it out by including a few features from ES6(arrow functions and Promises) in the javascript file I'm minifying with jsmin.

Everything runs correctly. Could we enhance the readme.md to clarify what is wrong with using jsmin on ES6?

Thanks!

Valid regexp breaks minification

The following syntactically correct code breaks the minifier:

var re = /^(([^<>()[\]{}'^?\\.,!|//#%*-+=&;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;

Internal bracket counts get messed up and code breaks about 2 ( symbols for the end.

The code is valid syntactically.

In the README, please add a link to the documentation

What exactly does jsmin() return? A string, or a list of strings, or a dict, or what?
How exactly do we use the quote_chars() method? What exactly do quote chars do?
How can we change or select the comment characters? Hash # doesn't seem to be recognized.
Where is the documentation? Thank you

Division in return statement hangs

A division operator in a return statement results in an infinite loop in regex_literal.

Minimal test case:

echo 'return x / 1;' > division_hang.js
python -m jsmin division_hang.js

Regex literals issue

>>> jsmin.jsmin('function foo(){/https?:\/\//.test(a)}')
'function foo(){/https?:\\/\\'

...breakage. Still haven't figured out what it's caused by.

requirements.txt version compatibility issues

I found some installing error on some of the designated module:

  • psycopg2-binary
  • pil
  • jsim

would you please to change the requirements.txt without designating the version number of all the module?

best regards

Unable to install with setuptools 58 - "error in jsmin setup command: use_2to3 is invalid."

When trying to install jsmin 2.2.2 from a requirements.txt file using a python environment with setuptools 58 the following failure is happening for us on centos:

Collecting jsmin==2.2.2
  Downloading jsmin-2.2.2.tar.gz (12 kB)
    ERROR: Command errored out with exit status 1:
     command: /opt/pact-virtual-environment/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-p9xovusy/jsmin_25a28adbd1db497daf15f6eb22893f8a/setup.py'"'"'; __file__='"'"'/tmp/pip-install-p9xovusy/jsmin_25a28adbd1db497daf15f6eb22893f8a/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-8_iwpxdk
         cwd: /tmp/pip-install-p9xovusy/jsmin_25a28adbd1db497daf15f6eb22893f8a/
    Complete output (1 lines):
    error in jsmin setup command: use_2to3 is invalid.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/17/73/615d1267a82ed26cd7c124108c3c61169d8e40c36d393883eaee3a561852/jsmin-2.2.2.tar.gz#sha256=b6df99b2cd1c75d9d342e4335b535789b8da9107ec748212706ef7bbe5c2553b (from https://pypi.org/simple/jsmin/). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
ERROR: Could not find a version that satisfies the requirement jsmin==2.2.2 (from versions: 2.0, 2.0.1, 2.0.2, 2.0.2.post1, 2.0.3, 2.0.5, 2.0.6, 2.0.7, 2.0.8, 2.0.9, 2.0.10, 2.0.11, 2.1.0, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.2.0, 2.2.1, 2.2.2)
ERROR: No matching distribution found for jsmin==2.2.2

This looks to be happening because setuptools 58 added a breaking change to remove use_2to3 support: https://setuptools.readthedocs.io/en/latest/history.html#v58-0-0

#2086: Removed support for 2to3 during builds. Projects should port to a unified codebase or pin to an older version of Setuptools using PEP 518 build-requires.

pypa/setuptools#2769

It would be awesome if this could be updated, but until then, if you're also getting this issue, try setuptools 57.5.0.

re delimiters // and if make broken js.

This code from Django 1.8.5 admin (yes, no semicolon, but still valid js if I'm not mistaken).

var re = /\d{4}/
if (re.test(year.toString()) && month >= 1 && month <= 12) {
    DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
}

becomes

var re=/\d{4}/if(re.test(year.toString())&&month>=1&&month<=12) ...

And it ends up with Firefox error - SyntaxError: invalid regular expression flag f.

Tried jsmin==2.1.5

Prevent spaces being removed from templates (handlebars, underscore) and multiline strings

In following situation, using an underscore template, the minimizing process removes spaces that are necessary for the layout:

let _row = `
    <tr>
        <th>Income <%= current_year %> USD</th>
        <th>Tax Rate %</th>
    </tr>
`

The code gets shortened to:

let _row=<tr><th>Income<%=current_year%>USD</th><th>Tax Rate%</th></tr>

Resulting in output like:

Income2017UDS Tax Rate%

I there a way to prevent this behaviour?

Continuous fuzzing by way of OSS-Fuzz

Hi,

I was wondering if you would like to integrate continuous fuzzing by way of OSS-Fuzz? In this PR google/oss-fuzz#8077 I do exactly that, namely created the necessary logic from an OSS-Fuzz perspective.

Essentially, OSS-Fuzz is a free service run by Google that performs continuous fuzzing of important open source projects. The only expectation of integrating into OSS-Fuzz is that bugs will be fixed. This is not a "hard" requirement in that no one enforces this and the main point is if bugs are not fixed then it is a waste of resources to run the fuzzers, which we would like to avoid.

If you would like to integrate, the only thing I need is as list of email(s) that will get access to the data produced by OSS-Fuzz, such as bug reports, coverage reports and more stats. Notice the emails affiliated with the project will be public in the OSS-Fuzz repo, as they will be part of a configuration file.

In the event your unfamiliar with fuzzing, then it's a technique used to automate test case generation. It's been used frequently over the last decade to analyse projects in memory unsafe languages to catch memory corruption issues, but is now moving into supporting memory safe languages (hence this PR). In the Python world, the expected bugs to be found at the moment is uncaught exceptions. I'm happy to answer any questions you may have!

Premature end of statement

jsmin is choking on this line here https://github.com/Automattic/jetpack/blob/d00226a061198feb72750b1bd7b980c9d9311c91/_inc/spin.js#L23 closing the statement prematurely. Here's a minimal test to reproduce for now:

    def test_empty_declaration_with_comment(self):
        original = '''
            var a /* this is a comment */
            a = 1
        '''
        self.assertMinified(original, 'var a;a=1')
AssertionError: 
got: 'var a a=1'
exp: 'var a;a=1'

Will follow up with more thoughts, findings and maybe a patch.

jsmin 2.1.3: SyntaxError: unterminated regular expression literal

Hi,

when minifying https://github.com/scottjehl/Respond/blob/master/src/respond.js I get an error:

SyntaxError: unterminated regular expression literal
data:,/* EXPRESSION EVALUATED USING THE FIREBUG COMMAND LINE: /%0A(function(w)%7B%22use%20strict%22%3B%20var%20respond%3D%7B%7D%3Bw.respond%3Drespond%3B%20respond.update%3Dfunction()%7B%7D%3B%20var%20requestQueue%3D%5B%5D%2CxmlHttp%3D(function()%7Bvar%20xmlhttpmethod%3Dfalse%3Btry%7Bxmlhttpmethod%3Dnew%20w.XMLHttpRequest()%3B%7D%0Acatch(e)%7Bxmlhttpmethod%3Dnew%20w.ActiveXObject(%22Microsoft.XMLHTTP%22)%3B%7D%0Areturn%20function()%7Breturn%20xmlhttpmethod%3B%7D%3B%7D)()%2C%20ajax%3Dfunction(url%2Ccallback)%7Bvar%20req%3DxmlHttp()%3Bif(!req)%7Breturn%3B%7D%0Areq.open(%22GET%22%2Curl%2Ctrue)%3Breq.onreadystatechange%3Dfunction()%7Bif(req.readyState!%3D%3D4%7C%7Creq.status!%3D%3D200%26%26req.status!%3D%3D304)%7Breturn%3B%7D%0Acallback(req.responseText)%3B%7D%3Bif(req.readyState%3D%3D%3D4)%7Breturn%3B%7D%0Areq.send(null)%3B%7D%2CisUnsupportedMediaQuery%3Dfunction(query)%7Breturn%20query.replace(respond.regex.minmaxwh%2C'').match(respond.regex.other)%3B%7D%3B%20respond.ajax%3Dajax%3Brespond.queue%3DrequestQueue%3Brespond.unsupportedmq%3DisUnsupportedMediaQuery%3Brespond.regex%3D%7Bmedia%3A%2F%40media%5B%5E%5C%7B%5D%2B%5C%7B(%5B%5E%5C%7B%5C%7D%5D%5C%7B%5B%5E%5C%7D%5C%7B%5D_%5C%7D)%2B%2Fgi%2Ckeyframes%3A%2F%40(%3F%3A%5C-(%3F%3Ao%7Cmoz%7Cwebkit)%5C-)%3Fkeyframes%5B%5E%5C%7B%5D%2B%5C%7B(%3F%3A%5B%5E%5C%7B%5C%7D%5D_%5C%7B%5B%5E%5C%7D%5C%7B%5D_%5C%7D)%2B%5B%5E%5C%7D%5D_%5C%7D%2Fgi%2Ccomments%3A%2F%5C%2F%5C_%5B%5E_%5D_%5C_%2B(%5B%5E%2F%5D%5B%5E_%5D_%5C_%2B)%5C%0Aurls%3A%2F(url%5C()%5B'%22%5D%3F(%5B%5E%5C%2F%5C)'%22%5D%5B%5E%3A%5C)'%22%5D%2B)%5B'%22%5D%3F(%5C))%2Fg%2CfindStyles%3A%2F%40media%20(%5B%5E%5C%7B%5D%2B)%5C%7B(%5B%5CS%5Cs%5D%2B%3F)%24%2F%2Conly%3A%2F(only%5Cs%2B)%3F(%5Ba-zA-Z%5D%2B)%5Cs%3F%2F%2Cminw%3A%2F%5C(%5Cs_min%5C-width%5Cs_%3A%5Cs_(%5Cs_%5B0-9%5C.%5D%2B)(px%7Cem)%5Cs_%5C)%2F%2Cmaxw%3A%2F%5C(%5Cs_max%5C-width%5Cs_%3A%5Cs_(%5Cs_%5B0-9%5C.%5D%2B)(px%7Cem)%5Cs_%5C)%2F%2Cminmaxwh%3A%2F%5C(%5Cs_m(in%7Cax)%5C-(height%7Cwidth)%5Cs_%3A%5Cs_(%5Cs_%5B0-9%5C.%5D%2B)(px%7Cem)%5Cs_%5C)%2Fgi%2Cother%3A%2F%5C(%5B%5E%5C)%5D_%5C)%2Fg%7D%3B%20respond.mediaQueriesSupported%3Dw.matchMedia%26%26w.matchMedia(%22only%20all%22)!%3D%3Dnull%26%26w.matchMedia(%22only%20all%22).matches%3B%20if(respond.mediaQueriesSupported)%7Breturn%3B%7D%20%0Avar%20doc%3Dw.document%2CdocElem%3Ddoc.documentElement%2Cmediastyles%3D%5B%5D%2Crules%3D%5B%5D%2CappendedEls%3D%5B%5D%2CparsedSheets%3D%7B%7D%2CresizeThrottle%3D30%2Chead%3Ddoc.getElementsByTagName(%22head%22)%5B0%5D%7C%7CdocElem%2Cbase%3Ddoc.getElementsByTagName(%22base%22)%5B0%5D%2Clinks%3Dhead.getElementsByTagName(%22link%22)%2ClastCall%2CresizeDefer%2C%20eminpx%2C%20getEmValue%3Dfunction()%7Bvar%20ret%2Cdiv%3Ddoc.createElement('div')%2Cbody%3Ddoc.body%2CoriginalHTMLFontSize%3DdocElem.style.fontSize%2CoriginalBodyFontSize%3Dbody%26%26body.style.fontSize%2CfakeUsed%3Dfalse%3Bdiv.style.cssText%3D%22position%3Aabsolute%3Bfont-size%3A1em%3Bwidth%3A1em%22%3Bif(!body)%7Bbody%3DfakeUsed%3Ddoc.createElement(%22body%22)%3Bbody.style.background%3D%22none%22%3B%7D%0A%20%0AdocElem.style.fontSize%3D%22100%25%22%3Bbody.style.fontSize%3D%22100%25%22%3Bbody.appendChild(div)%3Bif(fakeUsed)%7BdocElem.insertBefore(body%2CdocElem.firstChild)%3B%7D%0Aret%3Ddiv.offsetWidth%3Bif(fakeUsed)%7BdocElem.removeChild(body)%3B%7D%0Aelse%7Bbody.removeChild(div)%3B%7D%20%0AdocElem.style.fontSize%3DoriginalHTMLFontSize%3Bif(originalBodyFontSize)%7Bbody.style.fontSize%3DoriginalBodyFontSize%3B%7D%20%0Aret%3Deminpx%3DparseFloat(ret)%3Breturn%20ret%3B%7D%2C%20applyMedia%3Dfunction(fromResize)%7Bvar%20name%3D%22clientWidth%22%2CdocElemProp%3DdocElem%5Bname%5D%2CcurrWidth%3Ddoc.compatMode%3D%3D%3D%22CSS1Compat%22%26%26docElemProp%7C%7Cdoc.body%5Bname%5D%7C%7CdocElemProp%2CstyleBlocks%3D%7B%7D%2ClastLink%3Dlinks%5Blinks.length-1%5D%2Cnow%3D(new%20Date()).getTime()%3B%20if(fromResize%26%26lastCall%26%26now-lastCall%3CresizeThrottle)%7Bw.clearTimeout(resizeDefer)%3BresizeDefer%3Dw.setTimeout(applyMedia%2CresizeThrottle)%3Breturn%3B%7D%0Aelse%7BlastCall%3Dnow%3B%7D%0Afor(var%20i%20in%20mediastyles)%7Bif(mediastyles.hasOwnProperty(i))%7Bvar%20thisstyle%3Dmediastyles%5Bi%5D%2Cmin%3Dthisstyle.minw%2Cmax%3Dthisstyle.maxw%2Cminnull%3Dmin%3D%3D%3Dnull%2Cmaxnull%3Dmax%3D%3D%3Dnull%2Cem%3D%22em%22%3Bif(!!min)%7Bmin%3DparseFloat(min)(min.indexOf(em)%3E-1%3F(eminpx%7C%7CgetEmValue())%3A1)%3B%7D%0Aif(!!max)%7Bmax%3DparseFloat(max)(max.indexOf(em)%3E-1%3F(eminpx%7C%7CgetEmValue())%3A1)%3B%7D%20%0Aif(!thisstyle.hasquery%7C%7C(!minnull%7C%7C!maxnull)%26%26(minnull%7C%7CcurrWidth%3E%3Dmin)%26%26(maxnull%7C%7CcurrWidth%3C%3Dmax))%7Bif(!styleBlocks%5Bthisstyle.media%5D)%7BstyleBlocks%5Bthisstyle.media%5D%3D%5B%5D%3B%7D%0AstyleBlocks%5Bthisstyle.media%5D.push(rules%5Bthisstyle.rules%5D)%3B%7D%7D%7D%0Afor(var%20j%20in%20appendedEls)%7Bif(appendedEls.hasOwnProperty(j))%7Bif(appendedEls%5Bj%5D%26%26appendedEls%5Bj%5D.parentNode%3D%3D%3Dhead)%7Bhead.removeChild(appendedEls%5Bj%5D)%3B%7D%7D%7D%0AappendedEls.length%3D0%3B%20for(var%20k%20in%20styleBlocks)%7Bif(styleBlocks.hasOwnProperty(k))%7Bvar%20ss%3Ddoc.createElement(%22style%22)%2Ccss%3DstyleBlocks%5Bk%5D.join(%22%5Cn%22)%3Bss.type%3D%22text%2Fcss%22%3Bss.media%3Dk%3Bhead.insertBefore(ss%2ClastLink.nextSibling)%3Bif(ss.styleSheet)%7Bss.styleSheet.cssText%3Dcss%3B%7D%0Aelse%7Bss.appendChild(doc.createTextNode(css))%3B%7D%20%0AappendedEls.push(ss)%3B%7D%7D%7D%2C%20translate%3Dfunction(styles%2Chref%2Cmedia)%7Bvar%20qs%3Dstyles.replace(respond.regex.comments%2C'').replace(respond.regex.keyframes%2C'').match(respond.regex.media)%2Cql%3Dqs%26%26qs.length%7C%7C0%3B%20href%3Dhref.substring(0%2Chref.lastIndexOf(%22%2F%22))%3Bvar%20repUrls%3Dfunction(css)%7Breturn%20css.replace(respond.regex.urls%2C%22%241%22%2Bhref%2B%22%242%243%22)%3B%7D%2CuseMedia%3D!ql%26%26media%3B%20if(href.length)%7Bhref%2B%3D%22%2F%22%3B%7D%0A%0A%0Aif(useMedia)%7Bql%3D1%3B%7D%0Afor(var%20i%3D0%3Bi%3Cql%3Bi%2B%2B)%7Bvar%20fullq%2Cthisq%2Ceachq%2Ceql%3B%20if(useMedia)%7Bfullq%3Dmedia%3Brules.push(repUrls(styles))%3B%7D%20%0Aelse%7Bfullq%3Dqs%5Bi%5D.match(respond.regex.findStyles)%26%26RegExp.%241%3Brules.push(RegExp.%242%26%26repUrls(RegExp.%242))%3B%7D%0Aeachq%3Dfullq.split(%22%2C%22)%3Beql%3Deachq.length%3Bfor(var%20j%3D0%3Bj%3Ceql%3Bj%2B%2B)%7Bthisq%3Deachq%5Bj%5D%3Bif(isUnsupportedMediaQuery(thisq))%7Bcontinue%3B%7D%0Amediastyles.push(%7Bmedia%3Athisq.split(%22(%22)%5B0%5D.match(respond.regex.only)%26%26RegExp.%242%7C%7C%22all%22%2Crules%3Arules.length-1%2Chasquery%3Athisq.indexOf(%22(%22)%3E-1%2Cminw%3Athisq.match(respond.regex.minw)%26%26parseFloat(RegExp.%241)%2B(RegExp.%242%7C%7C%22%22)%2Cmaxw%3Athisq.match(respond.regex.maxw)%26%26parseFloat(RegExp.%241)%2B(RegExp.%242%7C%7C%22%22)%7D)%3B%7D%7D%0AapplyMedia()%3B%7D%2C%20makeRequests%3Dfunction()%7Bif(requestQueue.length)%7Bvar%20thisRequest%3DrequestQueue.shift()%3Bajax(thisRequest.href%2Cfunction(styles)%7Btranslate(styles%2CthisRequest.href%2CthisRequest.media)%3BparsedSheets%5BthisRequest.href%5D%3Dtrue%3B%0A%20w.setTimeout(function()%7BmakeRequests()%3B%7D%2C0)%3B%7D)%3B%7D%7D%2C%20ripCSS%3Dfunction()%7Bfor(var%20i%3D0%3Bi%3Clinks.length%3Bi%2B%2B)%7Bvar%20sheet%3Dlinks%5Bi%5D%2Chref%3Dsheet.href%2Cmedia%3Dsheet.media%2CisCSS%3Dsheet.rel%26%26sheet.rel.toLowerCase()%3D%3D%3D%22stylesheet%22%3B%20if(!!href%26%26isCSS%26%26!parsedSheets%5Bhref%5D)%7B%20if(sheet.styleSheet%26%26sheet.styleSheet.rawCssText)%7Btranslate(sheet.styleSheet.rawCssText%2Chref%2Cmedia)%3BparsedSheets%5Bhref%5D%3Dtrue%3B%7Delse%7Bif((!%2F%5E(%5Ba-zA-Z%3A%5D_%5C%2F%5C%2F)%2F.test(href)%26%26!base)%7C%7Chref.replace(RegExp.%241%2C%22%22).split(%22%2F%22)%5B0%5D%3D%3D%3Dw.location.host)%7B%0A%20if(href.substring(0%2C2)%3D%3D%3D%22%2F%2F%22)%7Bhref%3Dw.location.protocol%2Bhref%3B%7D%0ArequestQueue.push(%7Bhref%3Ahref%2Cmedia%3Amedia%7D)%3B%7D%7D%7D%7D%0AmakeRequests()%3B%7D%3B%20ripCSS()%3B%20respond.update%3DripCSS%3B%20respond.getEmValue%3DgetEmValue%3B%20function%20callMedia()%7BapplyMedia(true)%3B%7D%0Aif(w.addEventListener)%7Bw.addEventListener(%22resize%22%2CcallMedia%2Cfalse)%3B%7D%0Aelse%20if(w.attachEvent)%7Bw.attachEvent(%22onresize%22%2CcallMedia)%3B%7D%7D)(this)%3B
Line 7

Tests broken by 'is_3' removal

The tests are broken in the 3.0.0 release:

$ PYTHONPATH=. python jsmin/test.py 
.....................................................................EEEEEEE
======================================================================
ERROR: test_character_class (__main__.RegexTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jsmin/jsmin/test.py", line 618, in test_character_class
    self.assert_regex('/a[0-9]b/g', '/a[0-9]b/')
  File "/tmp/jsmin/jsmin/test.py", line 611, in assert_regex
    recognised = self.regex_recognise(js_input)
  File "/tmp/jsmin/jsmin/test.py", line 595, in regex_recognise
    if not jsmin.is_3:
AttributeError: module 'jsmin' has no attribute 'is_3'

======================================================================
ERROR: test_character_class_with_slash (__main__.RegexTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jsmin/jsmin/test.py", line 621, in test_character_class_with_slash
    self.assert_regex('/a[/]b/g', '/a[/]b/')
  File "/tmp/jsmin/jsmin/test.py", line 611, in assert_regex
    recognised = self.regex_recognise(js_input)
  File "/tmp/jsmin/jsmin/test.py", line 595, in regex_recognise
    if not jsmin.is_3:
AttributeError: module 'jsmin' has no attribute 'is_3'

======================================================================
ERROR: test_empty_character_class (__main__.RegexTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jsmin/jsmin/test.py", line 634, in test_empty_character_class
    self.assert_regex('/a[]/]b/g', '/a[]/]b/')
  File "/tmp/jsmin/jsmin/test.py", line 611, in assert_regex
    recognised = self.regex_recognise(js_input)
  File "/tmp/jsmin/jsmin/test.py", line 595, in regex_recognise
    if not jsmin.is_3:
AttributeError: module 'jsmin' has no attribute 'is_3'

======================================================================
ERROR: test_escaped_back_slash (__main__.RegexTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jsmin/jsmin/test.py", line 627, in test_escaped_back_slash
    self.assert_regex(r'/a\\/g', r'/a\\/')
  File "/tmp/jsmin/jsmin/test.py", line 611, in assert_regex
    recognised = self.regex_recognise(js_input)
  File "/tmp/jsmin/jsmin/test.py", line 595, in regex_recognise
    if not jsmin.is_3:
AttributeError: module 'jsmin' has no attribute 'is_3'

======================================================================
ERROR: test_escaped_forward_slash (__main__.RegexTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jsmin/jsmin/test.py", line 624, in test_escaped_forward_slash
    self.assert_regex(r'/a\/b/g', r'/a\/b/')
  File "/tmp/jsmin/jsmin/test.py", line 611, in assert_regex
    recognised = self.regex_recognise(js_input)
  File "/tmp/jsmin/jsmin/test.py", line 595, in regex_recognise
    if not jsmin.is_3:
AttributeError: module 'jsmin' has no attribute 'is_3'

======================================================================
ERROR: test_precedence_of_parens (__main__.RegexTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jsmin/jsmin/test.py", line 640, in test_precedence_of_parens
    self.assert_regex('/a([)])b/g', '/a([)])b/')
  File "/tmp/jsmin/jsmin/test.py", line 611, in assert_regex
    recognised = self.regex_recognise(js_input)
  File "/tmp/jsmin/jsmin/test.py", line 595, in regex_recognise
    if not jsmin.is_3:
AttributeError: module 'jsmin' has no attribute 'is_3'

======================================================================
ERROR: test_simple (__main__.RegexTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jsmin/jsmin/test.py", line 615, in test_simple
    self.assert_regex('/123/g', '/123/')
  File "/tmp/jsmin/jsmin/test.py", line 611, in assert_regex
    recognised = self.regex_recognise(js_input)
  File "/tmp/jsmin/jsmin/test.py", line 595, in regex_recognise
    if not jsmin.is_3:
AttributeError: module 'jsmin' has no attribute 'is_3'

----------------------------------------------------------------------
Ran 76 tests in 0.034s

FAILED (errors=7)

General correctness tests

We can make a pretty good test for general correctness as follows: for each one of a number of real JS files (the kind of thing that people want to minify):

  1. Make file.min.js with jsmin.
  2. Make file.othermin.js with some other minifying tool.
  3. Make file.min.othermin.js using the other minifying tool, starting with the jsmin minified file.

If jsmin is doing its job right, the two othermin files should be identical.

SyntaxError: Invalid regular expression: missing /

Hi,

when minifying the current moment.js File [1], I get a SyntaxError in the minified version created by jsmin. The source file contains the following code:

        this._dayOfMonthOrdinalParseLenient = new RegExp(
            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
                '|' +
                /\d{1,2}/.source
        );

which is minified to

this._config=config;this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+
'|'+/
\d{1,2}/.source);}

If I remove the new lines, the generated minified JavaScript is valid.

Why are those newlines preserved anyways?

Cheers,
Sebastian

[1] https://momentjs.com/downloads/moment.js

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.