Fix the plugin return object for keep-enabled gzipping #19
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In v0.2.0 we changed the return object for the plugin so that when
the
keep
option is enabled we set adistFiles
value in additionto gzippedFiles. This ensured our gzipped files got picked up by
later plugins (e.g the manifest, S3 upload etc).
Javascript passes objects by reference. You can see in the result
object we were using the same
gzippedFiles
array object returnedfrom the _gzipFiles Promise map. This turned out to be a bad idea.
Setting distFiles equal to the array of gzipped files works because
the return object from each plugin in the pipeline is merged with
the pipeline's context, effectively concatenating the pipeline's
distFiles
with ourgzippedFiles
array. So far, so logical.The merge of the result with the existing context object is
performed using lodash's
merge
function. This function maintainsa stack of object values already merged to avoid cyclical object
merging issues. As each key in the object to be merged is processed
lodash looks up the key's value in the stack. If it has been seen
before then the merge is cut short and the merge result's value for
the given key is set to the value of the merge from the earlier key..
What this means for the gzip plugin is that after the result object
is merged into the existing context by Ember CLI Deploy's pipeline
model,
context.distFiles
===context.gzippedFiles
- they are theexact same object. This is obviously incorrect and has repercussions
later on e.g. the S3 plugin ends up setting
Content-Encoding: gzip
on every file it uploads.
This would have been a whole lot easier to spot if I reordered the
keys in the result object during my initial PR i.e. if I put
distFiles
belowgzippedFiles
. In that case the merge would endup destroying the context's
distFiles
and both would just containthe list of gzipped files, wrecking the pipeline 😒
I've verified the problem still happens with Lodash 4.5.1 so I'm
going to go talk to them. We're going to sidestep the problem here
by not using the same object for both result keys, using a simple
concat to build a new object.