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

fix(bundle-size-tests): Update version numbers in bundles #16233

Merged
merged 10 commits into from
Jul 4, 2023

Conversation

tylerbutler
Copy link
Member

@tylerbutler tylerbutler commented Jul 3, 2023

Description

We update our version numbers in CI when building PRs. These version numbers make it into our compiled code via the packageVersion.ts file that exists in some projects (see the build:genver npm task), so if the version number in the CI pipeline is a different number of bytes than the "true" version number, our bundle size tests calculate bundle size differences of 1-3 bytes for every PR.

Changes

I used the version-tools package to parse the build numbers and convert them back into the correct version. I used string-replace-loader to do the replacements.

Related to AB#4457

@github-actions github-actions bot added area: examples Changes that focus on our examples dependencies Pull requests that update a dependency file base: main PRs targeted against main branch labels Jul 3, 2023
@tylerbutler tylerbutler marked this pull request as ready for review July 3, 2023 18:00
@tylerbutler tylerbutler requested review from msfluid-bot and a team as code owners July 3, 2023 18:00
Copy link
Contributor

@ChumpChief ChumpChief left a comment

Choose a reason for hiding this comment

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

Is this referring to the version numbers in packageVersion.ts files? Maybe clarify in the comment where you're expecting to find the version numbers that need replacing.

@tylerbutler
Copy link
Member Author

Is this referring to the version numbers in packageVersion.ts files? Maybe clarify in the comment where you're expecting to find the version numbers that need replacing.

Updated the PR description.

@@ -30,6 +49,17 @@ module.exports = {
use: "ts-loader",
exclude: /node_modules/,
},
{
test: /\.js$/,
Copy link
Contributor

Choose a reason for hiding this comment

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

Disclaimer: I'm not the most well versed in webpack.

We can't be more specific and target packageVersion.js here? Is this already working on post-bundling files?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, that should be doable provided this is the only place the version string shows up (I think that's true). Loaders are chained and invoked bottom-to-top as middleware during bundling.

This webpack config points at a bunch of entrypoint files which transitively reference code that's already been compiled in dependent packages. So this config should work fine. But if a package that had a packageVersion.ts was additionally an application (we have an example package like this--webflow I think), we'd want to put this rule before ts-loader in the list, since usually webpack configs will target source files for the package they live in.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's potentially reasonable to leave it as .js fwiw. Comes down to which we think is more likely:

  • We change something about package version generation such that we introduce dynamically generated package versions into non-packageVersion.js files
  • We introduce code in our packages which is semantically not a package version but happens to align exactly with one

I'd lean toward the latter being more of a danger, as once we get off the 2.0.0-internal versioning scheme, there are some other places (usually with protocol/persistent versioning concerns) that people might happen to choose semver-like constructs that have overlap with something we're replacing. It's still pretty minor though, since when we're replacing a version, the string we're searching for has something like a build hash on it (and not just '1.0.0' -> '1.0.0-internal' or something likely to collide).

I do like that putting the test condition as packageVersion.js makes this much more self-documenting though.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd lean toward the latter being more of a danger, as once we get off the 2.0.0-internal versioning scheme, there are some other places (usually with protocol/persistent versioning concerns) that people might happen to choose semver-like constructs that have overlap with something we're replacing. It's still pretty minor though, since when we're replacing a version, the string we're searching for has something like a build hash on it (and not just '1.0.0' -> '1.0.0-internal' or something likely to collide).

I agree with your reasoning. Another mitigating factor here is that this webpack output is not used other than to test bundle sizes. So if we do manage to get the versions wrong it should only lead to confusing +/-1-3 byte differences in the bundle size tests. 😄

So this config should work fine. But if a package that had a packageVersion.ts was additionally an application (we have an example package like this--webflow I think), we'd want to put this rule before ts-loader in the list, since usually webpack configs will target source files for the package they live in.

It sounds like it's best to both narrow the test condition to packageVersion.js, and also move it to be before ts-loader (and thus run after it). I made those changes in the latest iteration. Let me know if I misunderstood.

Loaders are chained and invoked bottom-to-top as middleware during bundling.

The docs seemed ambiguous to me at first. The example they give has a single rule that invokes multiple loaders, while this config declares multiple rules with a loader defined. But then I read this: https://webpack.js.org/configuration/module/#ruleloader

Rule.loader is a shortcut to Rule.use: [ { loader } ].

So I guess the example is equivalent to ours.

@@ -30,6 +49,17 @@ module.exports = {
use: "ts-loader",
exclude: /node_modules/,
},
{
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: dynamically including this loader iff verString !== newVersion is a little more efficient for the webpack build. Probably not very noticeable though.

Copy link
Contributor

Choose a reason for hiding this comment

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

even less of a big deal if you take Alejandro's suggestion above of adjusting the test condition.

@tylerbutler
Copy link
Member Author

I'm going to go ahead and merge because I think I took the feedback correctly, and if I messed up then the worst case is bundle-size tools are broken (which they sort of are right now 😄)

@tylerbutler tylerbutler merged commit 26d2d8d into microsoft:main Jul 4, 2023
27 checks passed
@tylerbutler tylerbutler deleted the bundle-size-version-numbers branch July 4, 2023 01:52
@Abe27342
Copy link
Contributor

Abe27342 commented Jul 5, 2023

I'm going to go ahead and merge because I think I took the feedback correctly, and if I messed up then the worst case is bundle-size tools are broken (which they sort of are right now 😄)

LGTM :shipit: can't wait to see 0 bundle diffs where I expect them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: examples Changes that focus on our examples base: main PRs targeted against main branch dependencies Pull requests that update a dependency file
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants