Find the cost of adding an npm package to your app's bundle size teardown.kelinci.dev
14
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: check for default via AST

Mary 4be2f932 65de9757

+28 -24
+27 -24
src/npm/bundler.ts
··· 65 65 const VIRTUAL_ENTRY_ID = '\0virtual:entry'; 66 66 67 67 /** 68 - * checks if a file likely has a default export. 69 - * looks for common patterns in ESM and CJS. 70 - */ 71 - function hasDefaultExport(source: string): boolean { 72 - // ESM patterns 73 - if (/\bexport\s+default\b/.test(source)) { 74 - return true; 75 - } 76 - if (/\bexport\s*\{\s*[^}]*\bdefault\b/.test(source)) { 77 - return true; 78 - } 79 - // CJS patterns (bundlers typically convert these to default exports) 80 - if (/\bmodule\.exports\s*=/.test(source)) { 81 - return true; 82 - } 83 - if (/\bexports\.default\s*=/.test(source)) { 84 - return true; 85 - } 86 - return false; 87 - } 88 - 89 - /** 90 68 * creates a virtual entry point that imports and re-exports from a specific subpath. 91 69 * 92 70 * @param packageName the package name ··· 225 203 if (resolved) { 226 204 try { 227 205 const source = volume.readFileSync(resolved.id, 'utf8') as string; 228 - includeDefault = hasDefaultExport(source); 206 + const ast = this.parse(source); 207 + 208 + for (const node of ast.body) { 209 + // export default ... 210 + if (node.type === 'ExportDefaultDeclaration') { 211 + includeDefault = true; 212 + break; 213 + } 214 + 215 + // export { default } from '...' or export { foo as default } 216 + if (node.type === 'ExportNamedDeclaration') { 217 + for (const spec of node.specifiers) { 218 + const exported = spec.exported; 219 + const name = exported.type === 'Literal' ? exported.value : exported.name; 220 + 221 + if (name === 'default') { 222 + includeDefault = true; 223 + break; 224 + } 225 + } 226 + 227 + if (includeDefault) { 228 + break; 229 + } 230 + } 231 + } 229 232 } catch { 230 - // couldn't read file, skip default export 233 + // couldn't read/parse file, skip default export 231 234 } 232 235 } 233 236 }
+1
src/npm/worker.ts
··· 2 2 import * as v from 'valibot'; 3 3 4 4 import { stripAnsi } from '../lib/strings'; 5 + 5 6 import { bundlePackage, type BundleOptions } from './bundler'; 6 7 import { progress } from './events'; 7 8 import { fetchPackagesToVolume } from './fetch';