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

Inline spread elements where possible #179

Merged

Conversation

chris-morgan
Copy link
Contributor

My use case that leads me to desire this is code conditional on compile-time constants, e.g. { …, ...FEATURE ? { … } : { … } } (with Rollup’s tree-shaking resolving the FEATURE ternary before it gets to Bublé). I first implemented what amounts to this change in Terser (terser/terser#224), but then realised that I was running Bublé before Terser, and so Terser never actually got the spreads to inline. The next idea was running Terser, then Bublé, then Terser again… yuck. Then I decided that this optimisation really belonged in Bublé anyway: generating less code is good!

Implementation notes:

The ObjectExpression implementation was straightforward and I implemented it in situ.

Then the ArrayExpression, CallExpression and NewExpression one: at first I performed the spread inlining in spread()’s while loop, and that seemed to work well, but I got scared of how ArrayExpression and CallExpression both handled their “single element” cases specially, and that they did not appear to be optional inasmuch as removing the special-casing yielded exceptions in the test suite; so I extracted that
into a separate function. That ended up pleasing me more as well, with clearly cut semantics and a smaller diff inside the *Expression files, as they no longer needed to change their single-element special cases to not activate on a SpreadElement containing an ArrayElement.

My use case that leads me to desire this is code conditional on
compile-time constants, e.g. `{ …, ...FEATURE ? { … } : { … } }` (with
Rollup’s tree-shaking resolving the FEATURE ternary before it gets to
Bublé). I first implemented what amounts to this change in Terser
(terser/terser#224), but then realised that I
was running Bublé before Terser, and so Terser never actually *got* the
spreads to inline. The next idea was running Terser, then Bublé, then
Terser again… yuck. Then I decided that this optimisation really
belonged in Bublé anyway: generating less code is good!

Implementation notes:

The ObjectExpression implementation was straightforward and I
implemented it in situ.

Then the ArrayExpression, CallExpression and NewExpression one: at first
I performed the spread inlining in spread()’s while loop, and that
seemed to work well, but I got scared of how ArrayExpression and
CallExpression both handled their “single element” cases specially, and
that they did not appear to be optional inasmuch as removing the
special-casing yielded exceptions in the test suite; so I extracted that
into a separate function. That ended up pleasing me more as well, with
clearly cut semantics and a smaller diff inside the *Expression files,
as they no longer needed to change their single-element special cases to
*not* activate on a SpreadElement containing an ArrayElement.
@chris-morgan chris-morgan force-pushed the inline-spread-where-literal branch from 8c8c398 to 27728c6 Compare January 16, 2019 10:42
@chris-morgan
Copy link
Contributor Author

Force push as I remembered I had forgotten to add tests about trailing comma behaviour on object spread. I think I’m finished now. Certainly am for the day.

@adrianheine
Copy link
Member

This seems pretty specific and I feel like it's a bit out-of-scope for bublé, but it's also nice, apparently helps at least one person and is small and self-contained, so I'm merging this. Thanks for your work!

@adrianheine adrianheine reopened this Jan 22, 2019
@adrianheine adrianheine merged commit 8656f88 into bublejs:master Jan 22, 2019
@chris-morgan chris-morgan deleted the inline-spread-where-literal branch January 23, 2019 00:16
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.

2 participants