Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Sichere ProgrammierungRecovering API Usage Automatically in Static Analysis?(20.09.2026 um 04:32 Uhr)
•
Sicherheitslücken (CVE)just dropped macos lpe - CVE-2026-43786(21.09.2026 um 21:48 Uhr)
••
Malware / Trojaner / VirenCDC-ACM Serial Interface Bypasses TCC on macOS(25.09.2026 um 19:18 Uhr)
•
Malware / Trojaner / VirenHow to start?(26.09.2026 um 00:24 Uhr)
•
Malware / Trojaner / VirenNeed an honest advice from seniors(26.09.2026 um 04:36 Uhr)
•
Malware / Trojaner / VirenFree malware analysis, reverse engineering and exploit development resources(27.09.2026 um 18:01 Uhr)
•••
Malware / Trojaner / VirenWhere to get resources and get started with malware dev?(30.09.2026 um 08:17 Uhr)
•
Sichere ProgrammierungRecovering API Usage Automatically in Static Analysis?(20.09.2026 um 04:32 Uhr)
•
Sicherheitslücken (CVE)just dropped macos lpe - CVE-2026-43786(21.09.2026 um 21:48 Uhr)
••
Malware / Trojaner / VirenCDC-ACM Serial Interface Bypasses TCC on macOS(25.09.2026 um 19:18 Uhr)
•
Malware / Trojaner / VirenHow to start?(26.09.2026 um 00:24 Uhr)
•
Malware / Trojaner / VirenNeed an honest advice from seniors(26.09.2026 um 04:36 Uhr)
•
Malware / Trojaner / VirenFree malware analysis, reverse engineering and exploit development resources(27.09.2026 um 18:01 Uhr)
•••
Malware / Trojaner / VirenWhere to get resources and get started with malware dev?(30.09.2026 um 08:17 Uhr)
•
Intelligence View
⚡ tsecurity.de Intelligence

Optimizing Vue.js Component Library Bundle Size: A Real-World Case Study

How I reduced my Vue component library from 388KB to 124KB (68% reduction) and solved dependency resolution issues The Problem: Massive Bundle Size and…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

How I reduced my Vue component library from 388KB to 124KB (68% reduction) and solved dependency resolution issues






The Problem: Massive Bundle Size and Dependency Hell






Initial Purpose: Consistency Across Multiple Frontend Products



When I first built the company's internal component library @zilla-tech/ace-ui, the primary goal was consistency. We had numerous frontend products across the organization, and we needed a way to use our components consistently across all projects. The library was designed to provide a unified design system and component API that all the team could rely on.



Initial Focus: Functionality, consistency, and developer experience

Bundle Size: Not a primary concern at the time





The Optimization Journey Begins



Several months after the initial development, as our library grew and more projects adopted it, bundle size became a critical concern. What started as a 388KB bundle was now causing performance issues and deployment headaches across our development team.





Initial Symptoms





  • Bundle size: 388KB (113.9KB gzipped) - way too large for a component library


  • Dependency resolution errors: Our projects couldn't resolve imports like libphonenumber-js, vue-tel-input, v-calendar


  • Vue mixin errors: Cannot read properties of undefined (reading 'mixin') in consuming projects


  • Complex installation: We had to manually install 7+ peer dependencies





The Root Cause



I had bundled all dependencies directly into the library, including heavy packages like:





  • v-calendar (~260KB)


  • vue-tel-input (~175KB)


  • @popperjs/core (~25KB)


  • dayjs (~12KB)


  • libphonenumber-js (~15KB)



This approach seemed logical at first - "just bundle everything so users don't have to install dependencies." But it created more problems than it solved.





The Journey: Three Optimization Approaches





Approach 1: Initial Peer Dependencies (v1.0.42)



My first attempt was to externalize all dependencies using peerDependencies:




{
"peerDependencies": {
"@popperjs/core": "^2.10.1",
"dayjs": "^1.11.13",
"libphonenumber-js": "^1.10.0",
"v-calendar": "^3.1.2",
"vue-router": "^4.0.0",
"vue-select": "^4.0.0-beta.1",
"vue-tel-input": "^9.3.0",
"floating-vue": "^5.2.2",
"remixicon": "^4.6.0"
}
}






Vite Configuration:




// vite.config.ts
rollupOptions: {
external: [
"vue", "v-calendar", "dayjs", "vue-select",
"vue-tel-input", "floating-vue", "@popperjs/core",
"vue-router", "libphonenumber-js"
]
}






Results:




  • ✅ Bundle size: ~30KB (87% reduction!)

  • ✅ Tree-shaking enabled

  • ❌ Complex installation process

  • ❌ Dependency resolution errors in host projects






The Hidden Problem: Nested Dependencies



After the initial optimization, I thought I was done. But then the team started encountering errors like:




✘ [ERROR] Could not resolve "libphonenumber-js"
✘ [ERROR] Could not resolve "vue-tel-input"
✘ [ERROR] Could not resolve "v-calendar"
✘ [ERROR] Could not resolve "vuex"






The Root Cause: I didn't understand that some packages have their own internal dependencies that also need to be externalized. For example:





  • vue-tel-input internally depends on libphonenumber-js


  • v-calendar internally depends on @popperjs/core

  • Some components were using vuex for state management



When I externalized vue-tel-input, I forgot that it would try to import libphonenumber-js internally, causing resolution errors.






Approach 2: Bundled Dependencies (v1.0.43 - First Attempt)



When our team complained about installation complexity and dependency resolution errors, I tried bundling dependencies:




{
"dependencies": {
"@popperjs/core": "^2.10.1",
"dayjs": "^1.11.13",
"libphonenumber-js": "^1.10.0",
"v-calendar": "^3.1.2",
"vue-router": "^4.0.0",
"vue-select": "^4.0.0-beta.1",
"vue-tel-input": "^9.3.0"
}
}






Results:




  • ✅ Simple installation: npm install @zilla-tech/ace-ui

  • ✅ No dependency resolution errors

  • ❌ Bundle size: ~400KB (even larger!)

  • ❌ Version conflicts

  • ❌ Duplicate dependencies






The Vue Mixin Error Mystery



Even with bundled dependencies, our team was still getting this cryptic error:




Uncaught TypeError: Cannot read properties of undefined (reading 'mixin')
at screens.js:53:5






This was caused by:




  • Multiple Vue instances in the host project

  • Missing Vue deduplication in Vite config

  • Incorrect Vue alias configuration






Approach 3: Optimized Peer Dependencies (v1.0.43 - Final)



I realized the issue wasn't the peer dependencies approach itself, but my incomplete understanding of nested dependencies and proper configuration. I went back to peer dependencies but with:





  1. Complete dependency mapping - Including all nested dependencies


  2. Better documentation - Clear installation instructions


  3. Host project guidance - Proper Vite configuration examples


  4. Vuex refactoring - Removed Vuex dependencies from components






The Vuex Refactoring Challenge



One of the biggest issues was that several components were using Vuex for state management:




// Before: Components using Vuex
import { mapActions } from 'vuex';

export default {
methods: {
...mapActions('notification', ['showToast']),
handleError() {
this.showToast({ message: 'Error occurred' });
}
}
}






This created a hard dependency on Vuex, which users might not have installed. I refactored these components to use internal services instead:




// After: Using internal services
import { showToast } from '../../Notification/Toast/toastService';

export default {
methods: {
handleError() {
showToast({ message: 'Error occurred' });
}
}
}






Components Refactored:





  • Select component - Toast notifications


  • Upload component - Toast notifications


  • GoogleAutoComplete component - Alert notifications


  • CardSelect component - Data fetching (converted to props/events)






Complete Dependency Mapping



The key insight was understanding the complete dependency tree:




ace-ui components
├── vue-tel-input
│ └── libphonenumber-js (nested dependency!)
├── v-calendar
│ └── @popperjs/core (nested dependency!)
├── vue-select
├── dayjs
├── vue-router
└── vuex (removed through refactoring)






I had to externalize ALL dependencies, including the nested ones that packages import internally.






The Solution: Optimized Peer Dependencies






1. Proper Vite Configuration






// vite.config.ts
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/components/index.js'),
name: 'AceUI',
fileName: 'ace-ui',
formats: ["es", "cjs"],
},
rollupOptions: {
// Externalize all peer dependencies
external: [
"vue", "v-calendar", "dayjs", "vue-select",
"vue-tel-input", "floating-vue", "@popperjs/core",
"vue-router", "libphonenumber-js", "vuex"
],
output: [
{
format: "es",
entryFileNames: "[name].mjs",
preserveModules: true,
preserveModulesRoot: "src",
exports: "named",
dir: "../ace-ui/es",
},
{
format: "cjs",
entryFileNames: "[name].js",
preserveModules: true,
preserveModulesRoot: "src",
exports: "named",
dir: "../ace-ui/lib",
}
]
},
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
}
}
}
});









2. Clear Installation Instructions



Instead of leaving our team to figure out dependencies, I provided comprehensive installation instructions:




# Install ace-ui
npm install @zilla-tech/ace-ui

# Install required peer dependencies
npm install vue@^3.0.0 @popperjs/core@^2.10.1 dayjs@^1.11.13 libphonenumber-js@^1.10.0 v-calendar@^3.1.2 vue-router@^4.0.0 vue-select@^4.0.0-beta.1 vue-tel-input@^9.3.0

# Install optional dependencies (only if using those components)
npm install floating-vue@^5.2.2 remixicon@^4.6.0









3. Host Project Vite Configuration



I also provided guidance for our projects to properly configure Vite:




// Host project vite.config.js
export default defineConfig({
optimizeDeps: {
include: [
'@zilla-tech/ace-ui',
'vue-tel-input',
'libphonenumber-js',
'v-calendar',
'dayjs',
'vue-select',
'floating-vue',
'@popperjs/core'
],
},
resolve: {
alias: {
'vue': fileURLToPath(new URL('./node_modules/vue/dist/vue.esm-bundler.js', import.meta.url))
},
dedupe: ['vue'], // Prevent multiple Vue instances
},
})









4. Troubleshooting Process



When our team reported errors, I had to debug systematically:



Step 1: Identify Missing Dependencies




# Check what's actually being imported
grep -r "import.*from" src/components/ | grep -E "(vue-tel-input|libphonenumber|v-calendar)"






Step 2: Check Nested Dependencies




# Look at package.json of dependencies
npm info vue-tel-input dependencies
npm info v-calendar dependencies






Step 3: Test Host Project Configuration




// Add debugging to vite.config.js
console.log('External dependencies:', rollupOptions.external);
console.log('Optimized deps:', optimizeDeps.include);






Step 4: Clear Caches




# Clear all caches when debugging
rm -rf node_modules/.vite
rm -rf node_modules/@zilla-tech
npm install









5. Common Project Issues and Solutions



Issue 1: Missing Peer Dependencies




# Error: Could not resolve "libphonenumber-js"
# Solution: Install the missing dependency
npm install libphonenumber-js






Issue 2: Vue Instance Conflicts




// Error: Cannot read properties of undefined (reading 'mixin')
// Solution: Add Vue deduplication
resolve: {
dedupe: ['vue'],
alias: {
'vue': path.resolve('./node_modules/vue/dist/vue.esm-bundler.js')
}
}






Issue 3: Incorrect Externalization




// Error: Dependencies bundled when they should be external
// Solution: Check Vite external array includes all peer dependencies
external: [
"vue", "v-calendar", "dayjs", "vue-select",
"vue-tel-input", "floating-vue", "@popperjs/core",
"vue-router", "libphonenumber-js" // Don't forget nested deps!
]









The Results: Massive Success






Bundle Size Reduction





  • Before: 388KB (113.9KB gzipped)


  • After: 124KB (35KB gzipped)


  • Reduction: 68% smaller!






Developer Experience Improvements




  • ✅ Clear installation instructions

  • ✅ No more dependency resolution errors

  • ✅ Proper Vue instance management

  • ✅ Tree-shaking enabled

  • ✅ Version control for dependencies






Performance Benefits




  • ✅ Faster initial load times

  • ✅ Better caching (dependencies cached separately)

  • ✅ Reduced memory usage

  • ✅ Smaller JavaScript bundles






Key Learnings






1. Nested Dependencies Are Critical



The biggest lesson: When externalizing dependencies, you must account for ALL nested dependencies. A package like vue-tel-input might internally import libphonenumber-js, which also needs to be externalized.



How to identify nested dependencies:




# Check what dependencies a package actually uses
npm info vue-tel-input dependencies
npm info v-calendar dependencies

# Look at the actual imports in node_modules
grep -r "import.*from" node_modules/vue-tel-input/









2. Peer Dependencies vs Dependencies



Peer Dependencies are perfect for libraries when:




  • Bundle size matters

  • You want version control

  • Dependencies are commonly used across projects

  • Tree-shaking is important



Dependencies are better when:




  • Installation simplicity is critical

  • Dependencies are rarely used elsewhere

  • Bundle size is less important






3. Component Architecture Matters



Avoid hard dependencies in components:




  • Don't use vuex directly in components

  • Use internal services instead

  • Convert data fetching to props/events

  • Make components truly reusable






4. Documentation is Everything



The peer dependencies approach only works with excellent documentation. Your team needs:




  • Clear installation instructions

  • Explanation of why peer dependencies are used

  • Project configuration guidance

  • Troubleshooting tips

  • Complete dependency list






5. Vite Configuration Matters



Proper Vite configuration is crucial:




  • Externalize peer dependencies correctly (including nested ones!)

  • Use preserveModules for tree-shaking

  • Configure proper output formats

  • Set up minification properly

  • Include ALL dependencies in external array






6. Project Setup



Your projects need proper configuration:




  • Include dependencies in optimizeDeps.include

  • Use Vue deduplication (dedupe: ['vue'])

  • Configure proper aliases

  • Clear Vite cache when needed

  • Install ALL peer dependencies






7. Debugging Strategy



When things go wrong:




  1. Check the complete dependency tree

  2. Verify all nested dependencies are externalized

  3. Test host project configuration

  4. Clear all caches

  5. Check for Vue instance conflicts






8. The Trade-off is Worth It



While peer dependencies require more setup, the benefits outweigh the costs:




  • Massive bundle size reduction (68% in our case)

  • Better performance

  • Version control

  • Tree-shaking

  • No duplicate dependencies






Best Practices for Vue Component Libraries






1. Use Peer Dependencies Strategically






{
"peerDependencies": {
"vue": "^3.0.0", // Always peer - version control critical
"heavy-library": "^1.0.0", // Peer - large, commonly used
"small-utility": "^2.0.0" // Could be bundled - small, rarely used
}
}









2. Provide Clear Installation Instructions






# One-liner for all dependencies
npm install @your-library vue@^3.0.0 dependency1 dependency2 dependency3









3. Configure Vite Properly






// Externalize peer dependencies
external: ["vue", "heavy-dependency"],
// Use preserveModules for tree-shaking
preserveModules: true,
// Minify aggressively
minify: 'terser'









4. Document Host Project Setup



Provide clear guidance for consuming projects:




  • Vite configuration examples

  • Troubleshooting common issues

  • Performance optimization tips






5. Test Both Approaches



Before deciding on dependencies vs peerDependencies:




  • Measure bundle sizes

  • Test installation complexity

  • Check for version conflicts

  • Validate tree-shaking






Conclusion



Optimizing a Vue component library's bundle size requires careful consideration of dependencies, proper Vite configuration, and excellent documentation. While peer dependencies add installation complexity, they provide massive benefits in bundle size, performance, and flexibility.



The key is finding the right balance between developer experience and performance. In my case, the 68% bundle size reduction and improved performance made the additional installation steps worthwhile.



Final Stats:




  • Bundle size: 388KB → 124KB (68% reduction)

  • Gzipped size: 113.9KB → 35KB (69% reduction)

  • Installation: Complex but well-documented

  • Performance: Significantly improved

  • Developer experience: Much better with proper setup



The journey taught me that optimization isn't just about code - it's about the entire developer experience, from installation to performance to documentation.






Have you faced similar challenges with Vue component libraries? What strategies worked for you? Let me know in the comments!

🔍 CTI & Forensik

Cyber Threat Intelligence & Forensik

Bedrohungsgraph · ATT&CK-Mapping · Exploit-Belege
CTI Threat Relationship Graph
Akteure · Techniken · Beziehungen
2 Knoten · 1 Relationen
CVE / Incident Threat Actor Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Optimizing Vue.js Component Library Bundle Size: A Real-World Case Study

Thematisch verwandte Begriffe: Optimizing, Vuejs, Component, Library · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag