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): Build types separately #4724

Merged
merged 8 commits into from
Mar 18, 2022
Merged

Conversation

lobsterkatie
Copy link
Member

@lobsterkatie lobsterkatie commented Mar 16, 2022

As part of the new bundling process, the splits the building of types off into its own build step. Key changes:

  • A new, types-specific tsconfig in each package, which generates types only, and a todo in the main tsconfig.json for turning off the current type generation in dist/ and esm/. (It's not turned off now in order to not break anyone importing directly from those folders instead of from @sentry/xxxx. We'll flip the switch come v7, but for now we're just generating both.) This types tsconfig is also added to the templates.

  • New yarn scripts for generating types (in regular and watch versions), and the addition of this script to other build commands.

  • A node script for running the repo-wide yarn:build:types command, which solves the problem of the watch build hanging if a regular build hasn't happened first. As explained at the top of the script:

    If yarn build:types:watch is run without types files previously having been created, the build will get stuck in an errored state. This happens because lerna runs all of the packages' yarn build:types:watch statements in parallel, and so packages like @sentry/browser will at first be missing types they import from packages like @sentry/utils and @sentry/types, causing errors to be thrown. Normally this is fine, because as the dependencies' types get built, file changes will be detected and the dependent packages' types will try again to build themselves. There might be several rounds of this, but in theory, eventually all packages should end up with an error-free build. For whatever reason, though, at a certain point the process hangs, either because changes stop being detected or because recompiles stop being triggered by detected changes.

    Either way, the process gets stuck. The solution is to run a sequential build first, because as long as there are existing files the first time the watch command runs, no subsequent changes ever cause a hang, no matter how many rounds of recompilation are needed. (It's not entirely clear why this is the case.) We only want to take the time to do that if we have to, though, so we first check all of the relevant packages to see if there are pre-existing types files.

  • A change to the types entry in all package.json files, to point to the types generated using the new tsconfig and the new scripts.

Ref: https://getsentry.atlassian.net/browse/WEB-668

@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 2022

size-limit report

Path Base Size (a7a6ea5) Current Size Change
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.49 KB 19.49 KB 0%
@sentry/browser - ES5 CDN Bundle (minified) 62.17 KB 62.17 KB 0%
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 18.11 KB 18.11 KB -0.01% 🔽
@sentry/browser - ES6 CDN Bundle (minified) 55.5 KB 55.5 KB 0%
@sentry/browser - Webpack (gzipped + minified) 22.41 KB 22.6 KB +0.84% 🔺
@sentry/browser - Webpack (minified) 76.82 KB 79.21 KB +3.11% 🔺
@sentry/react - Webpack (gzipped + minified) 22.45 KB 22.63 KB +0.84% 🔺
@sentry/nextjs Client - Webpack (gzipped + minified) 46.62 KB 47.6 KB +2.12% 🔺
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 25.36 KB 25.36 KB +0.01% 🔺
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 23.72 KB 23.72 KB 0%

Copy link
Member

@lforst lforst left a comment

Choose a reason for hiding this comment

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

Changes look good to me! I left one suggestion in the script.

scripts/buildTypesWatch.js Outdated Show resolved Hide resolved
Copy link
Member

@lforst lforst left a comment

Choose a reason for hiding this comment

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

Thanks for adding my suggestions! :D LGTM!

@lobsterkatie
Copy link
Member Author

Thanks for adding my suggestions! :D LGTM!

Thanks for helping me clean it up! Teamwork FTW! 🙂

@lobsterkatie lobsterkatie merged commit c17b752 into master Mar 18, 2022
@lobsterkatie lobsterkatie deleted the kmclb-build-types-separately branch March 18, 2022 08:08
@RobinCsl
Copy link

In @sentry/node v6.19.0, the build/ folder is missing.

Could you please inquire?

lobsterkatie added a commit that referenced this pull request Mar 22, 2022
A few of the `build:types:watch` instances added in #4724 got clobbered in a subsequent rebase. This adds the missing ones back in.
@lobsterkatie
Copy link
Member Author

In @sentry/node v6.19.0, the build/ folder is missing.

The problem that caused should be solved in 6.19.1. Please let us know if upgrade doesn't fix it for you.

@RobinCsl
Copy link

In @sentry/node v6.19.0, the build/ folder is missing.

The problem that caused should be solved in 6.19.1. Please let us know if upgrade doesn't fix it for you.

It did fix it, thanks.

Lms24 added a commit that referenced this pull request Mar 31, 2022
…ints (#4824)

* All tarballs now include the `build/types` directory. All `.npmignore`s were adjusted to include this directory.
* The `types` entry point in all `package.json`s are now adjusted to the new types directory

Proper bugfix for 6.19.0 regression:
With PR #4724, we introduced separate building of type declaration files which would be written to `<sdk>/build/types`. Furthermore, we adjusted the `types` entry point in the `package.json`s to this new directory. To avoid a breaking change, we kept type declarations in `dist` and `esm`. However, a bug in this PR caused a small regression in most of our SDKs: The new types directory was not included in most of our SDK tarballs. Subsequently, we released a hot fix via #4745 which simply reset the entry points back to their previous path (`dist/index.d.ts`) in all SDKs. 

Additional adjustments w.r.t. creating tarballs to improve consistency:
* Browser: Adjusted `postbuild.sh` to copy `.npmignore` to `./build`
* Gatsby: Use `.npmignore` instead of `files` property in `package.json`
* Utils: Changed `.npmignore` to be more similar to our other packages
* WASM: Changed `.npmignore` to be more similar to our other packages
* Next.js: Added `.npmignore`
lobsterkatie added a commit that referenced this pull request May 10, 2022
This switches our `build` and `build:dev` yarn scripts to use the new rollup/sucrase build process.

This is the culmination of a number of previous changes, whose highlights include:
- #4724, which made building types files a separate build process
- #4895, which updated the SDK to use TS 3.8.3
- #4926, which removed use of the `Severity` enum
- #5005, which switch our default tsconfig to target es6
- #4992, which added the Sucrase plugin, some helper functions, and the `yarn build:rollup` script
- #4993, which added rollup plugins to use `var` rather than `const` and clean up the built code in various ways
- #5022, which applied the same `const`-to-`var` translation to tests
- #5023, which added the ability to change injected polyfills into imports

The result is that, as of this PR, we will no longer use `tsc` to transpile or down-complile our code when building npm packages. Instead, we will be using Rollup to handle making our code CJS-friendlly and Sucrase to handle the transpilation from TS to JS. The main advantages of this change are:
- It forced us to do a lot of updating, centralizing, and cleanup of our tooling, not just for build but also for testing and linting.
- It brings our CDN build process and our npm build process much more in line with each other, for easier maintainability.
- It gives us more control over the eventual output, because we have access to a whole internet full of Rollup plugins (not to mention the ability to make our own), rather than being constrained to tsconfig options. (Plugins also allow us to interact with the code directly.)
- It speeds up our builds fairly significantly. I ran a number of trials in GHA of running `yarn build:dev` at the top level of the repo. Before this change, the average time was ~150 seconds. After this change, it's about half that, roughly 75 seconds.

Because of the switch in tooling, the code we publish is going to be slightly different. In order to make sure that those differences weren't going to be breaking, I built each package under the old system and under the new system, ran a `git diff`, and checked every file, both CJS and ESM, in every package affected by this change. The differences (none of which affect behavior or eventual bundle size by more than a few bytes in each direction), fell into a few categories:

- Purely cosmetic changes, things like which comments are retained, the order of imports, where in the file exports live, etc.
- Changes to class constructors, things like not explicitly assigning `undefined` to undefined attributes, using regular assignment rather than `Object.defineProperty` for attributes which are assigned values, and splitting some of those assignments off into helper functions. 
- Changes related to the upgrade to ES6 and dropping of support for Node 6, things like not polyfilling object spread or async/await

While this represents the most significant part of the overall change, a few outstanding tasks remain:

- Making this same switch in `build:watch`
- Parallelizing the builds, both locally and in CI
- Perhaps applying the new process to our CDN bundle builds
- Generalized cleanup

These will all be included in separate PRs, some in the immediate future and some in the hopefully-not-too-distant short-to-medium term.
AbhiPrasad pushed a commit that referenced this pull request May 30, 2022
This switches our `build` and `build:dev` yarn scripts to use the new rollup/sucrase build process.

This is the culmination of a number of previous changes, whose highlights include:
- #4724, which made building types files a separate build process
- #4895, which updated the SDK to use TS 3.8.3
- #4926, which removed use of the `Severity` enum
- #5005, which switch our default tsconfig to target es6
- #4992, which added the Sucrase plugin, some helper functions, and the `yarn build:rollup` script
- #4993, which added rollup plugins to use `var` rather than `const` and clean up the built code in various ways
- #5022, which applied the same `const`-to-`var` translation to tests
- #5023, which added the ability to change injected polyfills into imports

The result is that, as of this PR, we will no longer use `tsc` to transpile or down-complile our code when building npm packages. Instead, we will be using Rollup to handle making our code CJS-friendlly and Sucrase to handle the transpilation from TS to JS. The main advantages of this change are:
- It forced us to do a lot of updating, centralizing, and cleanup of our tooling, not just for build but also for testing and linting.
- It brings our CDN build process and our npm build process much more in line with each other, for easier maintainability.
- It gives us more control over the eventual output, because we have access to a whole internet full of Rollup plugins (not to mention the ability to make our own), rather than being constrained to tsconfig options. (Plugins also allow us to interact with the code directly.)
- It speeds up our builds fairly significantly. I ran a number of trials in GHA of running `yarn build:dev` at the top level of the repo. Before this change, the average time was ~150 seconds. After this change, it's about half that, roughly 75 seconds.

Because of the switch in tooling, the code we publish is going to be slightly different. In order to make sure that those differences weren't going to be breaking, I built each package under the old system and under the new system, ran a `git diff`, and checked every file, both CJS and ESM, in every package affected by this change. The differences (none of which affect behavior or eventual bundle size by more than a few bytes in each direction), fell into a few categories:

- Purely cosmetic changes, things like which comments are retained, the order of imports, where in the file exports live, etc.
- Changes to class constructors, things like not explicitly assigning `undefined` to undefined attributes, using regular assignment rather than `Object.defineProperty` for attributes which are assigned values, and splitting some of those assignments off into helper functions. 
- Changes related to the upgrade to ES6 and dropping of support for Node 6, things like not polyfilling object spread or async/await

While this represents the most significant part of the overall change, a few outstanding tasks remain:

- Making this same switch in `build:watch`
- Parallelizing the builds, both locally and in CI
- Perhaps applying the new process to our CDN bundle builds
- Generalized cleanup

These will all be included in separate PRs, some in the immediate future and some in the hopefully-not-too-distant short-to-medium term.
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