I'm learning about optimization and I've found that either I've misunderstood something or every article about Vue and the examples are basically wrong.
It's about bundle size and tree shaking.
When I use composable like this—and this pattern is mentioned in every tutorial and probably even on the official Vue.js website—it will be included in its entirety in the resulting bundle, and that's wrong!
Option 1
const counter = ref(0);
export function useCounter() {
const increment = () => counter.value++;
const decrement = () => counter.value--;
return { counter, increment, decrement };
}
// Usage:
import { useCounter } from './counter'
const { increment } = useCounter() // ❌ The bundle contains the ENTIRE useCounter function.
Option 2 - this way, after tree shaking, the bundle only contains what I actually use.
const counter = ref(0);
export const increment = () => counter.value++;
export const decrement = () => counter.value--;
// Usage:
import { increment } from './counter' // ✅ The bundle contains ONLY increment
But option two is not encapsulated, and generally the concept does not always fit.
Otherwise, for example, this is the Vue icon, and here it has composables similarly https://michaelnthiessen.com/inline-composables (listed here as inline, but it can be an external file and imported).
So what is the correct approach? I am confused because I am using it incorrectly.