bunchee 5.0.0-beta.1 → 5.0.0-beta.2

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
@@ -44,7 +44,7 @@ mkdir src && touch ./src/index.ts
44
44
 
45
45
  ```sh
46
46
  # Use bunchee to prepare package.json configuration
47
- npm bunchee --prepare
47
+ npm exec bunchee --prepare
48
48
  # "If you're using other package manager such as pnpm"
49
49
  # pnpm bunchee --prepare
50
50
 
package/dist/bin/cli.js CHANGED
@@ -189,9 +189,10 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
189
189
  // End of searching, export value is file path.
190
190
  // <export key>: <export value> (string)
191
191
  if (typeof exportValue === 'string') {
192
- exportTypes.add(exportKey.startsWith('./') ? 'default' : exportKey);
192
+ const composedTypes = new Set(exportTypes);
193
+ composedTypes.add(exportKey.startsWith('.') ? 'default' : exportKey);
193
194
  const exportInfo = exportToDist.get(currentPath);
194
- const exportCondition = Array.from(exportTypes).join('.');
195
+ const exportCondition = Array.from(composedTypes).join('.');
195
196
  if (!exportInfo) {
196
197
  const outputConditionPair = [
197
198
  exportValue,
@@ -254,6 +255,9 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
254
255
  const exportTypes = new Set();
255
256
  const isExportPath = exportKey.startsWith('.');
256
257
  const childPath = isExportPath ? joinRelativePath(currentPath, exportKey) : currentPath;
258
+ if (!isExportPath) {
259
+ exportTypes.add(exportKey);
260
+ }
257
261
  collectExportPath(exportValue, exportKey, childPath, exportTypes, exportToDist);
258
262
  }
259
263
  }
@@ -279,14 +283,15 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
279
283
  ]);
280
284
  }
281
285
  }
282
- if (pkg.main || pkg.module) {
286
+ // Handle package.json global exports fields
287
+ if (pkg.main || pkg.module || pkg.types) {
283
288
  const mainExportPath = pkg.main;
284
289
  const moduleExportPath = pkg.module;
285
290
  const typesEntryPath = pkg.types;
286
291
  const existingExportInfo = exportToDist.get('.');
287
292
  exportToDist.set('.', [
288
293
  ...existingExportInfo || [],
289
- [
294
+ Boolean(mainExportPath) && [
290
295
  mainExportPath,
291
296
  getMainFieldExportType(pkg)
292
297
  ],
@@ -453,7 +458,7 @@ function lint$1(pkg) {
453
458
  }
454
459
  }
455
460
 
456
- var version = "5.0.0-beta.1";
461
+ var version = "5.0.0-beta.2";
457
462
 
458
463
  function relativify(path) {
459
464
  return path.startsWith('.') ? path : `./${path}`;
@@ -495,7 +500,7 @@ function getExportTypeFromExportTypes(types) {
495
500
  new Set(types).forEach((value)=>{
496
501
  if (specialExportConventions.has(value)) {
497
502
  exportType = value;
498
- } else if (value === 'import' || value === 'require') {
503
+ } else if (value === 'import' || value === 'require' || value === 'types') {
499
504
  exportType = value;
500
505
  }
501
506
  });
package/dist/index.js CHANGED
@@ -601,9 +601,10 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
601
601
  // End of searching, export value is file path.
602
602
  // <export key>: <export value> (string)
603
603
  if (typeof exportValue === 'string') {
604
- exportTypes.add(exportKey.startsWith('./') ? 'default' : exportKey);
604
+ const composedTypes = new Set(exportTypes);
605
+ composedTypes.add(exportKey.startsWith('.') ? 'default' : exportKey);
605
606
  const exportInfo = exportToDist.get(currentPath);
606
- const exportCondition = Array.from(exportTypes).join('.');
607
+ const exportCondition = Array.from(composedTypes).join('.');
607
608
  if (!exportInfo) {
608
609
  const outputConditionPair = [
609
610
  exportValue,
@@ -666,6 +667,9 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
666
667
  const exportTypes = new Set();
667
668
  const isExportPath = exportKey.startsWith('.');
668
669
  const childPath = isExportPath ? joinRelativePath(currentPath, exportKey) : currentPath;
670
+ if (!isExportPath) {
671
+ exportTypes.add(exportKey);
672
+ }
669
673
  collectExportPath(exportValue, exportKey, childPath, exportTypes, exportToDist);
670
674
  }
671
675
  }
@@ -691,14 +695,15 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exp
691
695
  ]);
692
696
  }
693
697
  }
694
- if (pkg.main || pkg.module) {
698
+ // Handle package.json global exports fields
699
+ if (pkg.main || pkg.module || pkg.types) {
695
700
  const mainExportPath = pkg.main;
696
701
  const moduleExportPath = pkg.module;
697
702
  const typesEntryPath = pkg.types;
698
703
  const existingExportInfo = exportToDist.get('.');
699
704
  exportToDist.set('.', [
700
705
  ...existingExportInfo || [],
701
- [
706
+ Boolean(mainExportPath) && [
702
707
  mainExportPath,
703
708
  getMainFieldExportType(pkg)
704
709
  ],
@@ -729,12 +734,21 @@ function isCjsExportName(pkg, exportCondition, ext) {
729
734
  const isNotEsmExportName = !isEsmExportName(exportCondition, ext);
730
735
  return !isESModule && isNotEsmExportName && (ext !== 'mjs' || isCjsCondition) || ext === 'cjs';
731
736
  }
732
- function getExportsDistFilesOfCondition(pkg, parsedExportCondition, cwd) {
737
+ function getFileExportType(composedTypes) {
738
+ return composedTypes.split('.').pop();
739
+ }
740
+ function getExportsDistFilesOfCondition(pkg, parsedExportCondition, cwd, dts) {
733
741
  const dist = [];
734
742
  const exportConditionNames = Object.keys(parsedExportCondition.export);
735
743
  const uniqueFiles = new Set();
736
744
  for (const exportCondition of exportConditionNames){
737
- if (exportCondition === 'types') {
745
+ const exportType = getFileExportType(exportCondition);
746
+ // Filter out non-types field when generating types jobs
747
+ if (dts && exportType !== 'types') {
748
+ continue;
749
+ }
750
+ // Filter out types field when generating asset jobs
751
+ if (!dts && exportType === 'types') {
738
752
  continue;
739
753
  }
740
754
  const filePath = parsedExportCondition.export[exportCondition];
@@ -911,7 +925,7 @@ function getExportTypeFromExportTypes(types) {
911
925
  new Set(types).forEach((value)=>{
912
926
  if (specialExportConventions.has(value)) {
913
927
  exportType = value;
914
- } else if (value === 'import' || value === 'require') {
928
+ } else if (value === 'import' || value === 'require' || value === 'types') {
915
929
  exportType = value;
916
930
  }
917
931
  });
@@ -1018,7 +1032,9 @@ async function collectSourceEntries(sourceFolderPath) {
1018
1032
  }
1019
1033
 
1020
1034
  const swcMinifyOptions = {
1021
- compress: true,
1035
+ compress: {
1036
+ directives: false
1037
+ },
1022
1038
  format: {
1023
1039
  comments: 'some'
1024
1040
  },
@@ -1189,7 +1205,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1189
1205
  if (dts && code === 'EMPTY_BUNDLE') return;
1190
1206
  if (disabledWarnings.has(code)) return;
1191
1207
  // If the circular dependency warning is from node_modules, ignore it
1192
- if (code === 'CIRCULAR_DEPENDENCY' && /Circular dependency: node_modules/.test(warning.message)) {
1208
+ if (code === 'CIRCULAR_DEPENDENCY' && /Circular dependency:(\s|\S)*node_modules/.test(warning.message)) {
1193
1209
  return;
1194
1210
  }
1195
1211
  warn(warning);
@@ -1203,6 +1219,18 @@ function getModuleLater(moduleMeta) {
1203
1219
  const moduleLayer = directives[0];
1204
1220
  return moduleLayer;
1205
1221
  }
1222
+ function getCustomModuleLayer(moduleId) {
1223
+ const segments = path__default.default.basename(moduleId).split('.');
1224
+ if (segments.length >= 2) {
1225
+ const [layerSegment, ext] = segments.slice(-2);
1226
+ const match = layerSegment.match(/^(\w+)-runtime$/);
1227
+ const layer = match && match[1];
1228
+ if (availableExtensions.has(ext) && layer && layer.length > 0) {
1229
+ return layer;
1230
+ }
1231
+ }
1232
+ return undefined;
1233
+ }
1206
1234
  // dependencyGraphMap: Map<subModuleId, Set<entryParentId>>
1207
1235
  function createSplitChunks(dependencyGraphMap, entryFiles) {
1208
1236
  // If there's existing chunk being splitted, and contains a layer { <id>: <chunkGroup> }
@@ -1235,6 +1263,15 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
1235
1263
  }
1236
1264
  }
1237
1265
  }
1266
+ if (!isEntry) {
1267
+ const cachedCustomModuleLayer = splitChunksGroupMap.get(id);
1268
+ if (cachedCustomModuleLayer) return cachedCustomModuleLayer;
1269
+ const customModuleLayer = getCustomModuleLayer(id);
1270
+ if (customModuleLayer) {
1271
+ splitChunksGroupMap.set(id, customModuleLayer);
1272
+ return customModuleLayer;
1273
+ }
1274
+ }
1238
1275
  // If current module has a layer, and it's not an entry
1239
1276
  if (moduleLayer && !isEntry) {
1240
1277
  // If the module is imported by the entry:
@@ -1323,7 +1360,7 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1323
1360
  const { file } = bundleConfig;
1324
1361
  const { pkg, cwd } = pluginContext;
1325
1362
  const entry = exportCondition.source;
1326
- const outputExports = getExportsDistFilesOfCondition(pkg, exportCondition, cwd);
1363
+ const outputExports = getExportsDistFilesOfCondition(pkg, exportCondition, cwd, dts);
1327
1364
  // If there's nothing found, give a default output
1328
1365
  if (outputExports.length === 0 && !pkg.bin) {
1329
1366
  const isEsmPkg = isESModulePackage(pkg.type);
@@ -1335,44 +1372,52 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1335
1372
  });
1336
1373
  }
1337
1374
  let bundleOptions = [];
1338
- // multi outputs with specified format
1339
- // CLI output option is always prioritized
1340
1375
  if (file) {
1341
- const fallbackExport = outputExports[0];
1342
- bundleOptions = [
1343
- {
1344
- file: path.resolve(cwd, file),
1345
- format: bundleConfig.format || fallbackExport.format,
1346
- exportCondition: fallbackExport.exportCondition
1347
- }
1348
- ];
1376
+ const absoluteFile = path.resolve(cwd, file);
1377
+ const absoluteTypeFile = getExportFileTypePath(absoluteFile);
1378
+ if (dts) {
1379
+ bundleOptions = [
1380
+ {
1381
+ file: absoluteTypeFile,
1382
+ format: 'esm',
1383
+ exportCondition: 'types'
1384
+ }
1385
+ ];
1386
+ } else {
1387
+ const fallbackExport = outputExports[0];
1388
+ bundleOptions = [
1389
+ {
1390
+ file: absoluteFile,
1391
+ format: bundleConfig.format || fallbackExport.format,
1392
+ exportCondition: fallbackExport.exportCondition
1393
+ }
1394
+ ];
1395
+ }
1349
1396
  } else {
1350
- bundleOptions = outputExports.map((exportDist)=>{
1351
- return {
1352
- file: path.resolve(cwd, exportDist.file),
1353
- format: exportDist.format,
1354
- exportCondition: exportDist.exportCondition
1355
- };
1356
- });
1357
- }
1358
- if (dts) {
1359
- // types could have duplicates, dedupe them
1360
- // e.g. { types, import, .. } use the same `types` condition with all conditions
1361
- const uniqTypes = new Set();
1362
- bundleOptions.forEach((bundleOption)=>{
1363
- if (exportCondition.export.types) {
1364
- uniqTypes.add(path.resolve(cwd, exportCondition.export.types));
1365
- }
1366
- const typeForExtension = getExportFileTypePath(bundleOption.file);
1367
- uniqTypes.add(typeForExtension);
1368
- });
1369
- bundleOptions = Array.from(uniqTypes).map((typeFile)=>{
1370
- return {
1371
- file: typeFile,
1372
- format: 'esm',
1373
- exportCondition: 'types'
1374
- };
1375
- });
1397
+ // CLI output option is always prioritized
1398
+ if (dts) {
1399
+ // types could have duplicates, dedupe them
1400
+ // e.g. { types, import, .. } use the same `types` condition with all conditions
1401
+ const uniqTypes = new Set();
1402
+ outputExports.forEach((exportDist)=>{
1403
+ uniqTypes.add(path.resolve(cwd, exportDist.file));
1404
+ });
1405
+ bundleOptions = Array.from(uniqTypes).map((typeFile)=>{
1406
+ return {
1407
+ file: typeFile,
1408
+ format: 'esm',
1409
+ exportCondition: 'types'
1410
+ };
1411
+ });
1412
+ } else {
1413
+ bundleOptions = outputExports.map((exportDist)=>{
1414
+ return {
1415
+ file: path.resolve(cwd, exportDist.file),
1416
+ format: exportDist.format,
1417
+ exportCondition: exportDist.exportCondition
1418
+ };
1419
+ });
1420
+ }
1376
1421
  }
1377
1422
  const outputConfigs = bundleOptions.map(async (bundleOption)=>{
1378
1423
  const targetExportCondition = {
@@ -1394,17 +1439,21 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1394
1439
  const removeScope = (exportPath)=>exportPath.replace(/^@[^/]+\//, '');
1395
1440
  function createOutputState({ entries }) {
1396
1441
  const sizeStats = new Map();
1442
+ const uniqFiles = new Set();
1397
1443
  function addSize({ fileName, size, sourceFileName, exportPath }) {
1398
1444
  if (!sizeStats.has(exportPath)) {
1399
1445
  sizeStats.set(exportPath, []);
1400
1446
  }
1401
1447
  const distFilesStats = sizeStats.get(exportPath);
1402
- if (distFilesStats) {
1403
- distFilesStats.push([
1404
- fileName,
1405
- sourceFileName,
1406
- size
1407
- ]);
1448
+ if (!uniqFiles.has(fileName)) {
1449
+ uniqFiles.add(fileName);
1450
+ if (distFilesStats) {
1451
+ distFilesStats.push([
1452
+ fileName,
1453
+ sourceFileName,
1454
+ size
1455
+ ]);
1456
+ }
1408
1457
  }
1409
1458
  }
1410
1459
  const reversedMapping = new Map();
@@ -1458,9 +1507,6 @@ function normalizeExportName(exportName) {
1458
1507
  }
1459
1508
  return result;
1460
1509
  }
1461
- function getExportNameWithoutExportCondition(exportName) {
1462
- return exportName.includes('.') ? exportName.split('.')[0] : exportName;
1463
- }
1464
1510
  function logOutputState(sizeCollector) {
1465
1511
  const stats = sizeCollector.getSizeStats();
1466
1512
  if (stats.size === 0) {
@@ -1472,7 +1518,7 @@ function logOutputState(sizeCollector) {
1472
1518
  const statsArray = [
1473
1519
  ...stats.entries()
1474
1520
  ].sort(([a], [b])=>{
1475
- const comp = getExportNameWithoutExportCondition(a).length - getExportNameWithoutExportCondition(b).length;
1521
+ const comp = normalizeExportPath(a).length - normalizeExportPath(b).length;
1476
1522
  return comp === 0 ? a.localeCompare(b) : comp;
1477
1523
  });
1478
1524
  const maxLengthOfExportName = Math.max(...statsArray.map(([exportName])=>normalizeExportName(exportName).length));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "5.0.0-beta.1",
3
+ "version": "5.0.0-beta.2",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",
@@ -110,7 +110,7 @@
110
110
  "test:update": "TEST_UPDATE_SNAPSHOT=1 pnpm test",
111
111
  "test:post": "POST_BUILD=1 pnpm jest test/compile.test.ts test/integration.test.ts",
112
112
  "clean": "rm -rf ./dist",
113
- "typecheck": "tsc --noEmit",
113
+ "typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
114
114
  "build": "tsx ./src/bin/index.ts --runtime node",
115
115
  "format": "prettier --write ."
116
116
  }
package/dist/bin/cli.d.ts DELETED
@@ -1 +0,0 @@
1
- #!/usr/bin/env node