bunchee 6.3.4 → 6.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 CHANGED
@@ -282,7 +282,7 @@ This convention keeps shared modules private while enabling efficient bundling a
282
282
 
283
283
  ### CLI
284
284
 
285
- #### CLI Options
285
+ #### Options
286
286
 
287
287
  `bunchee` CLI provides few options to create different bundles or generating types. Call `bunchee --help` to see the help information in the terminal.
288
288
 
@@ -317,6 +317,14 @@ bunchee --no-external
317
317
 
318
318
  This will include all dependencies within your output bundle.
319
319
 
320
+ #### Build Successful Command
321
+
322
+ A command to be executed after a build is successful can be specified using the `--success` option, which is useful for development watching mode:
323
+
324
+ ```sh
325
+ bunchee --watch --success "node ./dist/index.js"
326
+ ```
327
+
320
328
  #### Prepare Package
321
329
 
322
330
  ```sh
package/dist/bin/cli.js CHANGED
@@ -281,7 +281,7 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
281
281
  ];
282
282
  addToExportDistMap(exportToDist, currentPath, [
283
283
  outputConditionPair
284
- ], runtimeExportConventions.has(exportType) ? exportType : undefined);
284
+ ]);
285
285
  } else {
286
286
  exportInfo.push([
287
287
  exportValue,
@@ -308,9 +308,8 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
308
308
  }
309
309
  }
310
310
  const mapExportFullPath = (exportPath)=>exportPath === '.' ? './index' : exportPath;
311
- function addToExportDistMap(exportToDist, exportPath, outputConditionPairs, specialExportType) {
311
+ function addToExportDistMap(exportToDist, exportPath, outputConditionPairs) {
312
312
  const fullPath = mapExportFullPath(exportPath);
313
- // + (specialExportType ? '.' + specialExportType : '')
314
313
  const existingExportInfo = exportToDist.get(fullPath);
315
314
  if (!existingExportInfo) {
316
315
  exportToDist.set(fullPath, outputConditionPairs);
@@ -647,7 +646,7 @@ function lint$1(pkg) {
647
646
  }
648
647
  }
649
648
 
650
- var version = "6.3.4";
649
+ var version = "6.5.0";
651
650
 
652
651
  async function writeDefaultTsconfig(tsConfigPath) {
653
652
  await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
@@ -974,14 +973,17 @@ async function prepare(cwd) {
974
973
  } else {
975
974
  // Update existing exports
976
975
  Object.keys(pkgExports).forEach((exportName)=>{
977
- if (pkgJson.exports[exportName]) {
978
- pkgJson.exports[exportName] = pkgExports[exportName];
979
- }
976
+ pkgJson.exports[exportName] = {
977
+ // Apply the new export conditions
978
+ ...pkgJson.exports[exportName],
979
+ // Keep the existing export conditions
980
+ ...pkgJson.exports[exportName]
981
+ };
980
982
  });
981
983
  }
982
984
  }
983
985
  }
984
- await fsp__default.default.writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
986
+ await fsp__default.default.writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + '\n');
985
987
  logger.info('Configured `exports` in package.json');
986
988
  }
987
989
 
@@ -1082,10 +1084,11 @@ Options:
1082
1084
  --runtime <runtime> build runtime (nodejs, browser). default: browser
1083
1085
  --env <env> inlined process env variables, separate by comma. default: NODE_ENV
1084
1086
  --cwd <cwd> specify current working directory
1085
- --sourcemap enable sourcemap generation, default: false
1087
+ --sourcemap enable sourcemap generation
1086
1088
  --no-dts do not generate types, default: undefined
1087
1089
  --tsconfig path to tsconfig file, default: tsconfig.json
1088
1090
  --dts-bundle bundle type declaration files, default: false
1091
+ --success <cmd> run command after build success
1089
1092
  `;
1090
1093
  function help() {
1091
1094
  logger.log(helpMessage);
@@ -1141,7 +1144,7 @@ async function parseCliArgs(argv) {
1141
1144
  description: 'js features target: swc target es versions'
1142
1145
  }).option('sourcemap', {
1143
1146
  type: 'boolean',
1144
- default: false,
1147
+ default: undefined,
1145
1148
  description: 'enable sourcemap generation'
1146
1149
  }).option('env', {
1147
1150
  type: 'string',
@@ -1160,6 +1163,9 @@ async function parseCliArgs(argv) {
1160
1163
  }).option('prepare', {
1161
1164
  type: 'boolean',
1162
1165
  description: 'auto setup package.json for building'
1166
+ }).option('success', {
1167
+ type: 'string',
1168
+ description: 'run command after build success'
1163
1169
  }).command('prepare', 'auto configure package.json exports for building', ()=>{}, (argv)=>{
1164
1170
  return prepare(argv.cwd || process.cwd());
1165
1171
  }).command('lint', 'lint package.json', ()=>{}, (argv)=>{
@@ -1194,13 +1200,18 @@ async function parseCliArgs(argv) {
1194
1200
  external: args['external'] === false ? null : args['external'],
1195
1201
  clean: args['clean'] !== false,
1196
1202
  env: args['env'],
1197
- tsconfig: args['tsconfig']
1203
+ tsconfig: args['tsconfig'],
1204
+ onSuccess: args['success']
1198
1205
  };
1206
+ // When minify is enabled, sourcemap should be enabled by default, unless explicitly opted out
1207
+ if (parsedArgs.minify && typeof args['sourcemap'] === 'undefined') {
1208
+ parsedArgs.sourcemap = true;
1209
+ }
1199
1210
  return parsedArgs;
1200
1211
  }
1201
1212
  async function run(args) {
1202
1213
  var _args_external;
1203
- const { source, format, watch, minify, sourcemap, target, runtime, dts, dtsBundle, env, clean, tsconfig } = args;
1214
+ const { source, format, watch, minify, sourcemap, target, runtime, dts, dtsBundle, env, clean, tsconfig, onSuccess } = args;
1204
1215
  const cwd = args.cwd || process.cwd();
1205
1216
  const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
1206
1217
  const bundleConfig = {
@@ -1212,13 +1223,14 @@ async function run(args) {
1212
1223
  cwd,
1213
1224
  target,
1214
1225
  runtime,
1215
- external: args.external === null ? null : ((_args_external = args.external) == null ? undefined : _args_external.split(',')) || [],
1226
+ external: args.external === null ? null : ((_args_external = args.external) == null ? void 0 : _args_external.split(',')) || [],
1216
1227
  watch: !!watch,
1217
1228
  minify: !!minify,
1218
1229
  sourcemap: sourcemap === false ? false : true,
1219
- env: (env == null ? undefined : env.split(',')) || [],
1230
+ env: (env == null ? void 0 : env.split(',')) || [],
1220
1231
  clean,
1221
- tsconfig
1232
+ tsconfig,
1233
+ onSuccess
1222
1234
  };
1223
1235
  const cliEntry = source ? path__default.default.resolve(cwd, source) : '';
1224
1236
  // lint package by default
@@ -1270,7 +1282,7 @@ async function run(args) {
1270
1282
  if (assetJobs.length === 0) {
1271
1283
  logger.warn('The "src" directory does not contain any entry files. ' + 'For proper usage, please refer to the following link: ' + 'https://github.com/huozhi/bunchee#usage');
1272
1284
  }
1273
- const outputState = initialBuildContext == null ? undefined : initialBuildContext.pluginContext.outputState;
1285
+ const outputState = initialBuildContext == null ? void 0 : initialBuildContext.pluginContext.outputState;
1274
1286
  if (outputState) {
1275
1287
  logOutputState(outputState.getSizeStats());
1276
1288
  }
@@ -1297,7 +1309,7 @@ async function run(args) {
1297
1309
  error: err
1298
1310
  };
1299
1311
  }
1300
- if ((buildError == null ? undefined : buildError.digest) === 'bunchee:not-existed') {
1312
+ if ((buildError == null ? void 0 : buildError.digest) === 'bunchee:not-existed') {
1301
1313
  help();
1302
1314
  } else {
1303
1315
  if (watch) {
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ type BundleConfig = {
21
21
  pkg?: PackageMetadata;
22
22
  clean?: boolean;
23
23
  tsconfig?: string;
24
+ onSuccess?: string | (() => void | Promise<void>);
24
25
  _callbacks?: {
25
26
  onBuildStart?: (state: any) => void;
26
27
  onBuildEnd?: (assetJobs: any) => void;
@@ -44,6 +45,6 @@ type PackageMetadata = {
44
45
  };
45
46
  type BrowserslistConfig = string | string[] | Record<string, string>;
46
47
 
47
- declare function bundle(cliEntryPath: string, { cwd: _cwd, ...options }?: BundleConfig): Promise<void>;
48
+ declare function bundle(cliEntryPath: string, { cwd: _cwd, onSuccess, ...options }?: BundleConfig): Promise<void>;
48
49
 
49
50
  export { type BundleConfig, bundle };
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ var preserveDirectives = require('rollup-preserve-directives');
18
18
  var MagicString = require('magic-string');
19
19
  var CleanCSS = require('clean-css');
20
20
  var pluginutils = require('@rollup/pluginutils');
21
+ var child_process = require('child_process');
21
22
 
22
23
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
23
24
 
@@ -445,7 +446,7 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
445
446
  ];
446
447
  addToExportDistMap(exportToDist, currentPath, [
447
448
  outputConditionPair
448
- ], runtimeExportConventions.has(exportType) ? exportType : undefined);
449
+ ]);
449
450
  } else {
450
451
  exportInfo.push([
451
452
  exportValue,
@@ -472,9 +473,8 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
472
473
  }
473
474
  }
474
475
  const mapExportFullPath = (exportPath)=>exportPath === '.' ? './index' : exportPath;
475
- function addToExportDistMap(exportToDist, exportPath, outputConditionPairs, specialExportType) {
476
+ function addToExportDistMap(exportToDist, exportPath, outputConditionPairs) {
476
477
  const fullPath = mapExportFullPath(exportPath);
477
- // + (specialExportType ? '.' + specialExportType : '')
478
478
  const existingExportInfo = exportToDist.get(fullPath);
479
479
  if (!existingExportInfo) {
480
480
  exportToDist.set(fullPath, outputConditionPairs);
@@ -679,6 +679,7 @@ async function collectEntriesFromParsedExports(cwd, parsedExportsInfo, pkg, sour
679
679
  continue;
680
680
  }
681
681
  if (!entries[entryExportPath]) {
682
+ // Create a new entry
682
683
  entries[entryExportPath] = {
683
684
  source: sourceFile,
684
685
  name: normalizedExportPath,
@@ -896,7 +897,6 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
896
897
  const sourceFileAbsolutePath = path__default.default.join(sourceFolderPath, file);
897
898
  const exportPath = sourceFilenameToExportFullPath(file);
898
899
  const isEsmPkg = isESModulePackage(pkg.type);
899
- // const specialItems: [string, string][] = []
900
900
  const specialExportType = getSpecialExportTypeFromSourcePath(file);
901
901
  const normalizedExportPath = stripSpecialCondition(exportPath);
902
902
  const isSpecialExport = specialExportType !== 'default';
@@ -1222,17 +1222,7 @@ function __insertCSS(code) {
1222
1222
  create (code) {
1223
1223
  return `__insertCSS(${JSON.stringify(code)});`;
1224
1224
  }
1225
- },
1226
- cssAssertionImport: {
1227
- global: '',
1228
- create (code) {
1229
- return `\
1230
- const sheet = new CSSStyleSheet()
1231
- sheet.replaceSync(${JSON.stringify(code)})
1232
- export default sheet`;
1233
- }
1234
- }
1235
- };
1225
+ }};
1236
1226
  const cleanCssInstance = new CleanCSS__default.default({});
1237
1227
  function minify(code) {
1238
1228
  return cleanCssInstance.minify(code).styles;
@@ -1308,7 +1298,7 @@ function hasNoSpecialCondition(conditionNames) {
1308
1298
  ...conditionNames
1309
1299
  ].every((name)=>!specialExportConventions.has(name));
1310
1300
  }
1311
- function findJsBundlePathCallback({ format, bundlePath, conditionNames }, specialCondition) {
1301
+ function findJsBundlePathCallback({ format, bundlePath, conditionNames }, specialCondition, isESMPkg) {
1312
1302
  const hasBundle = bundlePath != null;
1313
1303
  const formatCond = format === 'cjs' ? 'require' : 'import';
1314
1304
  const isTypesCondName = conditionNames.has('types');
@@ -1316,9 +1306,14 @@ function findJsBundlePathCallback({ format, bundlePath, conditionNames }, specia
1316
1306
  // Check if the format condition is matched:
1317
1307
  // if there's condition existed, check if the format condition is matched;
1318
1308
  // if there's no condition, just return true, assuming format doesn't matter;
1309
+ const bundleFormat = bundlePath.endsWith('.mjs') ? 'esm' : bundlePath.endsWith('.cjs') ? 'cjs' : isESMPkg ? 'esm' : 'cjs';
1310
+ // If there's only default condition, and the format is matched
1311
+ const isDefaultOnlyCondition = conditionNames.size === 1 && conditionNames.has('default') ? bundleFormat === format : true;
1319
1312
  const isMatchedFormat = hasFormatCond ? conditionNames.has(formatCond) : true;
1320
- const isMatchedConditionWithFormat = conditionNames.has(specialCondition) || !conditionNames.has('default') && hasNoSpecialCondition(conditionNames);
1321
- const match = isMatchedConditionWithFormat && !isTypesCondName && hasBundle && isMatchedFormat;
1313
+ const isMatchedConditionWithFormat = // Has matched special condition
1314
+ specialCondition !== 'default' && conditionNames.has(specialCondition) || // Match normal condition
1315
+ hasNoSpecialCondition(conditionNames);
1316
+ const match = isMatchedConditionWithFormat && !isTypesCondName && hasBundle && isMatchedFormat && isDefaultOnlyCondition;
1322
1317
  if (!match) {
1323
1318
  const fallback = runtimeExportConventionsFallback.get(specialCondition);
1324
1319
  if (!fallback) {
@@ -1328,7 +1323,7 @@ function findJsBundlePathCallback({ format, bundlePath, conditionNames }, specia
1328
1323
  // e.g. when import utils.js in index.js
1329
1324
  // In output: index.browser.js should match util.browser.js, fallback to util.js
1330
1325
  // The last guard condition is to ensure bundle condition but not types file.
1331
- return isMatchedFormat && (conditionNames.has(specialCondition) || fallback.some((name)=>conditionNames.has(name))) && !conditionNames.has('types');
1326
+ return isMatchedFormat && !isTypesCondName && (specialCondition !== 'default' && conditionNames.has(specialCondition) || fallback.some((name)=>conditionNames.has(name)));
1332
1327
  }
1333
1328
  } else {
1334
1329
  return match;
@@ -1341,22 +1336,27 @@ function findTypesFileCallback({ format, bundlePath, conditionNames }) {
1341
1336
  return isTypesCondName && hasCondition && (formatCond ? conditionNames.has(formatCond) : true);
1342
1337
  }
1343
1338
  // Alias entry key to dist bundle path
1344
- function aliasEntries({ entry: sourceFilePath, conditionNames, entries, format, dts, cwd }) {
1339
+ function aliasEntries({ entry: sourceFilePath, exportCondition, entries, isESMPkg, format, dts, cwd }) {
1340
+ const currentConditionNames = new Set(Object.keys(exportCondition.export)[0].split('.'));
1345
1341
  // <imported source file path>: <relative path to source's bundle>
1346
1342
  const sourceToRelativeBundleMap = new Map();
1347
- const specialCondition = getSpecialExportTypeFromConditionNames(conditionNames);
1343
+ let specialCondition = getSpecialExportTypeFromConditionNames(currentConditionNames);
1348
1344
  for (const [, exportCondition] of Object.entries(entries)){
1349
1345
  const exportDistMaps = exportCondition.export;
1350
- const exportMapEntries = Object.entries(exportDistMaps).map(([composedKey, bundlePath])=>({
1351
- conditionNames: new Set(composedKey.split('.')),
1346
+ const exportMapEntries = Object.entries(exportDistMaps).map(([composedKey, bundlePath])=>{
1347
+ const conditionNames = new Set(composedKey.split('.'));
1348
+ return {
1349
+ conditionNames,
1352
1350
  bundlePath,
1353
- format
1354
- }));
1351
+ format,
1352
+ isDefaultCondition: conditionNames.size === 1 && conditionNames.has('default')
1353
+ };
1354
+ });
1355
1355
  let matchedBundlePath;
1356
1356
  if (dts) {
1357
1357
  var _exportMapEntries_find;
1358
1358
  // Find the type with format condition first
1359
- matchedBundlePath = (_exportMapEntries_find = exportMapEntries.find(findTypesFileCallback)) == null ? undefined : _exportMapEntries_find.bundlePath;
1359
+ matchedBundlePath = (_exportMapEntries_find = exportMapEntries.find(findTypesFileCallback)) == null ? void 0 : _exportMapEntries_find.bundlePath;
1360
1360
  // If theres no format specific types such as import.types or require.types,
1361
1361
  // fallback to the general types file.
1362
1362
  if (!matchedBundlePath) {
@@ -1366,22 +1366,13 @@ function aliasEntries({ entry: sourceFilePath, conditionNames, entries, format,
1366
1366
  ...item,
1367
1367
  format: undefined
1368
1368
  });
1369
- })) == null ? undefined : _exportMapEntries_find1.bundlePath;
1369
+ })) == null ? void 0 : _exportMapEntries_find1.bundlePath;
1370
1370
  }
1371
1371
  } else {
1372
- var _exportMapEntries_sort_find;
1373
- matchedBundlePath = (_exportMapEntries_sort_find = exportMapEntries.sort(// always put special condition after the general condition (default, cjs, esm)
1374
- (a, b)=>{
1375
- if (a.conditionNames.has(specialCondition)) {
1376
- return -1;
1377
- }
1378
- if (b.conditionNames.has(specialCondition)) {
1379
- return 1;
1380
- }
1381
- return 0;
1382
- }).find((item)=>{
1383
- return findJsBundlePathCallback(item, specialCondition);
1384
- })) == null ? undefined : _exportMapEntries_sort_find.bundlePath;
1372
+ var _exportMapEntries_find2;
1373
+ matchedBundlePath = (_exportMapEntries_find2 = exportMapEntries.find((item)=>{
1374
+ return findJsBundlePathCallback(item, specialCondition, isESMPkg);
1375
+ })) == null ? void 0 : _exportMapEntries_find2.bundlePath;
1385
1376
  }
1386
1377
  if (matchedBundlePath) {
1387
1378
  if (!sourceToRelativeBundleMap.has(exportCondition.source)) sourceToRelativeBundleMap.set(exportCondition.source, matchedBundlePath);
@@ -1444,11 +1435,11 @@ const swcMinifyOptions = {
1444
1435
  }
1445
1436
  };
1446
1437
  async function createDtsPlugin(tsCompilerOptions, tsConfigPath, respectExternal, cwd) {
1447
- const enableIncrementalWithoutBuildInfo = tsCompilerOptions.incremental && !tsCompilerOptions.tsBuildInfoFile;
1438
+ const enableIncrementalWithoutBuildInfo = (tsCompilerOptions == null ? void 0 : tsCompilerOptions.incremental) && !(tsCompilerOptions == null ? void 0 : tsCompilerOptions.tsBuildInfoFile);
1448
1439
  const incrementalOptions = enableIncrementalWithoutBuildInfo ? {
1449
1440
  incremental: false
1450
1441
  } : undefined;
1451
- const compositeOptions = tsCompilerOptions.composite ? {
1442
+ const compositeOptions = (tsCompilerOptions == null ? void 0 : tsCompilerOptions.composite) ? {
1452
1443
  composite: false
1453
1444
  } : undefined;
1454
1445
  const { options: overrideResolvedTsOptions } = await convertCompilerOptions(cwd, {
@@ -1463,7 +1454,7 @@ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, respectExternal,
1463
1454
  // resolving types from <reference> from node_modules
1464
1455
  preserveSymlinks: false,
1465
1456
  target: 'ESNext',
1466
- ...!tsCompilerOptions.jsx ? {
1457
+ ...!(tsCompilerOptions == null ? void 0 : tsCompilerOptions.jsx) ? {
1467
1458
  jsx: 'react-jsx'
1468
1459
  } : undefined,
1469
1460
  // error TS5074: Option '--incremental' can only be specified using tsconfig, emitting to single
@@ -1501,7 +1492,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1501
1492
  const inlineDefinedValues = getDefinedInlineVariables(bundleConfig.env || [], exportCondition);
1502
1493
  const { useTypeScript } = buildContext;
1503
1494
  const { runtime, target: jscTarget, minify: shouldMinify } = bundleConfig;
1504
- const hasSpecifiedTsTarget = Boolean(tsCompilerOptions.target && tsConfigPath);
1495
+ const hasSpecifiedTsTarget = Boolean((tsCompilerOptions == null ? void 0 : tsCompilerOptions.target) && tsConfigPath);
1505
1496
  const swcParserConfig = {
1506
1497
  syntax: useTypeScript ? 'typescript' : 'ecmascript',
1507
1498
  [useTypeScript ? 'tsx' : 'jsx']: true,
@@ -1516,7 +1507,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1516
1507
  target: jscTarget
1517
1508
  },
1518
1509
  loose: true,
1519
- externalHelpers: false,
1510
+ externalHelpers: true,
1520
1511
  parser: swcParserConfig,
1521
1512
  transform: {
1522
1513
  decoratorVersion: '2022-03'
@@ -1540,13 +1531,13 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1540
1531
  const sizePlugin = pluginContext.outputState.plugin(cwd);
1541
1532
  // common plugins for both dts and ts assets that need to be processed
1542
1533
  // If it's a .d.ts file under non-ESM package or .d.cts file, use cjs types alias.
1543
- const aliasFormat = dts ? ((_bundleConfig_file = bundleConfig.file) == null ? undefined : _bundleConfig_file.endsWith('.d.cts')) || ((_bundleConfig_file1 = bundleConfig.file) == null ? undefined : _bundleConfig_file1.endsWith('.d.ts')) && !isESModulePackage(pkg.type) ? 'cjs' : 'esm' : bundleConfig.format;
1544
- const currentConditionNames = Object.keys(exportCondition.export)[0];
1534
+ const aliasFormat = dts ? ((_bundleConfig_file = bundleConfig.file) == null ? void 0 : _bundleConfig_file.endsWith('.d.cts')) || ((_bundleConfig_file1 = bundleConfig.file) == null ? void 0 : _bundleConfig_file1.endsWith('.d.ts')) && !isESModulePackage(pkg.type) ? 'cjs' : 'esm' : bundleConfig.format;
1545
1535
  const aliasPlugin = aliasEntries({
1546
1536
  entry,
1547
1537
  entries,
1548
1538
  format: aliasFormat,
1549
- conditionNames: new Set(currentConditionNames.split('.')),
1539
+ isESMPkg: isESModulePackage(pkg.type),
1540
+ exportCondition,
1550
1541
  dts,
1551
1542
  cwd
1552
1543
  });
@@ -1629,18 +1620,31 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1629
1620
  };
1630
1621
  }
1631
1622
 
1623
+ const hashTo3Char = memoize((input)=>{
1624
+ let hash = 0;
1625
+ for(let i = 0; i < input.length; i++){
1626
+ hash = (hash << 5) - hash + input.charCodeAt(i) // Simple hash shift
1627
+ ;
1628
+ }
1629
+ return (hash >>> 0).toString(36).slice(0, 3) // Base36 + trim to 3 chars
1630
+ ;
1631
+ });
1632
1632
  function getModuleLayer(moduleMeta) {
1633
1633
  const directives = (moduleMeta.preserveDirectives || {
1634
1634
  directives: []
1635
1635
  }).directives.map((d)=>d.replace(/^use /, '')).filter((d)=>d !== 'strict');
1636
1636
  const moduleLayer = directives[0];
1637
- return moduleLayer;
1637
+ return moduleLayer ? hashTo3Char(moduleLayer) : undefined;
1638
1638
  }
1639
1639
  // dependencyGraphMap: Map<subModuleId, Set<entryParentId>>
1640
1640
  function createSplitChunks(dependencyGraphMap, entryFiles) {
1641
1641
  // If there's existing chunk being splitted, and contains a layer { <id>: <chunkGroup> }
1642
1642
  const splitChunksGroupMap = new Map();
1643
1643
  return function splitChunks(id, ctx) {
1644
+ if (/[\\/]node_modules[\\/]\@swc[\\/]helper/.test(id)) {
1645
+ return 'cc' // common chunk
1646
+ ;
1647
+ }
1644
1648
  const moduleInfo = ctx.getModuleInfo(id);
1645
1649
  if (!moduleInfo) {
1646
1650
  return;
@@ -1693,7 +1697,8 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
1693
1697
  return;
1694
1698
  }
1695
1699
  const chunkName = path__default.default.basename(id, path__default.default.extname(id));
1696
- const chunkGroup = `${chunkName}-${moduleLayer}`;
1700
+ const layerSuffix = hashTo3Char(moduleLayer);
1701
+ const chunkGroup = `${chunkName}-${layerSuffix}`;
1697
1702
  splitChunksGroupMap.set(id, chunkGroup);
1698
1703
  return chunkGroup;
1699
1704
  }
@@ -1706,7 +1711,7 @@ async function buildOutputConfigs(bundleConfig, exportCondition, buildContext, d
1706
1711
  const { format } = bundleConfig;
1707
1712
  const { entries, pkg, cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1708
1713
  // Add esm mark and interop helper if esm export is detected
1709
- const useEsModuleMark = tsCompilerOptions == null ? undefined : tsCompilerOptions.esModuleInterop;
1714
+ const useEsModuleMark = tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop;
1710
1715
  const absoluteOutputFile = path.resolve(cwd, bundleConfig.file);
1711
1716
  const isEsmPkg = isESModulePackage(pkg.type);
1712
1717
  const name = filePathWithoutExtension(absoluteOutputFile);
@@ -1916,7 +1921,7 @@ function hasMultiEntryExport(exportPaths) {
1916
1921
  const exportKeys = Object.keys(exportPaths).filter((key)=>key !== './package.json');
1917
1922
  return exportKeys.length > 0 && exportKeys.every((name)=>name.startsWith('.'));
1918
1923
  }
1919
- async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1924
+ async function bundle(cliEntryPath, { cwd: _cwd, onSuccess, ...options } = {}) {
1920
1925
  var _options__callbacks_onBuildStart, _options__callbacks;
1921
1926
  const cwd = path.resolve(process.cwd(), _cwd || '');
1922
1927
  assignDefault(options, 'format', 'esm');
@@ -1931,10 +1936,10 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1931
1936
  const isFromCli = Boolean(cliEntryPath);
1932
1937
  const tsConfigPath = resolveTsConfigPath(cwd, options.tsconfig);
1933
1938
  let tsConfig = resolveTsConfig(cwd, tsConfigPath);
1934
- let hasTsConfig = Boolean(tsConfig == null ? undefined : tsConfig.tsConfigPath);
1939
+ let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
1935
1940
  const defaultTsOptions = {
1936
- tsConfigPath: tsConfig == null ? undefined : tsConfig.tsConfigPath,
1937
- tsCompilerOptions: (tsConfig == null ? undefined : tsConfig.tsCompilerOptions) || {}
1941
+ tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
1942
+ tsCompilerOptions: tsConfig == null ? void 0 : tsConfig.tsCompilerOptions
1938
1943
  };
1939
1944
  // Handle single entry file
1940
1945
  if (!isMultiEntries) {
@@ -2015,7 +2020,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
2015
2020
  moduleDirectiveLayerMap: new Map()
2016
2021
  }
2017
2022
  };
2018
- (_options__callbacks = options._callbacks) == null ? undefined : (_options__callbacks_onBuildStart = _options__callbacks.onBuildStart) == null ? undefined : _options__callbacks_onBuildStart.call(_options__callbacks, buildContext);
2023
+ (_options__callbacks = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildStart = _options__callbacks.onBuildStart) == null ? void 0 : _options__callbacks_onBuildStart.call(_options__callbacks, buildContext);
2019
2024
  const generateTypes = hasTsConfig && options.dts !== false;
2020
2025
  const rollupJobsOptions = {
2021
2026
  isFromCli,
@@ -2025,9 +2030,26 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
2025
2030
  var _options__callbacks_onBuildEnd, _options__callbacks1;
2026
2031
  const assetJobs = await createAssetRollupJobs(options, buildContext, rollupJobsOptions);
2027
2032
  (_options__callbacks1 = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildEnd = _options__callbacks1.onBuildEnd) == null ? void 0 : _options__callbacks_onBuildEnd.call(_options__callbacks1, assetJobs);
2033
+ // Finished building successfully
2034
+ if (onSuccess) {
2035
+ if (typeof onSuccess === 'string') {
2036
+ const successProg = child_process.spawn(onSuccess, {
2037
+ shell: true,
2038
+ stdio: 'inherit',
2039
+ cwd
2040
+ });
2041
+ successProg.on('exit', (code)=>{
2042
+ if (code) {
2043
+ process.exitCode = code;
2044
+ }
2045
+ });
2046
+ } else {
2047
+ await onSuccess();
2048
+ }
2049
+ }
2028
2050
  } catch (error) {
2029
2051
  var _options__callbacks_onBuildError, _options__callbacks2;
2030
- (_options__callbacks2 = options._callbacks) == null ? undefined : (_options__callbacks_onBuildError = _options__callbacks2.onBuildError) == null ? undefined : _options__callbacks_onBuildError.call(_options__callbacks2, error);
2052
+ (_options__callbacks2 = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildError = _options__callbacks2.onBuildError) == null ? void 0 : _options__callbacks_onBuildError.call(_options__callbacks2, error);
2031
2053
  return Promise.reject(error);
2032
2054
  }
2033
2055
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "6.3.4",
3
+ "version": "6.5.0",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",
@@ -42,16 +42,16 @@
42
42
  "@rollup/plugin-node-resolve": "^16.0.0",
43
43
  "@rollup/plugin-replace": "^6.0.2",
44
44
  "@rollup/plugin-wasm": "^6.2.2",
45
- "@rollup/pluginutils": "^5.1.3",
46
- "@swc/core": "^1.10.7",
47
- "@swc/helpers": "^0.5.11",
45
+ "@rollup/pluginutils": "^5.1.4",
46
+ "@swc/core": "^1.10.16",
47
+ "@swc/helpers": "^0.5.15",
48
48
  "clean-css": "^5.3.3",
49
49
  "fast-glob": "^3.3.3",
50
50
  "magic-string": "^0.30.17",
51
51
  "ora": "^8.0.1",
52
52
  "picomatch": "^4.0.2",
53
53
  "pretty-bytes": "^5.6.0",
54
- "rollup": "^4.30.1",
54
+ "rollup": "^4.34.7",
55
55
  "rollup-plugin-dts": "^6.1.1",
56
56
  "rollup-plugin-swc3": "^0.11.1",
57
57
  "rollup-preserve-directives": "^1.1.3",
@@ -76,7 +76,7 @@
76
76
  "@types/clean-css": "^4.2.11",
77
77
  "@types/node": "^22.9.3",
78
78
  "@types/picomatch": "^3.0.1",
79
- "@types/react": "19.0.1",
79
+ "@types/react": "^19.0.9",
80
80
  "@types/yargs": "^17.0.33",
81
81
  "bunchee": "link:./",
82
82
  "cross-env": "^7.0.3",