More accurate side-effect detection - #253
Merged
Merged
Conversation
Contributor
|
Woo! Comments! I haven't had a chance to read through the PR on a computer, but I like the look of it. |
Contributor
|
I don't really have the time to look at this properly, but I looked over the tests quickly and they seem sane. This is exciting! |
Merged
Contributor
Author
|
I think I have some changes on this branch that aren't checked in (on another machine) so I won't merge this just yet |
Rich-Harris
added a commit
that referenced
this pull request
Nov 14, 2015
More accurate side-effect detection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
This is quite a big PR; bear with me. Among other things it needs some battle testing and a tidy up before it gets merged (some of the names are a bit weird, etc).
Currently, any top-level CallExpression (i.e. not inside a function declaration/expression) is assumed to contain side-effects, and is therefore included in the bundle. This is often wasteful:
In this example there's no reason for
square,cubeandpowerto be included. As of this PR, Rollup is smart enough to recognise thatpowerrefers to a pure function (i.e. calling it has no side-effects).A few other changes that fall out of this way of doing things:
foo, andfoorefers tobar, the module depends strongly on the module wherebaris defined. Previously, the module had to have abarreference at the top level (or inside an IIFE, thanks to some special case logic introduced to accommodate a pattern used a lot inside Three.js)new Array(foo)orObject.keys(bar)) can be treated the same as local functions that are known to be pureUnfortunately this only goes some way towards solving the problem identified here – that apps using individual Lodash functions end up bundling a lot of unnecessary stuff (though with this PR it's nowhere near as bad as @callumlocke found). A lot of it could be eliminated if the lodash-es build were to forgo a default export altogether, but that's certainly not a perfect solution.
The reason the extra stuff gets included is because Rollup digs up the entire dependency graph and scans it for side-effects – and discovers statements that could have side-effects, but in modules we're not really interested in.
To be completely safe, we do need to include those side-effects because of things like this, where module
ahappens to muck about with the contents of moduleb, which we're using. But in a lot of cases – Lodash being a fine example – that's overly cautious. So this PR also introducesaggressivemode, which only looks for side-effects in the entry module:With
aggressive: true, these result in almost exactly the same sized bundle:Oh, and I moved a couple of files around to make things a bit easier.
Thoughts welcome!