@node-cli/bundlecheck 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -7
- package/dist/bundlecheck.js +10 -1
- package/dist/bundlecheck.js.map +1 -1
- package/dist/bundler.d.ts +19 -2
- package/dist/bundler.js +179 -30
- package/dist/bundler.js.map +1 -1
- package/dist/cache.js +29 -6
- package/dist/cache.js.map +1 -1
- package/dist/defaults.d.ts +10 -0
- package/dist/defaults.js +18 -1
- package/dist/defaults.js.map +1 -1
- package/dist/exports-installer.d.ts +19 -0
- package/dist/exports-installer.js +115 -0
- package/dist/exports-installer.js.map +1 -0
- package/dist/exports.d.ts +43 -0
- package/dist/exports.js +330 -0
- package/dist/exports.js.map +1 -0
- package/dist/index.d.ts +81 -2
- package/dist/index.js +64 -7
- package/dist/index.js.map +1 -1
- package/dist/parse.js +2 -2
- package/dist/parse.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ A CLI tool to check the bundle size of npm packages, similar to [bundlephobia.co
|
|
|
11
11
|
- Interactive version selection with `--versions` flag
|
|
12
12
|
- Bundle size trend analysis with `--trend` flag (bar graph across versions)
|
|
13
13
|
- Support for checking specific exports (tree-shaking)
|
|
14
|
-
-
|
|
14
|
+
- Smart externalization of React and React-DOM (only when declared as dependencies)
|
|
15
15
|
- Raw and gzip sizes with configurable compression level
|
|
16
16
|
- **Platform support**: target `browser` (default) or `node` with smart auto-detection
|
|
17
17
|
- Custom npm registry support (for private registries)
|
|
@@ -122,7 +122,7 @@ bundlecheck @versini/ui-panel@1.0.0
|
|
|
122
122
|
# Check specific exports from @mantine/core
|
|
123
123
|
bundlecheck @mantine/core "ScrollArea,Button"
|
|
124
124
|
|
|
125
|
-
# Check react
|
|
125
|
+
# Check react with all dependencies bundled (no externals)
|
|
126
126
|
bundlecheck react -n
|
|
127
127
|
|
|
128
128
|
# Add vue and svelte as additional externals
|
|
@@ -166,7 +166,7 @@ npm install @node-cli/bundlecheck
|
|
|
166
166
|
### Basic Usage
|
|
167
167
|
|
|
168
168
|
```js
|
|
169
|
-
import { getBundleStats, getBundleTrend, getPackageVersions } from "@node-cli/bundlecheck";
|
|
169
|
+
import { getBundleStats, getBundleTrend, getPackageVersions, getPackageExports } from "@node-cli/bundlecheck";
|
|
170
170
|
|
|
171
171
|
// Get bundle stats for a single package
|
|
172
172
|
const stats = await getBundleStats({
|
|
@@ -181,7 +181,7 @@ console.log(stats);
|
|
|
181
181
|
// rawSizeFormatted: "229.07 kB",
|
|
182
182
|
// gzipSizeFormatted: "44.61 kB",
|
|
183
183
|
// exports: [],
|
|
184
|
-
// externals: ["react", "react-dom"],
|
|
184
|
+
// externals: ["react", "react-dom"], // Only present because @mantine/core has these as peerDependencies
|
|
185
185
|
// dependencies: ["@floating-ui/react", ...],
|
|
186
186
|
// platform: "browser",
|
|
187
187
|
// gzipLevel: 5,
|
|
@@ -226,6 +226,13 @@ const versions = await getPackageVersions({
|
|
|
226
226
|
});
|
|
227
227
|
console.log(versions.tags.latest); // "7.0.0"
|
|
228
228
|
console.log(versions.versions.slice(0, 5)); // ["7.0.0", "6.0.21", "6.0.20", ...]
|
|
229
|
+
|
|
230
|
+
// Get named exports from a package
|
|
231
|
+
const exports = await getPackageExports({
|
|
232
|
+
package: "date-fns@3.6.0",
|
|
233
|
+
});
|
|
234
|
+
console.log(`Found ${exports.count} exports`);
|
|
235
|
+
console.log(exports.exports.slice(0, 5).map(e => e.name)); // ["add", "addBusinessDays", "addDays", ...]
|
|
229
236
|
```
|
|
230
237
|
|
|
231
238
|
### API Reference
|
|
@@ -241,7 +248,7 @@ Get bundle size statistics for a single package.
|
|
|
241
248
|
| `package` | `string` | (required) | Package name with optional version (e.g., `lodash@4.17.0`) |
|
|
242
249
|
| `exports` | `string[]` | `undefined`| Specific exports to measure (tree-shaking) |
|
|
243
250
|
| `external` | `string[]` | `undefined`| Additional packages to mark as external |
|
|
244
|
-
| `noExternal` | `boolean` | `false` | Bundle everything
|
|
251
|
+
| `noExternal` | `boolean` | `false` | Bundle everything (no externals, even react/react-dom) |
|
|
245
252
|
| `gzipLevel` | `number` | `5` | Gzip compression level (1-9) |
|
|
246
253
|
| `registry` | `string` | `undefined`| Custom npm registry URL |
|
|
247
254
|
| `platform` | `"browser" \| "node" \| "auto"` | `"auto"` | Target platform |
|
|
@@ -263,6 +270,7 @@ type BundleStats = {
|
|
|
263
270
|
rawSizeFormatted: string; // Human-readable (e.g., "45.2 kB")
|
|
264
271
|
gzipSizeFormatted: string | null;
|
|
265
272
|
fromCache: boolean; // Whether result was from cache
|
|
273
|
+
namedExportCount: number; // Total named exports in package
|
|
266
274
|
};
|
|
267
275
|
```
|
|
268
276
|
|
|
@@ -333,6 +341,47 @@ type PackageVersions = {
|
|
|
333
341
|
};
|
|
334
342
|
```
|
|
335
343
|
|
|
344
|
+
#### `getPackageExports(options)`
|
|
345
|
+
|
|
346
|
+
Get the named exports of an npm package by analyzing its TypeScript declarations.
|
|
347
|
+
|
|
348
|
+
**Options:**
|
|
349
|
+
|
|
350
|
+
| Option | Type | Default | Description |
|
|
351
|
+
| ---------- | -------- | ---------- | ------------------------------------------------ |
|
|
352
|
+
| `package` | `string` | (required) | Package name with optional version |
|
|
353
|
+
| `registry` | `string` | `undefined`| Custom npm registry URL |
|
|
354
|
+
|
|
355
|
+
**Returns:** `Promise<PackageExports>`
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
type PackageExports = {
|
|
359
|
+
packageName: string; // Package name
|
|
360
|
+
packageVersion: string; // Resolved version
|
|
361
|
+
exports: PackageExport[]; // All named exports (including types)
|
|
362
|
+
count: number; // Total count (including types)
|
|
363
|
+
runtimeExports: PackageExport[]; // Runtime exports only (no types/interfaces)
|
|
364
|
+
runtimeCount: number; // Count of runtime exports
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
type PackageExport = {
|
|
368
|
+
name: string; // Export name (e.g., "Button")
|
|
369
|
+
kind: "function" | "class" | "const" | "type" | "interface" | "enum" | "unknown";
|
|
370
|
+
};
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Example:**
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
const result = await getPackageExports({
|
|
377
|
+
package: "@mantine/core",
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
console.log(result.count); // 1056 (all exports including types)
|
|
381
|
+
console.log(result.runtimeCount); // 365 (only importable exports)
|
|
382
|
+
console.log(result.runtimeExports[0]); // { name: "Accordion", kind: "unknown" }
|
|
383
|
+
```
|
|
384
|
+
|
|
336
385
|
### Utility Functions
|
|
337
386
|
|
|
338
387
|
```js
|
|
@@ -386,9 +435,11 @@ bundlecheck fastify -p server # "server" is an alias for "node"
|
|
|
386
435
|
|
|
387
436
|
## Default Externals
|
|
388
437
|
|
|
389
|
-
|
|
438
|
+
When a package declares `react` or `react-dom` in its `dependencies` or `peerDependencies`, they are automatically marked as external (not included in the bundle size). This matches how these packages would typically be used in a real application where React is provided by the host application.
|
|
439
|
+
|
|
440
|
+
For packages that don't depend on React, these are not automatically externalized.
|
|
390
441
|
|
|
391
|
-
To include React
|
|
442
|
+
To include all dependencies (including React when present) in the bundle size calculation, use the `--no-external` flag.
|
|
392
443
|
|
|
393
444
|
## Custom Registry
|
|
394
445
|
|
package/dist/bundlecheck.js
CHANGED
|
@@ -21,9 +21,18 @@ const log = new Logger({
|
|
|
21
21
|
const green = kleur.green;
|
|
22
22
|
const platformLabel = result.platform === "node" ? "node" : "browser";
|
|
23
23
|
const platformNote = isAutoDetected ? " (auto-detected)" : "";
|
|
24
|
+
// Format exports display.
|
|
25
|
+
let exportsDisplay;
|
|
26
|
+
if (result.exports.length > 0) {
|
|
27
|
+
exportsDisplay = `{ ${result.exports.join(", ")} }`;
|
|
28
|
+
} else if (result.namedExportCount > 0) {
|
|
29
|
+
exportsDisplay = `${result.namedExportCount} named exports (entire package)`;
|
|
30
|
+
} else {
|
|
31
|
+
exportsDisplay = "* (entire package)";
|
|
32
|
+
}
|
|
24
33
|
log.printBox([
|
|
25
34
|
`${blue("Package:")} ${result.packageName} (${blue("version:")} ${result.packageVersion})`,
|
|
26
|
-
|
|
35
|
+
`${blue("Exports:")} ${exportsDisplay}`,
|
|
27
36
|
"",
|
|
28
37
|
`${blue("Raw size:")} ${formatBytes(result.rawSize)}`,
|
|
29
38
|
result.gzipSize !== null ? `${blue("Gzip size:")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})` : `${blue("Gzip size:")} N/A (not applicable for node platform)`,
|
package/dist/bundlecheck.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bundlecheck.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* istanbul ignore file */\n\nimport { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport {\n\tcheckBundleSize,\n\tformatBytes,\n\tgetExternals,\n\tparsePackageSpecifier,\n} from \"./bundler.js\";\nimport {\n\tgetCachedResult,\n\tnormalizeCacheKey,\n\tsetCachedResult,\n} from \"./cache.js\";\nimport { normalizePlatform, TREND_VERSION_COUNT } from \"./defaults.js\";\nimport { config } from \"./parse.js\";\nimport {\n\tanalyzeTrend,\n\trenderTrendGraph,\n\tselectTrendVersions,\n} from \"./trend.js\";\nimport { fetchPackageVersions, promptForVersion } from \"./versions.js\";\n\nconst flags = config.flags;\nconst parameters = config.parameters;\n\n// Disable kleur colors when --boring flag is set.\nkleur.enabled = !flags?.boring;\n\nconst log = new Logger({\n\tboring: flags?.boring,\n});\n\n/**\n * Display bundle result in a formatted box.\n */\nfunction displayResult(\n\tresult: {\n\t\tpackageName: string;\n\t\tpackageVersion: string;\n\t\texports: string[];\n\t\trawSize: number;\n\t\tgzipSize: number | null;\n\t\tgzipLevel: number;\n\t\texternals: string[];\n\t\tdependencies: string[];\n\t\tplatform: \"browser\" | \"node\";\n\t},\n\tisAutoDetected: boolean,\n): void {\n\tconst blue = kleur.blue;\n\tconst green = kleur.green;\n\n\tconst platformLabel = result.platform === \"node\" ? \"node\" : \"browser\";\n\tconst platformNote = isAutoDetected ? \" (auto-detected)\" : \"\";\n\n\tlog.printBox(\n\t\t[\n\t\t\t`${blue(\"Package:\")} ${result.packageName} (${blue(\"version:\")} ${result.packageVersion})`,\n\t\t\tresult.exports.length > 0\n\t\t\t\t? `${blue(\"Exports:\")} { ${result.exports.join(\", \")} }`\n\t\t\t\t: `${blue(\"Exports:\")} * (entire package)`,\n\t\t\t\"\",\n\t\t\t`${blue(\"Raw size:\")} ${formatBytes(result.rawSize)}`,\n\t\t\tresult.gzipSize !== null\n\t\t\t\t? `${blue(\"Gzip size:\")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`\n\t\t\t\t: `${blue(\"Gzip size:\")} N/A (not applicable for node platform)`,\n\t\t\t\"\",\n\t\t\tresult.externals.length > 0\n\t\t\t\t? `${blue(\"Externals:\")} ${result.externals.join(\", \")}`\n\t\t\t\t: `${blue(\"Externals:\")} ${green(\"none\")}`,\n\t\t\tresult.dependencies.length > 0\n\t\t\t\t? `${blue(\"Dependencies:\")} ${result.dependencies.join(\", \")}`\n\t\t\t\t: `${blue(\"Dependencies:\")} ${green(\"none\")}`,\n\t\t\t`${blue(\"Platform:\")} ${platformLabel}${platformNote}`,\n\t\t],\n\t\t{\n\t\t\tborderStyle: \"round\",\n\t\t\talign: \"left\",\n\t\t},\n\t);\n}\n\nasync function main() {\n\tlet packageName = parameters?.[\"0\"];\n\n\tif (!packageName) {\n\t\tlog.error(\"Package name is required\");\n\t\tconfig.showHelp?.();\n\t\tprocess.exit(1);\n\t}\n\n\t// Parse additional externals if provided (comma-separated).\n\tlet additionalExternals: string[] | undefined;\n\tif (flags?.external) {\n\t\tadditionalExternals = flags.external\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// Parse exports if provided (comma-separated).\n\tlet exports: string[] | undefined;\n\tconst exportsArg = parameters?.[\"1\"];\n\tif (exportsArg) {\n\t\texports = exportsArg\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// Normalize platform from flag (handles aliases like \"web\" → \"browser\").\n\tconst platform = normalizePlatform(flags?.platform);\n\n\t/**\n\t * If --trend flag is set, show bundle size trend across versions --trend alone\n\t * uses default (5), --trend N uses N versions.\n\t */\n\tconst trendValue = flags?.trend;\n\tif (trendValue !== undefined) {\n\t\tconst parsedCount = Number.parseInt(trendValue, 10);\n\t\tconst versionCount =\n\t\t\t!Number.isNaN(parsedCount) && parsedCount > 0\n\t\t\t\t? parsedCount\n\t\t\t\t: TREND_VERSION_COUNT;\n\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\t// Construct the full package path including subpath if present.\n\t\t\tconst fullPackagePath = subpath ? `${name}/${subpath}` : name;\n\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions } = await fetchPackageVersions({\n\t\t\t\tpackageName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Select versions for trend.\n\t\t\tconst trendVersions = selectTrendVersions(versions, versionCount);\n\n\t\t\tlog.info(\n\t\t\t\t`Analyzing ${trendVersions.length} versions: ${trendVersions.join(\", \")}`,\n\t\t\t);\n\t\t\tlog.info(\"\");\n\n\t\t\tconst results = await analyzeTrend({\n\t\t\t\tpackageName: fullPackagePath,\n\t\t\t\tversions: trendVersions,\n\t\t\t\texports,\n\t\t\t\tadditionalExternals,\n\t\t\t\tnoExternal: flags?.noExternal,\n\t\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\t\tboring: flags?.boring,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t\tplatform,\n\t\t\t\tforce: flags?.force,\n\t\t\t});\n\n\t\t\tif (results.length === 0) {\n\t\t\t\tlog.error(\"Failed to analyze any versions\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Render and display the trend graph.\n\t\t\tconst graphLines = renderTrendGraph(\n\t\t\t\tfullPackagePath,\n\t\t\t\tresults,\n\t\t\t\tflags?.boring,\n\t\t\t);\n\t\t\tfor (const line of graphLines) {\n\t\t\t\tlog.log(line);\n\t\t\t}\n\n\t\t\tprocess.exit(0);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to analyze trend: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// If --versions flag is set, fetch and prompt for version selection.\n\tif (flags?.versions) {\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions, tags } = await fetchPackageVersions({\n\t\t\t\tpackageName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst selectedVersion = await promptForVersion(name, versions, tags);\n\t\t\t// Rebuild specifier preserving any subpath.\n\t\t\tpackageName = subpath\n\t\t\t\t? `${name}/${subpath}@${selectedVersion}`\n\t\t\t\t: `${name}@${selectedVersion}`;\n\t\t\tlog.info(`\\nSelected: ${packageName}`);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to fetch versions: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tlog.info(`\\nAnalyzing bundle size for: ${packageName}`);\n\tif (exports && exports.length > 0) {\n\t\tlog.info(`Exports: { ${exports.join(\", \")} }`);\n\t}\n\n\ttry {\n\t\t// Parse package specifier to get name and version.\n\t\tconst { name: baseName, version: requestedVersion } =\n\t\t\tparsePackageSpecifier(packageName);\n\n\t\t// Resolve \"latest\" to actual version for cache key.\n\t\tlet resolvedVersion = requestedVersion;\n\t\tif (requestedVersion === \"latest\") {\n\t\t\tconst { tags } = await fetchPackageVersions({\n\t\t\t\tpackageName: baseName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\t\t\tresolvedVersion = tags.latest || requestedVersion;\n\t\t}\n\n\t\t// Compute externals for cache key (same logic as bundler).\n\t\tconst externals = getExternals(\n\t\t\tbaseName,\n\t\t\tadditionalExternals,\n\t\t\tflags?.noExternal,\n\t\t);\n\n\t\t/**\n\t\t * Build cache key.\n\t\t * NOTE: platform can be undefined (auto-detect), which is stored as \"auto\" in cache.\n\t\t */\n\t\tconst cacheKey = normalizeCacheKey({\n\t\t\tpackageName: baseName,\n\t\t\tversion: resolvedVersion,\n\t\t\texports,\n\t\t\tplatform,\n\t\t\tgzipLevel: flags?.gzipLevel ?? 5,\n\t\t\texternals,\n\t\t\tnoExternal: flags?.noExternal ?? false,\n\t\t});\n\n\t\t// Check cache (unless --force flag is set).\n\t\tif (!flags?.force) {\n\t\t\tconst cached = getCachedResult(cacheKey);\n\t\t\tif (cached) {\n\t\t\t\tlog.info(\"NOTE: Using cached results\\n\");\n\t\t\t\tdisplayResult(cached, platform === undefined);\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t}\n\n\t\tlog.info(\"Please wait, installing and bundling...\\n\");\n\n\t\tconst result = await checkBundleSize({\n\t\t\tpackageName,\n\t\t\texports,\n\t\t\tadditionalExternals,\n\t\t\tnoExternal: flags?.noExternal,\n\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\tregistry: flags?.registry,\n\t\t\tplatform,\n\t\t});\n\n\t\t// Store result in cache.\n\t\tsetCachedResult(cacheKey, result);\n\n\t\tdisplayResult(result, platform === undefined);\n\n\t\tprocess.exit(0);\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tlog.error(`Failed to analyze bundle size: ${errorMessage}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nmain();\n"],"names":["Logger","kleur","checkBundleSize","formatBytes","getExternals","parsePackageSpecifier","getCachedResult","normalizeCacheKey","setCachedResult","normalizePlatform","TREND_VERSION_COUNT","config","analyzeTrend","renderTrendGraph","selectTrendVersions","fetchPackageVersions","promptForVersion","flags","parameters","enabled","boring","log","displayResult","result","isAutoDetected","blue","green","platformLabel","platform","platformNote","printBox","packageName","packageVersion","exports","length","join","rawSize","gzipSize","gzipLevel","externals","dependencies","borderStyle","align","main","error","showHelp","process","exit","additionalExternals","external","split","map","e","trim","filter","Boolean","exportsArg","trendValue","trend","undefined","parsedCount","Number","parseInt","versionCount","isNaN","name","subpath","fullPackagePath","info","versions","registry","trendVersions","results","noExternal","force","graphLines","line","errorMessage","Error","message","String","tags","selectedVersion","baseName","version","requestedVersion","resolvedVersion","latest","cacheKey","cached"],"mappings":";AAEA,wBAAwB,GAExB,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,WAAW,QAAQ;AAC1B,SACCC,eAAe,EACfC,WAAW,EACXC,YAAY,EACZC,qBAAqB,QACf,eAAe;AACtB,SACCC,eAAe,EACfC,iBAAiB,EACjBC,eAAe,QACT,aAAa;AACpB,SAASC,iBAAiB,EAAEC,mBAAmB,QAAQ,gBAAgB;AACvE,SAASC,MAAM,QAAQ,aAAa;AACpC,SACCC,YAAY,EACZC,gBAAgB,EAChBC,mBAAmB,QACb,aAAa;AACpB,SAASC,oBAAoB,EAAEC,gBAAgB,QAAQ,gBAAgB;AAEvE,MAAMC,QAAQN,OAAOM,KAAK;AAC1B,MAAMC,aAAaP,OAAOO,UAAU;AAEpC,kDAAkD;AAClDjB,MAAMkB,OAAO,GAAG,CAACF,OAAOG;AAExB,MAAMC,MAAM,IAAIrB,OAAO;IACtBoB,QAAQH,OAAOG;AAChB;AAEA;;CAEC,GACD,SAASE,cACRC,MAUC,EACDC,cAAuB;IAEvB,MAAMC,OAAOxB,MAAMwB,IAAI;IACvB,MAAMC,QAAQzB,MAAMyB,KAAK;IAEzB,MAAMC,gBAAgBJ,OAAOK,QAAQ,KAAK,SAAS,SAAS;IAC5D,MAAMC,eAAeL,iBAAiB,qBAAqB;IAE3DH,IAAIS,QAAQ,CACX;QACC,GAAGL,KAAK,YAAY,CAAC,EAAEF,OAAOQ,WAAW,CAAC,EAAE,EAAEN,KAAK,YAAY,CAAC,EAAEF,OAAOS,cAAc,CAAC,CAAC,CAAC;QAC1FT,OAAOU,OAAO,CAACC,MAAM,GAAG,IACrB,GAAGT,KAAK,YAAY,GAAG,EAAEF,OAAOU,OAAO,CAACE,IAAI,CAAC,MAAM,EAAE,CAAC,GACtD,GAAGV,KAAK,YAAY,mBAAmB,CAAC;QAC3C;QACA,GAAGA,KAAK,aAAa,EAAE,EAAEtB,YAAYoB,OAAOa,OAAO,GAAG;QACtDb,OAAOc,QAAQ,KAAK,OACjB,GAAGZ,KAAK,cAAc,CAAC,EAAEtB,YAAYoB,OAAOc,QAAQ,EAAE,QAAQ,EAAEd,OAAOe,SAAS,CAAC,CAAC,CAAC,GACnF,GAAGb,KAAK,cAAc,uCAAuC,CAAC;QACjE;QACAF,OAAOgB,SAAS,CAACL,MAAM,GAAG,IACvB,GAAGT,KAAK,cAAc,CAAC,EAAEF,OAAOgB,SAAS,CAACJ,IAAI,CAAC,OAAO,GACtD,GAAGV,KAAK,cAAc,CAAC,EAAEC,MAAM,SAAS;QAC3CH,OAAOiB,YAAY,CAACN,MAAM,GAAG,IAC1B,GAAGT,KAAK,iBAAiB,CAAC,EAAEF,OAAOiB,YAAY,CAACL,IAAI,CAAC,OAAO,GAC5D,GAAGV,KAAK,iBAAiB,CAAC,EAAEC,MAAM,SAAS;QAC9C,GAAGD,KAAK,aAAa,CAAC,EAAEE,gBAAgBE,cAAc;KACtD,EACD;QACCY,aAAa;QACbC,OAAO;IACR;AAEF;AAEA,eAAeC;IACd,IAAIZ,cAAcb,YAAY,CAAC,IAAI;IAEnC,IAAI,CAACa,aAAa;QACjBV,IAAIuB,KAAK,CAAC;QACVjC,OAAOkC,QAAQ;QACfC,QAAQC,IAAI,CAAC;IACd;IAEA,4DAA4D;IAC5D,IAAIC;IACJ,IAAI/B,OAAOgC,UAAU;QACpBD,sBAAsB/B,MAAMgC,QAAQ,CAClCC,KAAK,CAAC,KACNC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,IACjBC,MAAM,CAACC;IACV;IAEA,+CAA+C;IAC/C,IAAItB;IACJ,MAAMuB,aAAatC,YAAY,CAAC,IAAI;IACpC,IAAIsC,YAAY;QACfvB,UAAUuB,WACRN,KAAK,CAAC,KACNC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,IACjBC,MAAM,CAACC;IACV;IAEA,yEAAyE;IACzE,MAAM3B,WAAWnB,kBAAkBQ,OAAOW;IAE1C;;;EAGC,GACD,MAAM6B,aAAaxC,OAAOyC;IAC1B,IAAID,eAAeE,WAAW;QAC7B,MAAMC,cAAcC,OAAOC,QAAQ,CAACL,YAAY;QAChD,MAAMM,eACL,CAACF,OAAOG,KAAK,CAACJ,gBAAgBA,cAAc,IACzCA,cACAlD;QAEJ,IAAI;YACH,MAAM,EAAEuD,IAAI,EAAEC,OAAO,EAAE,GAAG7D,sBAAsB0B;YAChD,gEAAgE;YAChE,MAAMoC,kBAAkBD,UAAU,GAAGD,KAAK,CAAC,EAAEC,SAAS,GAAGD;YAEzD5C,IAAI+C,IAAI,CAAC,CAAC,kCAAkC,EAAEH,KAAK,GAAG,CAAC;YAEvD,MAAM,EAAEI,QAAQ,EAAE,GAAG,MAAMtD,qBAAqB;gBAC/CgB;gBACAuC,UAAUrD,OAAOqD;YAClB;YAEA,IAAID,SAASnC,MAAM,KAAK,GAAG;gBAC1Bb,IAAIuB,KAAK,CAAC;gBACVE,QAAQC,IAAI,CAAC;YACd;YAEA,6BAA6B;YAC7B,MAAMwB,gBAAgBzD,oBAAoBuD,UAAUN;YAEpD1C,IAAI+C,IAAI,CACP,CAAC,UAAU,EAAEG,cAAcrC,MAAM,CAAC,WAAW,EAAEqC,cAAcpC,IAAI,CAAC,OAAO;YAE1Ed,IAAI+C,IAAI,CAAC;YAET,MAAMI,UAAU,MAAM5D,aAAa;gBAClCmB,aAAaoC;gBACbE,UAAUE;gBACVtC;gBACAe;gBACAyB,YAAYxD,OAAOwD;gBACnBnC,WAAWrB,OAAOqB;gBAClBlB,QAAQH,OAAOG;gBACfkD,UAAUrD,OAAOqD;gBACjB1C;gBACA8C,OAAOzD,OAAOyD;YACf;YAEA,IAAIF,QAAQtC,MAAM,KAAK,GAAG;gBACzBb,IAAIuB,KAAK,CAAC;gBACVE,QAAQC,IAAI,CAAC;YACd;YAEA,sCAAsC;YACtC,MAAM4B,aAAa9D,iBAClBsD,iBACAK,SACAvD,OAAOG;YAER,KAAK,MAAMwD,QAAQD,WAAY;gBAC9BtD,IAAIA,GAAG,CAACuD;YACT;YAEA9B,QAAQC,IAAI,CAAC;QACd,EAAE,OAAOH,OAAO;YACf,MAAMiC,eACLjC,iBAAiBkC,QAAQlC,MAAMmC,OAAO,GAAGC,OAAOpC;YACjDvB,IAAIuB,KAAK,CAAC,CAAC,yBAAyB,EAAEiC,cAAc;YACpD/B,QAAQC,IAAI,CAAC;QACd;IACD;IAEA,qEAAqE;IACrE,IAAI9B,OAAOoD,UAAU;QACpB,IAAI;YACH,MAAM,EAAEJ,IAAI,EAAEC,OAAO,EAAE,GAAG7D,sBAAsB0B;YAChDV,IAAI+C,IAAI,CAAC,CAAC,kCAAkC,EAAEH,KAAK,GAAG,CAAC;YAEvD,MAAM,EAAEI,QAAQ,EAAEY,IAAI,EAAE,GAAG,MAAMlE,qBAAqB;gBACrDgB;gBACAuC,UAAUrD,OAAOqD;YAClB;YAEA,IAAID,SAASnC,MAAM,KAAK,GAAG;gBAC1Bb,IAAIuB,KAAK,CAAC;gBACVE,QAAQC,IAAI,CAAC;YACd;YAEA,MAAMmC,kBAAkB,MAAMlE,iBAAiBiD,MAAMI,UAAUY;YAC/D,4CAA4C;YAC5ClD,cAAcmC,UACX,GAAGD,KAAK,CAAC,EAAEC,QAAQ,CAAC,EAAEgB,iBAAiB,GACvC,GAAGjB,KAAK,CAAC,EAAEiB,iBAAiB;YAC/B7D,IAAI+C,IAAI,CAAC,CAAC,YAAY,EAAErC,aAAa;QACtC,EAAE,OAAOa,OAAO;YACf,MAAMiC,eACLjC,iBAAiBkC,QAAQlC,MAAMmC,OAAO,GAAGC,OAAOpC;YACjDvB,IAAIuB,KAAK,CAAC,CAAC,0BAA0B,EAAEiC,cAAc;YACrD/B,QAAQC,IAAI,CAAC;QACd;IACD;IAEA1B,IAAI+C,IAAI,CAAC,CAAC,6BAA6B,EAAErC,aAAa;IACtD,IAAIE,WAAWA,QAAQC,MAAM,GAAG,GAAG;QAClCb,IAAI+C,IAAI,CAAC,CAAC,WAAW,EAAEnC,QAAQE,IAAI,CAAC,MAAM,EAAE,CAAC;IAC9C;IAEA,IAAI;QACH,mDAAmD;QACnD,MAAM,EAAE8B,MAAMkB,QAAQ,EAAEC,SAASC,gBAAgB,EAAE,GAClDhF,sBAAsB0B;QAEvB,oDAAoD;QACpD,IAAIuD,kBAAkBD;QACtB,IAAIA,qBAAqB,UAAU;YAClC,MAAM,EAAEJ,IAAI,EAAE,GAAG,MAAMlE,qBAAqB;gBAC3CgB,aAAaoD;gBACbb,UAAUrD,OAAOqD;YAClB;YACAgB,kBAAkBL,KAAKM,MAAM,IAAIF;QAClC;QAEA,2DAA2D;QAC3D,MAAM9C,YAAYnC,aACjB+E,UACAnC,qBACA/B,OAAOwD;QAGR;;;GAGC,GACD,MAAMe,WAAWjF,kBAAkB;YAClCwB,aAAaoD;YACbC,SAASE;YACTrD;YACAL;YACAU,WAAWrB,OAAOqB,aAAa;YAC/BC;YACAkC,YAAYxD,OAAOwD,cAAc;QAClC;QAEA,4CAA4C;QAC5C,IAAI,CAACxD,OAAOyD,OAAO;YAClB,MAAMe,SAASnF,gBAAgBkF;YAC/B,IAAIC,QAAQ;gBACXpE,IAAI+C,IAAI,CAAC;gBACT9C,cAAcmE,QAAQ7D,aAAa+B;gBACnCb,QAAQC,IAAI,CAAC;YACd;QACD;QAEA1B,IAAI+C,IAAI,CAAC;QAET,MAAM7C,SAAS,MAAMrB,gBAAgB;YACpC6B;YACAE;YACAe;YACAyB,YAAYxD,OAAOwD;YACnBnC,WAAWrB,OAAOqB;YAClBgC,UAAUrD,OAAOqD;YACjB1C;QACD;QAEA,yBAAyB;QACzBpB,gBAAgBgF,UAAUjE;QAE1BD,cAAcC,QAAQK,aAAa+B;QAEnCb,QAAQC,IAAI,CAAC;IACd,EAAE,OAAOH,OAAO;QACf,MAAMiC,eAAejC,iBAAiBkC,QAAQlC,MAAMmC,OAAO,GAAGC,OAAOpC;QACrEvB,IAAIuB,KAAK,CAAC,CAAC,+BAA+B,EAAEiC,cAAc;QAC1D/B,QAAQC,IAAI,CAAC;IACd;AACD;AAEAJ"}
|
|
1
|
+
{"version":3,"sources":["../src/bundlecheck.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* istanbul ignore file */\n\nimport { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport {\n\tcheckBundleSize,\n\tformatBytes,\n\tgetExternals,\n\tparsePackageSpecifier,\n} from \"./bundler.js\";\nimport {\n\tgetCachedResult,\n\tnormalizeCacheKey,\n\tsetCachedResult,\n} from \"./cache.js\";\nimport { normalizePlatform, TREND_VERSION_COUNT } from \"./defaults.js\";\nimport { config } from \"./parse.js\";\nimport {\n\tanalyzeTrend,\n\trenderTrendGraph,\n\tselectTrendVersions,\n} from \"./trend.js\";\nimport { fetchPackageVersions, promptForVersion } from \"./versions.js\";\n\nconst flags = config.flags;\nconst parameters = config.parameters;\n\n// Disable kleur colors when --boring flag is set.\nkleur.enabled = !flags?.boring;\n\nconst log = new Logger({\n\tboring: flags?.boring,\n});\n\n/**\n * Display bundle result in a formatted box.\n */\nfunction displayResult(\n\tresult: {\n\t\tpackageName: string;\n\t\tpackageVersion: string;\n\t\texports: string[];\n\t\trawSize: number;\n\t\tgzipSize: number | null;\n\t\tgzipLevel: number;\n\t\texternals: string[];\n\t\tdependencies: string[];\n\t\tplatform: \"browser\" | \"node\";\n\t\tnamedExportCount: number;\n\t},\n\tisAutoDetected: boolean,\n): void {\n\tconst blue = kleur.blue;\n\tconst green = kleur.green;\n\n\tconst platformLabel = result.platform === \"node\" ? \"node\" : \"browser\";\n\tconst platformNote = isAutoDetected ? \" (auto-detected)\" : \"\";\n\n\t// Format exports display.\n\tlet exportsDisplay: string;\n\tif (result.exports.length > 0) {\n\t\texportsDisplay = `{ ${result.exports.join(\", \")} }`;\n\t} else if (result.namedExportCount > 0) {\n\t\texportsDisplay = `${result.namedExportCount} named exports (entire package)`;\n\t} else {\n\t\texportsDisplay = \"* (entire package)\";\n\t}\n\n\tlog.printBox(\n\t\t[\n\t\t\t`${blue(\"Package:\")} ${result.packageName} (${blue(\"version:\")} ${result.packageVersion})`,\n\t\t\t`${blue(\"Exports:\")} ${exportsDisplay}`,\n\t\t\t\"\",\n\t\t\t`${blue(\"Raw size:\")} ${formatBytes(result.rawSize)}`,\n\t\t\tresult.gzipSize !== null\n\t\t\t\t? `${blue(\"Gzip size:\")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`\n\t\t\t\t: `${blue(\"Gzip size:\")} N/A (not applicable for node platform)`,\n\t\t\t\"\",\n\t\t\tresult.externals.length > 0\n\t\t\t\t? `${blue(\"Externals:\")} ${result.externals.join(\", \")}`\n\t\t\t\t: `${blue(\"Externals:\")} ${green(\"none\")}`,\n\t\t\tresult.dependencies.length > 0\n\t\t\t\t? `${blue(\"Dependencies:\")} ${result.dependencies.join(\", \")}`\n\t\t\t\t: `${blue(\"Dependencies:\")} ${green(\"none\")}`,\n\t\t\t`${blue(\"Platform:\")} ${platformLabel}${platformNote}`,\n\t\t],\n\t\t{\n\t\t\tborderStyle: \"round\",\n\t\t\talign: \"left\",\n\t\t},\n\t);\n}\n\nasync function main() {\n\tlet packageName = parameters?.[\"0\"];\n\n\tif (!packageName) {\n\t\tlog.error(\"Package name is required\");\n\t\tconfig.showHelp?.();\n\t\tprocess.exit(1);\n\t}\n\n\t// Parse additional externals if provided (comma-separated).\n\tlet additionalExternals: string[] | undefined;\n\tif (flags?.external) {\n\t\tadditionalExternals = flags.external\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// Parse exports if provided (comma-separated).\n\tlet exports: string[] | undefined;\n\tconst exportsArg = parameters?.[\"1\"];\n\tif (exportsArg) {\n\t\texports = exportsArg\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// Normalize platform from flag (handles aliases like \"web\" → \"browser\").\n\tconst platform = normalizePlatform(flags?.platform);\n\n\t/**\n\t * If --trend flag is set, show bundle size trend across versions --trend alone\n\t * uses default (5), --trend N uses N versions.\n\t */\n\tconst trendValue = flags?.trend;\n\tif (trendValue !== undefined) {\n\t\tconst parsedCount = Number.parseInt(trendValue, 10);\n\t\tconst versionCount =\n\t\t\t!Number.isNaN(parsedCount) && parsedCount > 0\n\t\t\t\t? parsedCount\n\t\t\t\t: TREND_VERSION_COUNT;\n\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\t// Construct the full package path including subpath if present.\n\t\t\tconst fullPackagePath = subpath ? `${name}/${subpath}` : name;\n\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions } = await fetchPackageVersions({\n\t\t\t\tpackageName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Select versions for trend.\n\t\t\tconst trendVersions = selectTrendVersions(versions, versionCount);\n\n\t\t\tlog.info(\n\t\t\t\t`Analyzing ${trendVersions.length} versions: ${trendVersions.join(\", \")}`,\n\t\t\t);\n\t\t\tlog.info(\"\");\n\n\t\t\tconst results = await analyzeTrend({\n\t\t\t\tpackageName: fullPackagePath,\n\t\t\t\tversions: trendVersions,\n\t\t\t\texports,\n\t\t\t\tadditionalExternals,\n\t\t\t\tnoExternal: flags?.noExternal,\n\t\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\t\tboring: flags?.boring,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t\tplatform,\n\t\t\t\tforce: flags?.force,\n\t\t\t});\n\n\t\t\tif (results.length === 0) {\n\t\t\t\tlog.error(\"Failed to analyze any versions\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Render and display the trend graph.\n\t\t\tconst graphLines = renderTrendGraph(\n\t\t\t\tfullPackagePath,\n\t\t\t\tresults,\n\t\t\t\tflags?.boring,\n\t\t\t);\n\t\t\tfor (const line of graphLines) {\n\t\t\t\tlog.log(line);\n\t\t\t}\n\n\t\t\tprocess.exit(0);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to analyze trend: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// If --versions flag is set, fetch and prompt for version selection.\n\tif (flags?.versions) {\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions, tags } = await fetchPackageVersions({\n\t\t\t\tpackageName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst selectedVersion = await promptForVersion(name, versions, tags);\n\t\t\t// Rebuild specifier preserving any subpath.\n\t\t\tpackageName = subpath\n\t\t\t\t? `${name}/${subpath}@${selectedVersion}`\n\t\t\t\t: `${name}@${selectedVersion}`;\n\t\t\tlog.info(`\\nSelected: ${packageName}`);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to fetch versions: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tlog.info(`\\nAnalyzing bundle size for: ${packageName}`);\n\tif (exports && exports.length > 0) {\n\t\tlog.info(`Exports: { ${exports.join(\", \")} }`);\n\t}\n\n\ttry {\n\t\t// Parse package specifier to get name and version.\n\t\tconst { name: baseName, version: requestedVersion } =\n\t\t\tparsePackageSpecifier(packageName);\n\n\t\t// Resolve \"latest\" to actual version for cache key.\n\t\tlet resolvedVersion = requestedVersion;\n\t\tif (requestedVersion === \"latest\") {\n\t\t\tconst { tags } = await fetchPackageVersions({\n\t\t\t\tpackageName: baseName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\t\t\tresolvedVersion = tags.latest || requestedVersion;\n\t\t}\n\n\t\t// Compute externals for cache key (same logic as bundler).\n\t\tconst externals = getExternals(\n\t\t\tbaseName,\n\t\t\tadditionalExternals,\n\t\t\tflags?.noExternal,\n\t\t);\n\n\t\t/**\n\t\t * Build cache key.\n\t\t * NOTE: platform can be undefined (auto-detect), which is stored as \"auto\" in cache.\n\t\t */\n\t\tconst cacheKey = normalizeCacheKey({\n\t\t\tpackageName: baseName,\n\t\t\tversion: resolvedVersion,\n\t\t\texports,\n\t\t\tplatform,\n\t\t\tgzipLevel: flags?.gzipLevel ?? 5,\n\t\t\texternals,\n\t\t\tnoExternal: flags?.noExternal ?? false,\n\t\t});\n\n\t\t// Check cache (unless --force flag is set).\n\t\tif (!flags?.force) {\n\t\t\tconst cached = getCachedResult(cacheKey);\n\t\t\tif (cached) {\n\t\t\t\tlog.info(\"NOTE: Using cached results\\n\");\n\t\t\t\tdisplayResult(cached, platform === undefined);\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t}\n\n\t\tlog.info(\"Please wait, installing and bundling...\\n\");\n\n\t\tconst result = await checkBundleSize({\n\t\t\tpackageName,\n\t\t\texports,\n\t\t\tadditionalExternals,\n\t\t\tnoExternal: flags?.noExternal,\n\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\tregistry: flags?.registry,\n\t\t\tplatform,\n\t\t});\n\n\t\t// Store result in cache.\n\t\tsetCachedResult(cacheKey, result);\n\n\t\tdisplayResult(result, platform === undefined);\n\n\t\tprocess.exit(0);\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tlog.error(`Failed to analyze bundle size: ${errorMessage}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nmain();\n"],"names":["Logger","kleur","checkBundleSize","formatBytes","getExternals","parsePackageSpecifier","getCachedResult","normalizeCacheKey","setCachedResult","normalizePlatform","TREND_VERSION_COUNT","config","analyzeTrend","renderTrendGraph","selectTrendVersions","fetchPackageVersions","promptForVersion","flags","parameters","enabled","boring","log","displayResult","result","isAutoDetected","blue","green","platformLabel","platform","platformNote","exportsDisplay","exports","length","join","namedExportCount","printBox","packageName","packageVersion","rawSize","gzipSize","gzipLevel","externals","dependencies","borderStyle","align","main","error","showHelp","process","exit","additionalExternals","external","split","map","e","trim","filter","Boolean","exportsArg","trendValue","trend","undefined","parsedCount","Number","parseInt","versionCount","isNaN","name","subpath","fullPackagePath","info","versions","registry","trendVersions","results","noExternal","force","graphLines","line","errorMessage","Error","message","String","tags","selectedVersion","baseName","version","requestedVersion","resolvedVersion","latest","cacheKey","cached"],"mappings":"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"}
|
package/dist/bundler.d.ts
CHANGED
|
@@ -37,6 +37,11 @@ export type BundleResult = {
|
|
|
37
37
|
externals: string[];
|
|
38
38
|
dependencies: string[];
|
|
39
39
|
platform: "browser" | "node";
|
|
40
|
+
/**
|
|
41
|
+
* Total number of named exports in the package (when analyzing entire
|
|
42
|
+
* package).
|
|
43
|
+
*/
|
|
44
|
+
namedExportCount: number;
|
|
40
45
|
};
|
|
41
46
|
/**
|
|
42
47
|
* Format bytes to human-readable string.
|
|
@@ -50,9 +55,21 @@ export type EntryContentOptions = {
|
|
|
50
55
|
exportToSubpath?: Map<string, string>;
|
|
51
56
|
};
|
|
52
57
|
/**
|
|
53
|
-
* Get externals list based on options.
|
|
58
|
+
* Get externals list based on options and package dependencies. react and
|
|
59
|
+
* react-dom are only marked as external if they are declared in the package's
|
|
60
|
+
* dependencies or peerDependencies.
|
|
61
|
+
*
|
|
62
|
+
* Returns the base package names (e.g., ["react", "react-dom"]) for display
|
|
63
|
+
* purposes.
|
|
64
|
+
*
|
|
65
|
+
*/
|
|
66
|
+
export declare function getExternals(packageName: string, externals?: string[], noExternal?: boolean, packageDependencies?: string[]): string[];
|
|
67
|
+
/**
|
|
68
|
+
* Expand externals to include subpaths for esbuild. For example, "react"
|
|
69
|
+
* expands to ["react", "react/jsx-runtime", "react/jsx-dev-runtime"]. This is
|
|
70
|
+
* needed because esbuild doesn't automatically externalize subpaths.
|
|
54
71
|
*/
|
|
55
|
-
export declare function
|
|
72
|
+
export declare function expandExternalsForEsbuild(externals: string[]): string[];
|
|
56
73
|
export type PackageExports = Record<string, string | {
|
|
57
74
|
import?: string;
|
|
58
75
|
types?: string;
|
package/dist/bundler.js
CHANGED
|
@@ -5,7 +5,8 @@ import path from "node:path";
|
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
6
|
import zlib from "node:zlib";
|
|
7
7
|
import * as esbuild from "esbuild";
|
|
8
|
-
import { DEFAULT_EXTERNALS } from "./defaults.js";
|
|
8
|
+
import { DEFAULT_EXTERNALS, EXTERNAL_SUBPATHS } from "./defaults.js";
|
|
9
|
+
import { getNamedExports } from "./exports.js";
|
|
9
10
|
const gzipAsync = promisify(zlib.gzip);
|
|
10
11
|
/**
|
|
11
12
|
* Escape special regex characters in a string.
|
|
@@ -208,20 +209,89 @@ let usePnpm = null;
|
|
|
208
209
|
return `import * as pkg from "${packageName}";\nexport default pkg;\n`;
|
|
209
210
|
}
|
|
210
211
|
/**
|
|
211
|
-
*
|
|
212
|
-
|
|
212
|
+
* Check if an error is an esbuild BuildFailure. BuildFailure has an `errors`
|
|
213
|
+
* array with structured error objects.
|
|
214
|
+
*/ function isEsbuildBuildFailure(error) {
|
|
215
|
+
return typeof error === "object" && error !== null && "errors" in error && Array.isArray(error.errors);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Extract unresolved module paths from an esbuild BuildFailure error. Returns
|
|
219
|
+
* an object indicating which react-related modules failed to resolve.
|
|
220
|
+
*
|
|
221
|
+
* Uses esbuild's structured error objects (errors array) for reliable parsing.
|
|
222
|
+
* Falls back to string matching if the error format is unexpected.
|
|
223
|
+
*
|
|
224
|
+
* Tested against esbuild 0.27.x error format.
|
|
225
|
+
*
|
|
226
|
+
*/ function parseUnresolvedModules(error) {
|
|
227
|
+
const result = {
|
|
228
|
+
hasUnresolvedReact: false,
|
|
229
|
+
hasUnresolvedReactDom: false
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Pattern to extract module path from "Could not resolve X" errors. Matches:
|
|
233
|
+
* Could not resolve "module-name" or Could not resolve 'module-name'.
|
|
234
|
+
*/ const resolveErrorPattern = /Could not resolve ["']([^"']+)["']/;
|
|
235
|
+
if (isEsbuildBuildFailure(error)) {
|
|
236
|
+
// Use structured error objects from esbuild BuildFailure.
|
|
237
|
+
for (const err of error.errors){
|
|
238
|
+
const match = resolveErrorPattern.exec(err.text);
|
|
239
|
+
if (match) {
|
|
240
|
+
const modulePath = match[1];
|
|
241
|
+
// Check if it's a react or react-dom import (including subpaths).
|
|
242
|
+
if (modulePath === "react" || modulePath.startsWith("react/")) {
|
|
243
|
+
result.hasUnresolvedReact = true;
|
|
244
|
+
}
|
|
245
|
+
if (modulePath === "react-dom" || modulePath.startsWith("react-dom/")) {
|
|
246
|
+
result.hasUnresolvedReactDom = true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
// Fallback: parse error message string (less reliable).
|
|
252
|
+
const errorMessage = String(error);
|
|
253
|
+
const matches = errorMessage.matchAll(/Could not resolve ["']([^"']+)["']/g);
|
|
254
|
+
for (const match of matches){
|
|
255
|
+
const modulePath = match[1];
|
|
256
|
+
if (modulePath === "react" || modulePath.startsWith("react/")) {
|
|
257
|
+
result.hasUnresolvedReact = true;
|
|
258
|
+
}
|
|
259
|
+
if (modulePath === "react-dom" || modulePath.startsWith("react-dom/")) {
|
|
260
|
+
result.hasUnresolvedReactDom = true;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get externals list based on options and package dependencies. react and
|
|
268
|
+
* react-dom are only marked as external if they are declared in the package's
|
|
269
|
+
* dependencies or peerDependencies.
|
|
270
|
+
*
|
|
271
|
+
* Returns the base package names (e.g., ["react", "react-dom"]) for display
|
|
272
|
+
* purposes.
|
|
273
|
+
*
|
|
274
|
+
*/ export function getExternals(packageName, externals, noExternal, packageDependencies) {
|
|
213
275
|
if (noExternal) {
|
|
214
276
|
return [];
|
|
215
277
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
278
|
+
/**
|
|
279
|
+
* Start with empty result - we'll only add react/react-dom if they're in
|
|
280
|
+
* package deps.
|
|
281
|
+
*/ let result = [];
|
|
282
|
+
/**
|
|
283
|
+
* Only include react/react-dom if they're in the package's dependencies or
|
|
284
|
+
* peerDependencies.
|
|
285
|
+
*/ if (packageDependencies && packageDependencies.length > 0) {
|
|
286
|
+
for (const dep of DEFAULT_EXTERNALS){
|
|
287
|
+
// Don't mark as external if we're checking the package itself.
|
|
288
|
+
if (dep === packageName) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (packageDependencies.includes(dep)) {
|
|
292
|
+
result.push(dep);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
225
295
|
}
|
|
226
296
|
// Add any additional externals.
|
|
227
297
|
if (externals && externals.length > 0) {
|
|
@@ -234,6 +304,24 @@ let usePnpm = null;
|
|
|
234
304
|
}
|
|
235
305
|
return result;
|
|
236
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Expand externals to include subpaths for esbuild. For example, "react"
|
|
309
|
+
* expands to ["react", "react/jsx-runtime", "react/jsx-dev-runtime"]. This is
|
|
310
|
+
* needed because esbuild doesn't automatically externalize subpaths.
|
|
311
|
+
*/ export function expandExternalsForEsbuild(externals) {
|
|
312
|
+
const expanded = [];
|
|
313
|
+
for (const ext of externals){
|
|
314
|
+
expanded.push(ext);
|
|
315
|
+
// Add subpaths if this is a known package with subpath exports.
|
|
316
|
+
const subpaths = EXTERNAL_SUBPATHS[ext];
|
|
317
|
+
if (subpaths) {
|
|
318
|
+
expanded.push(...subpaths);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return [
|
|
322
|
+
...new Set(expanded)
|
|
323
|
+
];
|
|
324
|
+
}
|
|
237
325
|
/**
|
|
238
326
|
* Get version, dependencies, peer dependencies, and exports from an installed
|
|
239
327
|
* package.
|
|
@@ -447,23 +535,79 @@ let usePnpm = null;
|
|
|
447
535
|
});
|
|
448
536
|
const entryFile = path.join(tmpDir, "entry.js");
|
|
449
537
|
fs.writeFileSync(entryFile, entryContent);
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
538
|
+
/**
|
|
539
|
+
* Get externals based on package dependencies. Only include react/react-dom
|
|
540
|
+
* if they're in the package's dependencies or peerDependencies.
|
|
541
|
+
*/ let externals = getExternals(packageName, additionalExternals, noExternal, allDependencies);
|
|
542
|
+
/**
|
|
543
|
+
* Expand externals to include subpaths for esbuild.
|
|
544
|
+
* e.g., "react" -> ["react", "react/jsx-runtime", "react/jsx-dev-runtime"]
|
|
545
|
+
*/ let esbuildExternals = expandExternalsForEsbuild(externals);
|
|
546
|
+
/**
|
|
547
|
+
* Bundle with esbuild. We use a two-phase approach:
|
|
548
|
+
* 1. First attempt with logLevel: "silent" to suppress errors
|
|
549
|
+
* 2. If it fails due to unresolved react imports, auto-add react to externals and retry
|
|
550
|
+
* This handles packages that don't properly declare react as a peer
|
|
551
|
+
* dependency.
|
|
552
|
+
*/ let result;
|
|
553
|
+
try {
|
|
554
|
+
result = await esbuild.build({
|
|
555
|
+
entryPoints: [
|
|
556
|
+
entryFile
|
|
557
|
+
],
|
|
558
|
+
bundle: true,
|
|
559
|
+
write: false,
|
|
560
|
+
format: "esm",
|
|
561
|
+
platform,
|
|
562
|
+
target: "es2020",
|
|
563
|
+
minify: true,
|
|
564
|
+
treeShaking: true,
|
|
565
|
+
external: esbuildExternals,
|
|
566
|
+
metafile: true,
|
|
567
|
+
logLevel: "silent"
|
|
568
|
+
});
|
|
569
|
+
} catch (error) {
|
|
570
|
+
/**
|
|
571
|
+
* Parse unresolved module errors using esbuild's structured error format.
|
|
572
|
+
* This handles packages that don't properly declare react as a peer
|
|
573
|
+
* dependency.
|
|
574
|
+
*/ const { hasUnresolvedReact, hasUnresolvedReactDom } = parseUnresolvedModules(error);
|
|
575
|
+
if (!noExternal && (hasUnresolvedReact || hasUnresolvedReactDom)) {
|
|
576
|
+
// Auto-add react and/or react-dom to externals and retry.
|
|
577
|
+
const autoExternals = [];
|
|
578
|
+
if (hasUnresolvedReact && !externals.includes("react")) {
|
|
579
|
+
autoExternals.push("react");
|
|
580
|
+
}
|
|
581
|
+
if (hasUnresolvedReactDom && !externals.includes("react-dom")) {
|
|
582
|
+
autoExternals.push("react-dom");
|
|
583
|
+
}
|
|
584
|
+
if (autoExternals.length > 0) {
|
|
585
|
+
externals = [
|
|
586
|
+
...externals,
|
|
587
|
+
...autoExternals
|
|
588
|
+
];
|
|
589
|
+
esbuildExternals = expandExternalsForEsbuild(externals);
|
|
590
|
+
result = await esbuild.build({
|
|
591
|
+
entryPoints: [
|
|
592
|
+
entryFile
|
|
593
|
+
],
|
|
594
|
+
bundle: true,
|
|
595
|
+
write: false,
|
|
596
|
+
format: "esm",
|
|
597
|
+
platform,
|
|
598
|
+
target: "es2020",
|
|
599
|
+
minify: true,
|
|
600
|
+
treeShaking: true,
|
|
601
|
+
external: esbuildExternals,
|
|
602
|
+
metafile: true
|
|
603
|
+
});
|
|
604
|
+
} else {
|
|
605
|
+
throw error;
|
|
606
|
+
}
|
|
607
|
+
} else {
|
|
608
|
+
throw error;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
467
611
|
// Get raw size.
|
|
468
612
|
const bundleContent = result.outputFiles[0].contents;
|
|
469
613
|
const rawSize = bundleContent.length;
|
|
@@ -486,6 +630,10 @@ let usePnpm = null;
|
|
|
486
630
|
].sort();
|
|
487
631
|
displayName = `${packageName}/{${uniqueSubpaths.join(", ")}}`;
|
|
488
632
|
}
|
|
633
|
+
/**
|
|
634
|
+
* Get named export count from the package's type definitions. Use
|
|
635
|
+
* runtimeCount to exclude type-only exports (types, interfaces).
|
|
636
|
+
*/ const { runtimeCount: namedExportCount } = getNamedExports(tmpDir, packageName);
|
|
489
637
|
return {
|
|
490
638
|
packageName: displayName,
|
|
491
639
|
packageVersion: pkgInfo.version,
|
|
@@ -495,7 +643,8 @@ let usePnpm = null;
|
|
|
495
643
|
gzipLevel,
|
|
496
644
|
externals,
|
|
497
645
|
dependencies: allDependencies,
|
|
498
|
-
platform
|
|
646
|
+
platform,
|
|
647
|
+
namedExportCount
|
|
499
648
|
};
|
|
500
649
|
} finally{
|
|
501
650
|
cleanupTempDir(tmpDir);
|