-
Notifications
You must be signed in to change notification settings - Fork 5
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
Allows the Cedar library to be tree shaken in consuming applications #131
Conversation
…es for distribution. Enables tree-shaking downstream
@@ -2,7 +2,7 @@ | |||
import { | |||
defineComponent, useCssModule, computed, ref, reactive, onMounted, provide, | |||
} from 'vue'; | |||
import debounce from 'lodash-es/debounce'; | |||
import { debounce } from 'lodash-es'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to destructure the named exports from the lodash-es
module, which points to the module entry defined in lodash-es/package.json
. Otherwise, in the context of testing in consuming applications, Vitest whines about not being able to import lodash-es/debounce
without a .js
extension.
output: { | ||
globals: { | ||
vue: 'Vue', | ||
}, | ||
preserveModules: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic
vite.umd.config.mjs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this file if UMD is not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉🎉🎉
Problem
The
cedar.mjs
distributable asset is the total collection of all Cedar library components. Even thoughcedar.mjs
is an ES module, Vite/Rollup cannot tree shake the components it needs fromcedar.mjs
. In consuming application builds, this results in Vite/Rollup building the entirety of the Cedar into a module, where it is eventually downloaded by end users.As a test, I configured Vite to build just the Climber's landing page bundle, stripped all Cedar components from all nested components within the page component. I imported a single Cedar component,
CdrContainer
, to see the resultant bundle.Within the compiled bundle, I expect to see just the
CdrContainer
code, however, I see the entirety of the Cedar library.Solution
This PR sets preserveModules to
true
which breaks up the largecedar.mjs
distributable into multiple ES modules. This allows the Cedar library to be tree shaken in consuming applications.I installed the
npm pack
ed tarball from this PR intoclimbers-site
. Using the same test setup, we see a major difference at build time:Now we only see
CdrContainer
code inclimber-3e7f1771.js
.Thats nearly a 80% reduction in the uncompressed bundle size (60% reduction on the gzipped version). Obviously, this would be a less dramatic difference the more unique Cedar components I used, but its still a major improvement.
Notes/caveats
I've taken some liberties with this PR that should be examined and reviewed by the team.
Removed UMD format from Vite config
In order to use
preserveModules
, we need to isolate a ES build in the Vite config.Using
fileName: '[name]'
preserves the directory structure of the output ES modules withindist
. This seems like the intuitive thing to do. However, if you prefer a flat output, you can opt to use the commented out function I left.I'm not sure if anybody uses the UMD module that Cedar outputs, but it case you'd still like this, I've created a separate
vite.umd.config.mjs
. You'd just need to run vite against this in your NPM build script.Updated
external
inrollupOptions.mjs
I've changed this to use a function that ensures any submodules of these dependencies are externalized. Without this, while using
preserveModules
, submodules fromcore-js
andlodash-es
get built into the distributables, which we don't want.History
When we first migrated to Vue 3 and Vite, Vite was on version 2. We validated that tree-shaking was working against apps built with Webpack 4 and Vite 2.
Webpack needed
PURE
annotations in the compiled code in order to tree shake stuff out, while Vite 2 seemed to work out of box.. or so we thought.It's unclear whether or not we mistook tree shaking for common chunks generated by Vite/Rollup. Its possible tree shaking hasn't been working since the migration but because we're serving smaller chunks, it appeared tree shaking was happening.
Reference