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

ref(build): Use sucrase for es6 bundles #5111

Merged
merged 1 commit into from
May 17, 2022

Conversation

lobsterkatie
Copy link
Member

This switches the building of our es6 CDN bundles to use sucrase instead of tsc (or, more accurately, to use the sucrase rollup plugin rather than the typescript rollup plugin), in order both to build more quickly (in a time trial of multiple runs on GHA, this change brings the average yarn build run down from ~8 minutes to ~4 minutes) and to ensure that we have exact code parity between our CDN bundles and our npm packages.

Because sucrase doesn't down-compile the way tsc will, the building of the es5 bundles hasn't been changed, and that build still uses the typescript plugin.

@github-actions
Copy link
Contributor

size-limit report 📦

Path Size
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 18.75 KB (-6.91% 🔽)
@sentry/browser - ES5 CDN Bundle (minified) 58.19 KB (-9.95% 🔽)
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 17.65 KB (-6.44% 🔽)
@sentry/browser - ES6 CDN Bundle (minified) 52.09 KB (-10.14% 🔽)
@sentry/browser - Webpack (gzipped + minified) 19.33 KB (-16.84% 🔽)
@sentry/browser - Webpack (minified) 61.44 KB (-24.82% 🔽)
@sentry/react - Webpack (gzipped + minified) 19.35 KB (-16.88% 🔽)
@sentry/nextjs Client - Webpack (gzipped + minified) 42.81 KB (-10.92% 🔽)
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 24.41 KB (-6.39% 🔽)
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 23 KB (-6.08% 🔽)

@lobsterkatie lobsterkatie merged commit 66a6b59 into 7.x May 17, 2022
@lobsterkatie lobsterkatie deleted the kmclb-use-sucrase-for-bundles branch May 17, 2022 13:10
lobsterkatie added a commit that referenced this pull request May 18, 2022
In #5094, a change was made to parallelize our repo-level build commands as much as possible. In that PR, it was stated that `build:bundle` could run independent of, and therefore in parallel with, the types and rollup builds, and at the time that was true. When TS (through rollup) builds a bundle, it creates a giant AST out of the bundled package and all of its monorepo dependencies, based on the original source code, then transpiles the whole thing - no prework needed.

But in #5111 we switched our ES6 bundles to use sucrase for transpilation (still through rollup), and that changed things. Sucrase (along with every other non-TS transpilation tool) only considers files one by one, not as part of a larger whole, and won't reach across package boundaries, even within the monorepo. As a result, rollup needs all dependencies to already exist in transpiled form, since sucrase doesn't touch them, which becomes a problem if both processes are happening at once.

(_But how has CI even been passing since that second PR, then?_, you may ask. The answer is, sucrase is very fast, and lerna can only start so many things at once. It ends up being a race condition between sucrase finishing with the dependencies and lerna kicking off the bundle builds, and almost all the time, sucrase wins. And the other situations in which this is broken all involve using something other than the top-level `build` script to create bundles in a repo with no existing build artifacts, and CI just never does that.)

So TL;DR, we need to have already transpiled a packages's monorepo dependencies before that package can be turned into a bundle. For `build:bundle` at both the repo and package level, and for `build` at the package level, this means that if they're not there, we have to build them. For `build` at the repo level, where transpilation of all packages does in fact already happen, we have two options:
1) Push bundle builds to happen alongside `build:extras`, after rollup builds have finished.
2) Mimic what happens when the race condition is successful, but in a way that isn't flaky. In other words, continue to run `build:bundle` in parallel with the types and npm package builds, but guarantee that the needed dependencies have finished building themselves before starting the bundle build.

Of the two options, the first is certainly simpler, but it also forces the two longest parts of the build (bundle and types builds) to be sequential, which is the exact _opposite_ of what we want, given that the goal all along has been to make the builds noticeably faster. Choosing the second solution also gives us an excuse to add the extra few lines of code needed to fix the repo-level-build:bundle/package-level-build/package-level-build:bundle problem, which we otherwise probably wouldn't fix. 

This implements that second strategy, by polling at 5 second intervals for the existence of the needed files, for up to 60 seconds, before beginning the bundle builds. (In practice, it fairly reliably seems to take two retries, or ten seconds, before the bundle build can begin.) It also handles the other three situations above, by building the missing files when necessary. Finally, it fixes a type import to rely on the main types package, rather than a built version of it. This prevents our ES5 bundles (which still use TS for transpilation, in order to also take advantage of its ability to down-compile) from running to the same problem as the sucrase bundles are having.
AbhiPrasad pushed a commit that referenced this pull request May 30, 2022
This switches the building of our es6 CDN bundles to use sucrase instead of `tsc` (or, more accurately, to use the sucrase rollup plugin rather than the typescript rollup plugin), in order both to build more quickly (in a time trial of multiple runs on GHA, this change brings the average `yarn build` run down from ~8 minutes to ~4 minutes) and to ensure that we have exact code parity between our CDN bundles and our npm packages.

Because sucrase doesn't down-compile the way `tsc` will, the building of the es5 bundles hasn't been changed, and that build still uses the typescript plugin.
AbhiPrasad pushed a commit that referenced this pull request May 30, 2022
In #5094, a change was made to parallelize our repo-level build commands as much as possible. In that PR, it was stated that `build:bundle` could run independent of, and therefore in parallel with, the types and rollup builds, and at the time that was true. When TS (through rollup) builds a bundle, it creates a giant AST out of the bundled package and all of its monorepo dependencies, based on the original source code, then transpiles the whole thing - no prework needed.

But in #5111 we switched our ES6 bundles to use sucrase for transpilation (still through rollup), and that changed things. Sucrase (along with every other non-TS transpilation tool) only considers files one by one, not as part of a larger whole, and won't reach across package boundaries, even within the monorepo. As a result, rollup needs all dependencies to already exist in transpiled form, since sucrase doesn't touch them, which becomes a problem if both processes are happening at once.

(_But how has CI even been passing since that second PR, then?_, you may ask. The answer is, sucrase is very fast, and lerna can only start so many things at once. It ends up being a race condition between sucrase finishing with the dependencies and lerna kicking off the bundle builds, and almost all the time, sucrase wins. And the other situations in which this is broken all involve using something other than the top-level `build` script to create bundles in a repo with no existing build artifacts, and CI just never does that.)

So TL;DR, we need to have already transpiled a packages's monorepo dependencies before that package can be turned into a bundle. For `build:bundle` at both the repo and package level, and for `build` at the package level, this means that if they're not there, we have to build them. For `build` at the repo level, where transpilation of all packages does in fact already happen, we have two options:
1) Push bundle builds to happen alongside `build:extras`, after rollup builds have finished.
2) Mimic what happens when the race condition is successful, but in a way that isn't flaky. In other words, continue to run `build:bundle` in parallel with the types and npm package builds, but guarantee that the needed dependencies have finished building themselves before starting the bundle build.

Of the two options, the first is certainly simpler, but it also forces the two longest parts of the build (bundle and types builds) to be sequential, which is the exact _opposite_ of what we want, given that the goal all along has been to make the builds noticeably faster. Choosing the second solution also gives us an excuse to add the extra few lines of code needed to fix the repo-level-build:bundle/package-level-build/package-level-build:bundle problem, which we otherwise probably wouldn't fix. 

This implements that second strategy, by polling at 5 second intervals for the existence of the needed files, for up to 60 seconds, before beginning the bundle builds. (In practice, it fairly reliably seems to take two retries, or ten seconds, before the bundle build can begin.) It also handles the other three situations above, by building the missing files when necessary. Finally, it fixes a type import to rely on the main types package, rather than a built version of it. This prevents our ES5 bundles (which still use TS for transpilation, in order to also take advantage of its ability to down-compile) from running to the same problem as the sucrase bundles are having.
@AbhiPrasad AbhiPrasad added this to the 7.0.0 milestone May 30, 2022
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.

3 participants