Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix minifyJS when used outside of Node.js #531

Merged
merged 4 commits into from
Mar 15, 2016
Merged

fix minifyJS when used outside of Node.js #531

merged 4 commits into from
Mar 15, 2016

Conversation

alexlamsl
Copy link
Collaborator

Intermittent failures in online tests is primarily due to missing character statistics reset in minifyJS().

Redone the non-Node.js version by referring to the official version, also extracted common logic for minifyCSS() and minifyURLs() so we don't have to reload module and repopulate default option values for every invocation.

@alexlamsl
Copy link
Collaborator Author

@kangax @XhmikosR so I decided to go nuclear and extract UglifyJS.minify() and build it into assets/uglify.js directly.

This way we'll be more future-proof, plus we get to simiplify minifyJS(). The only downside I can see so far is npm run assets/uglify-js looking unwieldy 😅

@XhmikosR
Copy link
Collaborator

XhmikosR commented Mar 4, 2016

I just don't get why we need that custom command to generate it. I'd rather if we kept it official.

@alexlamsl
Copy link
Collaborator Author

@XhmikosR so when uglify-js is running within Node.js, it uses UglifyJS2/tools/node.js

However, when it packages itself for the web, it does not include that file since it uses Node.js libraries.

Since UglifyJS.minify is defined within UglifyJS2/tools/node.js and for the logic path we use does not involve/require Node.js, we use it directly instead of duplicating (wrongly) the same logic inside htmlminifier.js

@alexlamsl
Copy link
Collaborator Author

The old code in minifyJS might be what UglifyJS.minify does in a prior version of uglify-js, but it certainly isn't so now and contains at least two bugs (does not reset character statistics; does not pass options.compress to Compressor) so it's actually more fragile if we go down the path of updating the duplicated code.

As for official version of uglify-js - we are still using it, just appending an extra definition of UglifyJS.minify at the end of the file, which is also extracted from the official source.

@alexlamsl alexlamsl mentioned this pull request Mar 5, 2016
@alexlamsl
Copy link
Collaborator Author

Rebased - but I think I still need to convince @XhmikosR about appending extra code to assets/uglify.js before merging

@alexlamsl
Copy link
Collaborator Author

@XhmikosR currently, minifyJS has two different code paths calling uglify-js for Node.js and online versions. The online code path is broken, either since day one or has become out-of-sync with the upstream project's API. We have a few options to fix this:

  1. fix the online code path by copying from tools/node.js
    • need to manually track upstream changes to maintain consistent behaviour
  2. merge Node.js and online versions into latter
    • consistent behaviour
    • need to manually track upstream bug fixes
    • harder to discover and use for Node.js users
  3. (current PR) merge both versions into require('uglify-js').minify
    • need to append a function in tools/node.js to official version of uglify.js
    • consistent behaviour
    • no DRY issues, all code are from UglifyJS2 repository

@alexlamsl
Copy link
Collaborator Author

I have now modify uglify.js generation once again by using browserify in the same way as cleancss-browser.js and relateurl-browser.js - does that work better for you @XhmikosR?

Would it make sense to call the output file uglify-browser.js?

@XhmikosR
Copy link
Collaborator

Sorry for the lack of replies, I was busy :/

Personally, I'd like to keep things as vanilla as possible. The problem I see with your solution is that you require a custom step even for node; this shouldn't be needed.

Anyway, whatever @kangax prefers.

@alexlamsl
Copy link
Collaborator Author

@XhmikosR no worries - we all have day job(s) 😉

Which custom step for Node.js are you referring to here? Do you mean fromString and inline_script?

@alexlamsl
Copy link
Collaborator Author

Looking through all of this - is dist/* for web consumption only? I ask because Node.js users are using src/* directly as specified by package.json.

If that's the case, why don't we get rid of assets/* altogether, and just browserify src/htmlminifier.js and put that under dist/?

@alexlamsl
Copy link
Collaborator Author

Nope, cli.js uses dist/htmlminifier.min.js for some very interesting reasons...

refactor minify{URLs,JS,CSS} to reduce evaluation overheads
remove code duplication in minifyJS()
@kangax
Copy link
Owner

kangax commented Mar 15, 2016

I think this LGTM so merging. Was minifyJS not working in a browser before?

kangax added a commit that referenced this pull request Mar 15, 2016
fix minifyJS when used outside of Node.js
@kangax kangax merged commit 4461740 into kangax:gh-pages Mar 15, 2016
@alexlamsl
Copy link
Collaborator Author

@kangax that's right - minifyJS work differently in the browser than on Node.js before, but the arrangement of test cases in the past conveniently hides the problem.

Now that I'm expanding on tests/minifier.js... 💣💥

// try to get global reference first
var result = global[name];
if (typeof result === 'undefined' && typeof require === 'function') {
result = require(path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't play well with webpack:

WARNING in .//html-minifier/src/htmlminifier.js
Critical dependencies:
649:15-28 the request of a dependency is an expression
@ ./
/html-minifier/src/htmlminifier.js 649:15-28

And later

webpack:///./~/html-minifier/src ^./.*$:13
return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
^
Error: Cannot find module 'relateurl'.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have zero idea how webpack works, so PR welcome 😉

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me have a look at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants