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

drive-by fix for minify options brokeness #69

Closed
wants to merge 1 commit into from

Conversation

iamjochem
Copy link

@iamjochem iamjochem commented Jun 19, 2017

see #66 for reasoning.

Little Rant: I (& a million others) have spent man-months of wasted time debugging problems related to shitty handling of options/config objects. where "shitty" is defined as applying one or more of the following:

  1. Not cloning [option] objects before passing them to a lib/function.
  2. Not cloning [option] objects when they are passed into your/a lib/function (and then changing the given reference!?!?)
  3. Some module/lib being really helpful and throwing exceptions because "option property 'foo' is invalid/unknown"

1. & 2. are easy to fix - Object.assign() is your friend - if everyone would just do this we'd be free of so many bugs related to objects passed in as parameters being changed by the callee.

3. - this one requires a change of mindset so that we start treating options object parameters as collections from which known/valid option properties are extracted; this is in constrast to the heavy-handed use of, for instance, JSON schema to validate a given options object and throw an esoteric Error if the options are "invalid" ... which is really helpful when your using a lib indirectly (e.g. babel from the context of uglifyify)

@voxpelli
Copy link

This solves the #66 for me

@zifeo
Copy link

zifeo commented Jun 22, 2017

Also solving #66 in my case. Cheers to @iamjochem!

@@ -51,27 +44,38 @@ function uglifyify(file, opts) {
)

debug = opts.sourceMap !== false && (debug || matched)
opts = extend({}, {

var thisopts = extend({}, {
Copy link
Contributor

Choose a reason for hiding this comment

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

do you want to rename this to _opts, so we can distinguish that this is uglify's opts we are gonna use for uglify only. thisopts just seems off for me. but definitely agree that we should create a new obj

Copy link
Author

Choose a reason for hiding this comment

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

this is bikeshedding, no?

sorry, I have lost my sense of humour about this, too much head-banging and time lost due to lazy/dumb/unfriendly option handling (yeah, hi there Babel!)

regardless, I think you should run with your PR's in favour of this one, the end result is the same in terms of fixing the relevant problems/bugs and you seem to be more involved (with the project).

so, by al means delete/close this PR once your's is merged.

if (typeof opts.compress === 'object') {
delete opts.compress._
// remove exts before passing opts to uglify
delete thisopts.global
Copy link
Contributor

Choose a reason for hiding this comment

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

yeeee agree, let's delete these within the stream 👍

var min = ujs.minify(buffer, opts)
var min = ujs.minify(buffer, thisopts)

if (min.error)
Copy link
Contributor

Choose a reason for hiding this comment

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

this is a stream, so we should be emitting an error rather than throwing it (i added this is in #71 when i remapped the argv stuff)

Copy link
Author

Choose a reason for hiding this comment

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

okay, I was aware of what through() was doing, didn't realise that it was generating a stream instance ... although looking at the code I think that due to the implementation of the capture() function that doing throw min.error actually results in an "error" event being emitted.

It is also worth considering that min.error might not be an actual Error instance ... "best practice" states you should only be throwing actual instances of Error (even though you can throw anything you like) .. so we might wish to transform the given min.error into a real Error object (note that min.error may be set by uglyfy's dependencies and that it's type may change depending on what the error is and where it originated.)

@lrlna
Copy link
Contributor

lrlna commented Jun 26, 2017

Hey! I left a few comments. I am not a fan of Object.assign() tbh, mainly because it's not quite supported everywhere, so I am a bit hesitant. I am down to use extend or xtend, however to create a new object.

@iamjochem
Copy link
Author

Object.assign() in node v4+ (not sure down to what version you are supporting) is fine for simple object cloning, but extend() is better here if only because it is doing a deep clone (which even if you don't need it now will save us all another round of time-wasting musical-"options-are-changing-under-my-feet"-chairs.)

@iamjochem
Copy link
Author

@lrlna - I rebased my PR to get rid of the conflicts with master but ended up doing this in a fork of my fork (silly rabbit)... which meant I couldn't push the changes ... probably there are git incantations that will fix such a situation but I took the easy/crufty way out and created a new PR.

#72 replaces this, so I'm closing it. :-)

@iamjochem iamjochem closed this Jun 26, 2017
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