|
| 1 | +# External Dependency Stubs |
| 2 | + |
| 3 | +This directory contains stub modules used during the external package bundling process to replace unused dependencies and reduce bundle size. |
| 4 | + |
| 5 | +**Philosophy:** Be conservative. Only stub dependencies that are provably unused or already disabled. |
| 6 | + |
| 7 | +## How It Works |
| 8 | + |
| 9 | +The build-externals system bundles external npm dependencies (like pacote, cacache, make-fetch-happen) into standalone modules in `dist/external/`. During bundling, esbuild uses the stubs in this directory to replace dependencies we don't need. |
| 10 | + |
| 11 | +The stub configuration lives in `../esbuild-config.mjs`, which maps module patterns to stub files: |
| 12 | + |
| 13 | +```javascript |
| 14 | +const STUB_MAP = { |
| 15 | + '^(encoding|iconv-lite)$': 'encoding.cjs', |
| 16 | + '^debug$': 'debug.cjs', |
| 17 | +} |
| 18 | +``` |
| 19 | + |
| 20 | +When esbuild encounters `require('encoding')` during bundling, it replaces it with the contents of `encoding.cjs` instead of bundling the entire encoding package. |
| 21 | + |
| 22 | +## Stub Types |
| 23 | + |
| 24 | +This directory provides both active stubs (currently in use) and utility stubs (available for future use): |
| 25 | + |
| 26 | +### Utility Stubs (Available for Use) |
| 27 | + |
| 28 | +**`empty.cjs`** - Empty object for unused modules |
| 29 | +- Exports: `{}` |
| 30 | +- Use case: Dependencies referenced but never executed |
| 31 | + |
| 32 | +**`noop.cjs`** - No-op function for optional features |
| 33 | +- Exports: Function that does nothing |
| 34 | +- Use case: Logging, debugging, optional callbacks |
| 35 | + |
| 36 | +**`throw.cjs`** - Error-throwing for unexpected usage |
| 37 | +- Exports: Function that throws descriptive error |
| 38 | +- Use case: Code paths that should never execute |
| 39 | + |
| 40 | +### Active Stubs (Currently in Use) |
| 41 | + |
| 42 | +**`encoding.cjs`** - Character encoding stub |
| 43 | +- Replaces: `encoding`, `iconv-lite` |
| 44 | +- Reason: We only use UTF-8, don't need legacy encoding support |
| 45 | +- Size impact: ~9KB saved (pacote, make-fetch-happen) |
| 46 | + |
| 47 | +**`debug.cjs`** - Debug logging stub |
| 48 | +- Replaces: `debug` module |
| 49 | +- Reason: Already compiled out via `process.env.DEBUG = undefined` |
| 50 | +- Size impact: ~9KB saved |
| 51 | + |
| 52 | +## Adding New Stubs |
| 53 | + |
| 54 | +**Before adding a stub:** |
| 55 | +1. Verify the dependency is truly unused via code analysis |
| 56 | +2. Check if it's already disabled via esbuild `define` constants |
| 57 | +3. Consider the risk - conservative only! |
| 58 | + |
| 59 | +**To add a stub:** |
| 60 | +1. Create stub file in this directory |
| 61 | +2. Document what it replaces and why it's safe |
| 62 | +3. Add entry to `STUB_MAP` in `../esbuild-config.mjs` |
| 63 | +4. Test: `pnpm build && pnpm test` |
| 64 | +5. Verify size savings: `du -sh dist/external` |
| 65 | + |
| 66 | +## Testing Stubs |
| 67 | + |
| 68 | +After adding stubs, verify: |
| 69 | +1. Build succeeds: `pnpm build` |
| 70 | +2. Tests pass: `pnpm test` |
| 71 | +3. No runtime errors in dependent packages |
| 72 | +4. Bundle size decreased as expected |
0 commit comments