bunchee 5.3.2 → 5.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
@@ -326,6 +326,7 @@ import { AppContext } from './app-context.shared-runtime'
326
326
  - Watch (`-w`): Watch for source file changes.
327
327
  - No Clean(`--no-clean`): Do not clean the dist folder before building. (default: `false`)
328
328
  - TSConfig (`--tsconfig <path>`): Specify the path to the TypeScript configuration file. (default: `tsconfig.json`)
329
+ - Bundle Types (`--dts-bundle`): Bundle type declaration files. (default: `false`)
329
330
 
330
331
  ```sh
331
332
  cd <project-root-dir>
package/dist/bin/cli.js CHANGED
@@ -28,10 +28,19 @@ const availableExtensions = new Set([
28
28
  'cts',
29
29
  'mts'
30
30
  ]);
31
+ // You can find the list of runtime keys here:
32
+ // https://runtime-keys.proposal.wintercg.org/
31
33
  const runtimeExportConventions = new Set([
34
+ 'electron',
32
35
  'react-server',
33
36
  'react-native',
34
- 'edge-light'
37
+ 'edge-light',
38
+ 'node',
39
+ 'deno',
40
+ 'bun',
41
+ 'workerd',
42
+ // Browser only
43
+ 'browser'
35
44
  ]);
36
45
  const optimizeConventions = new Set([
37
46
  'development',
@@ -183,6 +192,9 @@ function isESModulePackage(packageType) {
183
192
  function isBinExportPath(exportPath) {
184
193
  return exportPath === BINARY_TAG || exportPath.startsWith(BINARY_TAG + '/');
185
194
  }
195
+ function isTypeFile(filename) {
196
+ return filename.endsWith('.d.ts') || filename.endsWith('.d.mts') || filename.endsWith('.d.cts');
197
+ }
186
198
 
187
199
  function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exportToDist) {
188
200
  // End of searching, export value is file path.
@@ -329,6 +341,14 @@ function getExportTypeFromFile(filename, pkgType) {
329
341
  return exportType;
330
342
  }
331
343
 
344
+ function validateTypesFieldCondition(pair) {
345
+ const [outputPath, composedExportType] = pair;
346
+ const exportTypes = new Set(composedExportType.split('.'));
347
+ if (!exportTypes.has('types') && isTypeFile(outputPath)) {
348
+ return true;
349
+ }
350
+ return false;
351
+ }
332
352
  function lint$1(pkg) {
333
353
  const { name, main, exports } = pkg;
334
354
  const isESM = isESModulePackage(pkg.type);
@@ -355,7 +375,8 @@ function lint$1(pkg) {
355
375
  badEsmImportExport: {
356
376
  value: false,
357
377
  paths: []
358
- }
378
+ },
379
+ badTypesExport: []
359
380
  };
360
381
  // Validate ESM package
361
382
  if (isESM) {
@@ -368,7 +389,17 @@ function lint$1(pkg) {
368
389
  state.invalidExportsFieldType = true;
369
390
  } else {
370
391
  parsedExports.forEach((outputPairs)=>{
371
- for (const [outputPath, composedExportType] of outputPairs){
392
+ for (const outputPair of outputPairs){
393
+ const [outputPath, composedExportType] = outputPair;
394
+ if (validateTypesFieldCondition([
395
+ outputPath,
396
+ composedExportType
397
+ ])) {
398
+ state.badTypesExport.push([
399
+ outputPath,
400
+ composedExportType
401
+ ]);
402
+ }
372
403
  const exportTypes = new Set(composedExportType.split('.'));
373
404
  let requirePath = '';
374
405
  let importPath = '';
@@ -406,7 +437,17 @@ function lint$1(pkg) {
406
437
  state.invalidExportsFieldType = true;
407
438
  } else {
408
439
  parsedExports.forEach((outputPairs)=>{
409
- for (const [outputPath, composedExportType] of outputPairs){
440
+ for (const outputPair of outputPairs){
441
+ const [outputPath, composedExportType] = outputPair;
442
+ if (validateTypesFieldCondition([
443
+ outputPath,
444
+ composedExportType
445
+ ])) {
446
+ state.badTypesExport.push([
447
+ outputPath,
448
+ composedExportType
449
+ ]);
450
+ }
410
451
  const exportTypes = new Set(composedExportType.split('.'));
411
452
  let requirePath = '';
412
453
  let importPath = '';
@@ -468,9 +509,15 @@ function lint$1(pkg) {
468
509
  logger.warn(` ${p}`);
469
510
  });
470
511
  }
512
+ if (state.badTypesExport.length) {
513
+ state.badTypesExport.forEach(([outputPath, composedExportType])=>{
514
+ logger.error(`Bad export types field with ${composedExportType} in ${outputPath}, use "types" export condition for it`);
515
+ });
516
+ process.exit(1);
517
+ }
471
518
  }
472
519
 
473
- var version = "5.3.2";
520
+ var version = "5.5.0";
474
521
 
475
522
  function relativify(path) {
476
523
  return path.startsWith('.') ? path : `./${path}`;
@@ -842,9 +889,6 @@ async function prepare(cwd) {
842
889
  logger.info('Configured `exports` in package.json');
843
890
  }
844
891
 
845
- function isTypeFile(filename) {
846
- return filename.endsWith('.d.ts') || filename.endsWith('.d.mts') || filename.endsWith('.d.cts');
847
- }
848
892
  function normalizeExportName(exportName) {
849
893
  const isBinary = isBinExportPath(exportName);
850
894
  let result = exportName;
@@ -921,6 +965,7 @@ Options:
921
965
  --sourcemap enable sourcemap generation, default: false
922
966
  --no-dts do not generate types, default: undefined
923
967
  --tsconfig path to tsconfig file, default: tsconfig.json
968
+ --dts-bundle bundle type declaration files, default: false
924
969
  `;
925
970
  function help() {
926
971
  logger.log(helpMessage);
@@ -952,6 +997,7 @@ function parseCliArgs(argv) {
952
997
  '--no-clean': Boolean,
953
998
  '--prepare': Boolean,
954
999
  '--tsconfig': String,
1000
+ '--dts-bundle': Boolean,
955
1001
  '-h': '--help',
956
1002
  '-v': '--version',
957
1003
  '-w': '--watch',
@@ -972,6 +1018,7 @@ function parseCliArgs(argv) {
972
1018
  sourcemap: !!args['--sourcemap'],
973
1019
  cwd: args['--cwd'],
974
1020
  dts: args['--no-dts'] ? false : undefined,
1021
+ dtsBundle: args['--dts-bundle'],
975
1022
  help: args['--help'],
976
1023
  version: args['--version'],
977
1024
  runtime: args['--runtime'],
@@ -986,11 +1033,13 @@ function parseCliArgs(argv) {
986
1033
  }
987
1034
  async function run(args) {
988
1035
  var _args_external;
989
- const { source, format, watch, minify, sourcemap, target, runtime, dts, env, clean, tsconfig } = args;
1036
+ const { source, format, watch, minify, sourcemap, target, runtime, dts, dtsBundle, env, clean, tsconfig } = args;
990
1037
  const cwd = args.cwd || process.cwd();
991
1038
  const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
992
1039
  const bundleConfig = {
993
- dts,
1040
+ dts: dts !== false && {
1041
+ respectExternal: dtsBundle ? true : undefined
1042
+ },
994
1043
  file,
995
1044
  format,
996
1045
  cwd,
package/dist/index.d.ts CHANGED
@@ -14,7 +14,9 @@ type BundleConfig = {
14
14
  sourcemap?: boolean;
15
15
  external?: string[] | null;
16
16
  env?: string[];
17
- dts?: boolean;
17
+ dts?: {
18
+ respectExternal?: boolean;
19
+ } | false;
18
20
  runtime?: string;
19
21
  pkg?: PackageMetadata;
20
22
  clean?: boolean;
package/dist/index.js CHANGED
@@ -121,10 +121,19 @@ const nodeResolveExtensions = [
121
121
  '.node',
122
122
  '.jsx'
123
123
  ];
124
+ // You can find the list of runtime keys here:
125
+ // https://runtime-keys.proposal.wintercg.org/
124
126
  const runtimeExportConventions = new Set([
127
+ 'electron',
125
128
  'react-server',
126
129
  'react-native',
127
- 'edge-light'
130
+ 'edge-light',
131
+ 'node',
132
+ 'deno',
133
+ 'bun',
134
+ 'workerd',
135
+ // Browser only
136
+ 'browser'
128
137
  ]);
129
138
  const optimizeConventions = new Set([
130
139
  'development',
@@ -908,6 +917,39 @@ async function writeDefaultTsconfig(tsConfigPath) {
908
917
  logger.log(`Detected using TypeScript but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
909
918
  }
910
919
 
920
+ /**
921
+ * @return {Record<string, string>} env { 'process.env.<key>': '<value>' }
922
+ */ function getDefinedInlineVariables(envs, parsedExportCondition) {
923
+ if (!envs.includes('NODE_ENV')) {
924
+ envs.push('NODE_ENV');
925
+ }
926
+ const envVars = envs.reduce((acc, key)=>{
927
+ const value = process.env[key];
928
+ if (typeof value !== 'undefined') {
929
+ acc['process.env.' + key] = JSON.stringify(value);
930
+ }
931
+ return acc;
932
+ }, {});
933
+ const exportConditionNames = Object.keys(parsedExportCondition.export).reduce((acc, key)=>{
934
+ // key could be 'require' or 'import.development' etc.
935
+ const exportTypes = key.split('.');
936
+ for (const exportType of exportTypes){
937
+ acc.add(exportType);
938
+ }
939
+ return acc;
940
+ }, new Set());
941
+ // For development and production convention, we override the NODE_ENV value
942
+ if (exportConditionNames.has('development')) {
943
+ envVars['process.env.NODE_ENV'] = JSON.stringify('development');
944
+ } else if (exportConditionNames.has('production')) {
945
+ envVars['process.env.NODE_ENV'] = JSON.stringify('production');
946
+ }
947
+ if (exportConditionNames.has('edge-light')) {
948
+ envVars['EdgeRuntime'] = JSON.stringify('edge-runtime');
949
+ }
950
+ return envVars;
951
+ }
952
+
911
953
  const FILENAME_REGEX = /__filename/;
912
954
  const DIRNAME_REGEX = /__dirname/;
913
955
  // not char, or space before require(.resolve)?(
@@ -1217,60 +1259,6 @@ const prependShebang = (entry)=>({
1217
1259
  }
1218
1260
  });
1219
1261
 
1220
- /**
1221
- * @return {Record<string, string>} env { 'process.env.<key>': '<value>' }
1222
- */ function getDefinedInlineVariables(envs, parsedExportCondition) {
1223
- if (!envs.includes('NODE_ENV')) {
1224
- envs.push('NODE_ENV');
1225
- }
1226
- const envVars = envs.reduce((acc, key)=>{
1227
- const value = process.env[key];
1228
- if (typeof value !== 'undefined') {
1229
- acc['process.env.' + key] = JSON.stringify(value);
1230
- }
1231
- return acc;
1232
- }, {});
1233
- const exportConditionNames = Object.keys(parsedExportCondition.export).reduce((acc, key)=>{
1234
- // key could be 'require' or 'import.development' etc.
1235
- const exportTypes = key.split('.');
1236
- for (const exportType of exportTypes){
1237
- acc.add(exportType);
1238
- }
1239
- return acc;
1240
- }, new Set());
1241
- // For development and production convention, we override the NODE_ENV value
1242
- if (exportConditionNames.has('development')) {
1243
- envVars['process.env.NODE_ENV'] = JSON.stringify('development');
1244
- } else if (exportConditionNames.has('production')) {
1245
- envVars['process.env.NODE_ENV'] = JSON.stringify('production');
1246
- }
1247
- if (exportConditionNames.has('edge-light')) {
1248
- envVars['EdgeRuntime'] = JSON.stringify('edge-runtime');
1249
- }
1250
- return envVars;
1251
- }
1252
-
1253
- function getModuleLayer(moduleMeta) {
1254
- const directives = (moduleMeta.preserveDirectives || {
1255
- directives: []
1256
- }).directives.map((d)=>d.replace(/^use /, '')).filter((d)=>d !== 'strict');
1257
- const moduleLayer = directives[0];
1258
- return moduleLayer;
1259
- }
1260
- function getCustomModuleLayer(moduleId) {
1261
- const segments = path__default.default.basename(moduleId).split('.');
1262
- if (segments.length >= 2) {
1263
- const [layerSegment, ext] = segments.slice(-2);
1264
- const baseName = segments[0];
1265
- const match = layerSegment.match(/^(\w+)-runtime$/);
1266
- const layer = match && match[1];
1267
- if (availableExtensions.has(ext) && layer && layer.length > 0) {
1268
- return baseName + '-' + layer;
1269
- }
1270
- }
1271
- return undefined;
1272
- }
1273
-
1274
1262
  const swcMinifyOptions = {
1275
1263
  compress: {
1276
1264
  directives: false
@@ -1282,7 +1270,7 @@ const swcMinifyOptions = {
1282
1270
  toplevel: true
1283
1271
  }
1284
1272
  };
1285
- async function createDtsPlugin(tsCompilerOptions, tsConfigPath, cwd) {
1273
+ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, respectExternal, cwd) {
1286
1274
  const enableIncrementalWithoutBuildInfo = tsCompilerOptions.incremental && !tsCompilerOptions.tsBuildInfoFile;
1287
1275
  const incrementalOptions = enableIncrementalWithoutBuildInfo ? {
1288
1276
  incremental: false
@@ -1313,12 +1301,11 @@ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, cwd) {
1313
1301
  });
1314
1302
  const dtsPlugin = require('rollup-plugin-dts').default({
1315
1303
  tsconfig: tsConfigPath,
1316
- compilerOptions: overrideResolvedTsOptions
1304
+ compilerOptions: overrideResolvedTsOptions,
1305
+ respectExternal
1317
1306
  });
1318
1307
  return dtsPlugin;
1319
1308
  }
1320
- // Avoid create multiple dts plugins instance and parsing the same tsconfig multi times,
1321
- // This will avoid memory leak and performance issue.
1322
1309
  const memoizeDtsPluginByKey = memoizeByKey(createDtsPlugin);
1323
1310
  async function buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts) {
1324
1311
  var _bundleConfig_file, _bundleConfig_file1;
@@ -1399,7 +1386,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1399
1386
  // Each package build should be unique
1400
1387
  // Composing above factors into a unique cache key to retrieve the memoized dts plugin with tsconfigs
1401
1388
  const uniqueProcessId = 'dts-plugin:' + process.pid + tsConfigPath;
1402
- const dtsPlugin = await memoizeDtsPluginByKey(uniqueProcessId)(tsCompilerOptions, tsConfigPath, cwd);
1389
+ const dtsPlugin = await memoizeDtsPluginByKey(uniqueProcessId)(tsCompilerOptions, tsConfigPath, bundleConfig.dts && bundleConfig.dts.respectExternal, cwd);
1403
1390
  typesPlugins.push(dtsPlugin);
1404
1391
  }
1405
1392
  const plugins = (dts ? typesPlugins : [
@@ -1460,6 +1447,27 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1460
1447
  }
1461
1448
  };
1462
1449
  }
1450
+
1451
+ function getModuleLayer(moduleMeta) {
1452
+ const directives = (moduleMeta.preserveDirectives || {
1453
+ directives: []
1454
+ }).directives.map((d)=>d.replace(/^use /, '')).filter((d)=>d !== 'strict');
1455
+ const moduleLayer = directives[0];
1456
+ return moduleLayer;
1457
+ }
1458
+ function getCustomModuleLayer(moduleId) {
1459
+ const segments = path__default.default.basename(moduleId).split('.');
1460
+ if (segments.length >= 2) {
1461
+ const [layerSegment, ext] = segments.slice(-2);
1462
+ const baseName = segments[0];
1463
+ const match = layerSegment.match(/^(\w+)-runtime$/);
1464
+ const layer = match && match[1];
1465
+ if (availableExtensions.has(ext) && layer && layer.length > 0) {
1466
+ return baseName + '-' + layer;
1467
+ }
1468
+ }
1469
+ return undefined;
1470
+ }
1463
1471
  // dependencyGraphMap: Map<subModuleId, Set<entryParentId>>
1464
1472
  function createSplitChunks(dependencyGraphMap, entryFiles) {
1465
1473
  // If there's existing chunk being splitted, and contains a layer { <id>: <chunkGroup> }
@@ -1534,13 +1542,12 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
1534
1542
  return;
1535
1543
  };
1536
1544
  }
1537
- async function buildOutputConfigs(entry, bundleConfig, exportCondition, buildContext, dts) {
1545
+
1546
+ async function buildOutputConfigs(bundleConfig, exportCondition, buildContext, dts) {
1538
1547
  const { format } = bundleConfig;
1539
- const { entries, pkg, // exportPaths,
1540
- cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1548
+ const { entries, pkg, cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1541
1549
  // Add esm mark and interop helper if esm export is detected
1542
- const useEsModuleMark = tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop // hasEsmExport(exportPaths, tsCompilerOptions)
1543
- ;
1550
+ const useEsModuleMark = tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop;
1544
1551
  const absoluteOutputFile = path.resolve(cwd, bundleConfig.file);
1545
1552
  const isEsmPkg = isESModulePackage(pkg.type);
1546
1553
  const name = filePathWithoutExtension(absoluteOutputFile);
@@ -1550,7 +1557,6 @@ async function buildOutputConfigs(entry, bundleConfig, exportCondition, buildCon
1550
1557
  const jsDir = path.dirname(absoluteOutputFile);
1551
1558
  const outputFile = dts ? dtsFile : absoluteOutputFile;
1552
1559
  const entryFiles = new Set(Object.values(entries).map((entry)=>entry.source));
1553
- const inputOptions = await buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts);
1554
1560
  const outputOptions = {
1555
1561
  name: pkg.name || name,
1556
1562
  dir: dts ? typesDir : jsDir,
@@ -1572,11 +1578,9 @@ async function buildOutputConfigs(entry, bundleConfig, exportCondition, buildCon
1572
1578
  hoistTransitiveImports: false,
1573
1579
  entryFileNames: path.basename(outputFile)
1574
1580
  };
1575
- return {
1576
- input: inputOptions,
1577
- output: outputOptions
1578
- };
1581
+ return outputOptions;
1579
1582
  }
1583
+
1580
1584
  async function buildEntryConfig(bundleConfig, pluginContext, bundleEntryOptions) {
1581
1585
  const configs = [];
1582
1586
  const { entries } = pluginContext;
@@ -1586,6 +1590,14 @@ async function buildEntryConfig(bundleConfig, pluginContext, bundleEntryOptions)
1586
1590
  }
1587
1591
  return configs;
1588
1592
  }
1593
+ async function buildRollupConfigs(entry, bundleConfig, exportCondition, buildContext, dts) {
1594
+ const inputOptions = await buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts);
1595
+ const outputOptions = await buildOutputConfigs(bundleConfig, exportCondition, buildContext, dts);
1596
+ return {
1597
+ input: inputOptions,
1598
+ output: outputOptions
1599
+ };
1600
+ }
1589
1601
  async function buildConfig(bundleConfig, exportCondition, pluginContext, bundleEntryOptions) {
1590
1602
  const { file } = bundleConfig;
1591
1603
  const { pkg, cwd } = pluginContext;
@@ -1659,7 +1671,7 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, bundleE
1659
1671
  [bundleOption.exportCondition]: bundleOption.exportCondition === 'types' ? bundleOption.file : exportCondition.export[bundleOption.exportCondition]
1660
1672
  }
1661
1673
  };
1662
- return await buildOutputConfigs(entry, {
1674
+ return await buildRollupConfigs(entry, {
1663
1675
  ...bundleConfig,
1664
1676
  file: bundleOption.file,
1665
1677
  format: bundleOption.format
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "5.3.2",
3
+ "version": "5.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,14 +42,14 @@
42
42
  "@rollup/plugin-replace": "^5.0.7",
43
43
  "@rollup/plugin-wasm": "^6.2.2",
44
44
  "@rollup/pluginutils": "^5.1.0",
45
- "@swc/core": "^1.6.1",
45
+ "@swc/core": "^1.7.14",
46
46
  "@swc/helpers": "^0.5.11",
47
47
  "arg": "^5.0.2",
48
48
  "clean-css": "^5.3.3",
49
49
  "magic-string": "^0.30.11",
50
50
  "ora": "^8.0.1",
51
51
  "pretty-bytes": "^5.6.0",
52
- "rollup": "^4.19.1",
52
+ "rollup": "^4.19.2",
53
53
  "rollup-plugin-dts": "^6.1.1",
54
54
  "rollup-plugin-swc3": "^0.11.1",
55
55
  "rollup-preserve-directives": "^1.1.1",