Skip to content

Conversation

@joshblack
Copy link
Member

This is a draft PR to see what it would be like to use rollup for the full build process. Using rollup in this way can:

  • Decrease package size on disk (and reduce install times)
  • Reduce build time (somewhat)
  • Deduplicate common code across modules (useful when using babel helpers)

It can also be a useful tool for highlighting when modules have circular dependencies within the project. It also has the side-effect of only production artifacts making their way into the package (no tests or stories). Types still seem to be emitted by the build process.

Package size (on disk)

Folder Before After % Change
lib-esm 4.3M 828K -80%
lib 4.6M 884K -81%

This PR also marginally decreases the build time from roughly 18s to 13s, mostly due to it using the same bundle to output cjs/esm/umd instead of building once in rollup and compiling once for cjs/esm.

Task Before After % Change
time npm run build 18.859s 13.561s -28%

Blockers

This change cannot be adopted until circular dependencies are addressed

@changeset-bot
Copy link

changeset-bot bot commented Aug 22, 2022

⚠️ No Changeset found

Latest commit: fec502e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Contributor

size-limit report 📦

Path Size
dist/browser.esm.js 92.9 KB (+22.85% 🔺)
dist/browser.umd.js 94.91 KB (+24.51% 🔺)

@joshblack joshblack temporarily deployed to github-pages August 22, 2022 22:12 Inactive
rm -rf dist
rm -rf lib
rm -rf lib-esm
npm run clean
Copy link
Contributor

Choose a reason for hiding this comment

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

So clean!

const external = [
...Object.keys(packageJson.peerDependencies),
...Object.keys(packageJson.dependencies),
...Object.keys(packageJson.devDependencies)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this how the bundle size is reduced?

@lesliecdubs
Copy link
Member

I’ll let other folks weigh in here, but thought this might be prudent to share (x-posting from Slack for posterity) --

#web-systems, our sister UI platform team over in the Eng org, historically made the call to use rollup to build GitHub assets. More recently, they decided to roll back this decision and adopt webpack instead. Perhaps there’s insight about their decision-making process in here that could be useful for us to consider, too.

Copy link
Contributor

@pksjce pksjce left a comment

Choose a reason for hiding this comment

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

This is a really cool change! I have a few questions.

  • Will the lib-esm package size decrease be felt by our consumers? Will their bundle sizes decrease?
  • What kind of tests were you able to run for these new bundled files? Can you make sure nextjs/remix are able to consume them with no issues? We've had tons of issues regarding bundling now working for these frameworks. Maybe you could test in memex too?
  • Did you test for importing draft components. The subpaths were one of my pain points with esm modules.
  • Also I'm a little apprehensive about making dependencies external. Maybe I don't understand the context properly.

extensions
}),
commonjs(),
babel({
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd recommend avoiding babel here. We dropped babel from dotcom and all public repos a few years ago because:

  • babel is quite slow. Typescript or esbuild or swc are much faster and equally as capable
  • Babel tends to err on the side of compatibility which means transforming things that don't necessarily need to be transformed due to edge cases. (An example of this is object rest spread gets transformed if you specify edgehtml as a browser, even though edge supports object rest spread). This results in bigger bundle sizes than necessary.
  • Configuring babel can be tricky and can result in varying compatibilities. Typescripts target is a little more blunt (just specifying a year to compile down to) but that's much easier to propagate across many repos.

In addition, moving from babel would be a great step to coalescing all our repositories around a central build config. As mentioned doctor uses swc, while all other repositories just use typescript.

Here's Primer ViewComponents configuration: https://github.com/primer/view_components/blob/b0dbefb471d8262a2a45235ccaf0501260f00cd4/rollup.config.js#L15

@keithamus
Copy link
Contributor

#web-systems, our sister UI platform team over in the Eng org, historically made the call to use rollup to build GitHub assets. More recently, they decided to roll back this decision and adopt webpack instead. Perhaps there’s insight about their decision-making process in here that could be useful for us to consider, too.

This makes sense given the context of dotcom which requires delivering of assets in ways which webpack supports better than rollup, but for libraries we still use rollup across the board as it provides much simpler configuration.

@joshblack
Copy link
Member Author

Thanks for taking the time to review @pksjce!

Will the lib-esm package size decrease be felt by our consumers? Will their bundle sizes decrease?

Sadly not much, I think the only thing would be that Babel currently is transpiling files 1:1 whereas rollup is able to build a dependency graph and extract common helpers. But that isn't too much savings in the grand scheme of things, especially since the project already is setup for tree shaking.

What kind of tests were you able to run for these new bundled files? Can you make sure nextjs/remix are able to consume them with no issues? We've had tons of issues regarding bundling now working for these frameworks. Maybe you could test in memex too?

Nothing yet, wanted to gauge interest first since this change would require updating the circular dependencies in the project first 👀 I love all your suggestions and am happy to test them out and keep this exploration going!

Did you test for importing draft components. The subpaths were one of my pain points with esm modules.

Thankfully rollup has the preserveModules and preserveModulesRoot options to enable sub-paths 🙏 This should be working as expected with the changes (users can import from sub-dirs)

Also I'm a little apprehensive about making dependencies external. Maybe I don't understand the context properly.

The way I understand this is that rollup by default will include all dependencies in the output bundle. This is great for UMD bundles but in the ESM/CommonJS case it's nice to exclude them because they can be resolved via import/require. This is important so that dependencies can be deduped instead of included multiple times if the project uses both primer and the shared dependency.

@joshblack
Copy link
Member Author

Thanks all for leaving a comment! Going to close out this exploration and will post a follow-up after addressing the circular deps issue 😄 Will also make sure to revisit the rollup setup with TypeScript vs Babel 👍

@joshblack joshblack closed this Aug 24, 2022
@joshblack joshblack deleted the experiment/update-rollup-setup branch August 24, 2022 16:37
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.

5 participants