bunchee 4.4.1 → 4.4.3

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/dist/bin/cli.js CHANGED
@@ -25,6 +25,13 @@ const availableExtensions = new Set([
25
25
  'cts',
26
26
  'mts'
27
27
  ]);
28
+ const suffixedExportConventions = new Set([
29
+ 'react-server',
30
+ 'react-native',
31
+ 'edge-light',
32
+ 'development',
33
+ 'production'
34
+ ]);
28
35
  const SRC = 'src';
29
36
  const DIST = 'dist';
30
37
  const dtsExtensionsMap = {
@@ -154,7 +161,7 @@ const hasCjsExtension = (filename)=>path__default.default.extname(filename) ===
154
161
  const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
155
162
  const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
156
163
 
157
- function getTypings(pkg) {
164
+ function getPackageTypings(pkg) {
158
165
  return pkg.types || pkg.typings;
159
166
  }
160
167
  // Reached the end of the export path
@@ -203,6 +210,9 @@ const getFirstExportPath = (fullExportCondition)=>{
203
210
  }
204
211
  return fullExportCondition;
205
212
  };
213
+ const joinExportAndCondition = (exportPath, condition)=>{
214
+ return (exportPath === '.' ? '' : exportPath) + '.' + condition;
215
+ };
206
216
  function findExport(exportPath, exportCondition, paths, packageType, currentPath) {
207
217
  // Skip `types` field, it cannot be the entry point
208
218
  if (exportPath === 'types') return;
@@ -215,12 +225,20 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
215
225
  };
216
226
  } else {
217
227
  const exportJsBundlePath = getFirstExportPath(fullExportCondition);
218
- // exportPath is exportType, import, require, ...
219
- // merge to currentPath
220
- paths[currentPath] = {
221
- ...paths[currentPath],
222
- [exportPath]: exportJsBundlePath
223
- };
228
+ if (suffixedExportConventions.has(exportPath)) {
229
+ const specialPath = joinExportAndCondition(currentPath, exportPath);
230
+ paths[specialPath] = {
231
+ ...paths[specialPath],
232
+ ...exportCondition
233
+ };
234
+ } else {
235
+ // exportPath is exportType, import, require, ...
236
+ // merge to currentPath
237
+ paths[currentPath] = {
238
+ ...paths[currentPath],
239
+ [exportPath]: exportJsBundlePath
240
+ };
241
+ }
224
242
  }
225
243
  return;
226
244
  }
@@ -233,6 +251,25 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
233
251
  } else {
234
252
  // subpath is exportType, import, require, ...
235
253
  const exportType = subpath;
254
+ if (typeof exportCondition[subpath] === 'object') {
255
+ const defaultPath = exportCondition[subpath].default;
256
+ if (defaultPath) {
257
+ const nestedExportCondition = {
258
+ [exportType]: defaultPath
259
+ };
260
+ findExport(exportPath, nestedExportCondition, paths, packageType, currentPath);
261
+ }
262
+ // Find special export type, such as import: { development: './dev.js', production: './prod.js' }
263
+ const conditionSpecialTypes = Object.keys(exportCondition[exportType]).filter((key)=>suffixedExportConventions.has(key));
264
+ if (conditionSpecialTypes.length > 0) {
265
+ for (const conditionSpecialType of conditionSpecialTypes){
266
+ const nestedExportConditionPath = {
267
+ [exportType]: exportCondition[exportType][conditionSpecialType]
268
+ };
269
+ findExport(conditionSpecialType, nestedExportConditionPath, paths, packageType, currentPath);
270
+ }
271
+ }
272
+ }
236
273
  const defaultPath = typeof exportCondition[subpath] === 'object' ? exportCondition[subpath].default : exportCondition[subpath];
237
274
  const nestedExportCondition = {
238
275
  [exportType]: defaultPath
@@ -345,7 +382,7 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
345
382
  const defaultMainExport = constructFullExportCondition({
346
383
  ...mainExportCondition,
347
384
  module: pkg.module,
348
- types: getTypings(pkg)
385
+ types: getPackageTypings(pkg)
349
386
  }, packageType);
350
387
  if (!isEsmPackage && ((_pathsMap_ = pathsMap['.']) == null ? void 0 : _pathsMap_['require'])) {
351
388
  // pathsMap's exports.require are prioritized.
@@ -516,7 +553,7 @@ function lint$1(pkg) {
516
553
  }
517
554
  }
518
555
 
519
- var version = "4.4.1";
556
+ var version = "4.4.3";
520
557
 
521
558
  function relativify(path) {
522
559
  return path.startsWith('.') ? path : `./${path}`;
@@ -851,7 +888,7 @@ async function run(args) {
851
888
  }
852
889
  // watching mode
853
890
  if (watch) {
854
- logger.log(`Watching assets in ${cwd}...`);
891
+ logger.log(`Watching project ${cwd}...`);
855
892
  return;
856
893
  }
857
894
  // build mode
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ var rollup = require('rollup');
4
4
  var fsp = require('fs/promises');
5
5
  var fs = require('fs');
6
6
  var path = require('path');
7
+ var perf_hooks = require('perf_hooks');
7
8
  var require$$0 = require('tty');
8
9
  var module$1 = require('module');
9
10
  var rimraf = require('rimraf');
@@ -229,8 +230,14 @@ async function getSourcePathFromExportPath(cwd, exportPath, exportType) {
229
230
  }
230
231
  // TODO: add unit test
231
232
  // Unlike path.basename, forcedly removing extension
232
- function filePathWithoutExtension(file) {
233
- return file ? file.replace(new RegExp(`${path__default.default.extname(file)}$`), '') : undefined;
233
+ function filePathWithoutExtension(filePath) {
234
+ if (!filePath) return;
235
+ const lastDotIndex = filePath.lastIndexOf('.');
236
+ const lastSlashIndex = filePath.lastIndexOf('/');
237
+ if (lastDotIndex !== -1 && lastDotIndex > lastSlashIndex) {
238
+ return filePath.slice(0, filePath.indexOf('.', lastSlashIndex + 1));
239
+ }
240
+ return filePath;
234
241
  }
235
242
  const nonNullable = (n)=>Boolean(n);
236
243
  const hasAvailableExtension = (filename)=>availableExtensions.has(path__default.default.extname(filename).slice(1));
@@ -367,23 +374,64 @@ function rawContent({ exclude }) {
367
374
  };
368
375
  }
369
376
 
377
+ function relativify(path) {
378
+ return path.startsWith('.') ? path : `./${path}`;
379
+ }
380
+
370
381
  // Alias entries to import path
371
382
  // e.g.
372
383
  // For a resolved file, if it's one of the entries,
373
384
  // aliases it as export path, such as <absolute file> -> <pkg>/<export path>
374
- function aliasEntries({ entries }) {
385
+ function aliasEntries({ entry, entries, entriesAlias, format, dts }) {
386
+ let currentDistPath = '';
387
+ const entryAliasWithoutSelf = {
388
+ ...entriesAlias,
389
+ [entry]: null
390
+ };
391
+ const pathToRelativeDistMap = new Map();
392
+ for (const [, exportCondition] of Object.entries(entries)){
393
+ var _Object_entries_find;
394
+ const { import: importCond, require: requireCond, default: defaultCond } = exportCondition.export;
395
+ const firstCond = (_Object_entries_find = Object.entries(exportCondition.export).find(([key, cond])=>key !== 'types' && cond != null)) == null ? void 0 : _Object_entries_find[1];
396
+ if (dts) {
397
+ const fallbackCond = defaultCond || firstCond;
398
+ // For cjs, use require() instead of import
399
+ const firstDistPath = (format === 'cjs' ? requireCond : importCond) || fallbackCond;
400
+ if (firstDistPath) {
401
+ if (entry !== exportCondition.source) {
402
+ pathToRelativeDistMap.set(exportCondition.source, firstDistPath);
403
+ } else {
404
+ currentDistPath = firstDistPath;
405
+ }
406
+ }
407
+ }
408
+ }
375
409
  return {
376
410
  name: 'alias',
377
411
  resolveId: {
378
412
  async handler (source, importer, options) {
379
413
  const resolvedId = await this.resolve(source, importer, options);
380
414
  if (resolvedId != null) {
381
- const aliasedId = entries[resolvedId.id];
382
- if (aliasedId != null) {
383
- return {
384
- id: aliasedId,
385
- external: true
386
- };
415
+ if (dts) {
416
+ // For types, generate relative path to the other type files,
417
+ // this will be compatible for the node10 ts module resolution.
418
+ const aliasedId = pathToRelativeDistMap.get(resolvedId.id);
419
+ if (aliasedId != null && aliasedId !== currentDistPath) {
420
+ const ext = path__default.default.extname(aliasedId);
421
+ const filePathBase = filePathWithoutExtension(path__default.default.relative(path__default.default.dirname(currentDistPath), aliasedId));
422
+ const relativePath = relativify(filePathBase + ext);
423
+ return {
424
+ id: relativePath,
425
+ external: true
426
+ };
427
+ }
428
+ } else {
429
+ const aliasedId = entryAliasWithoutSelf[resolvedId.id];
430
+ if (aliasedId != null) {
431
+ return {
432
+ id: aliasedId
433
+ };
434
+ }
387
435
  }
388
436
  }
389
437
  return null;
@@ -414,7 +462,7 @@ function prependDirectives() {
414
462
  };
415
463
  }
416
464
 
417
- function getTypings(pkg) {
465
+ function getPackageTypings(pkg) {
418
466
  return pkg.types || pkg.typings;
419
467
  }
420
468
  // Reached the end of the export path
@@ -463,6 +511,9 @@ const getFirstExportPath = (fullExportCondition)=>{
463
511
  }
464
512
  return fullExportCondition;
465
513
  };
514
+ const joinExportAndCondition = (exportPath, condition)=>{
515
+ return (exportPath === '.' ? '' : exportPath) + '.' + condition;
516
+ };
466
517
  function findExport(exportPath, exportCondition, paths, packageType, currentPath) {
467
518
  // Skip `types` field, it cannot be the entry point
468
519
  if (exportPath === 'types') return;
@@ -475,12 +526,20 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
475
526
  };
476
527
  } else {
477
528
  const exportJsBundlePath = getFirstExportPath(fullExportCondition);
478
- // exportPath is exportType, import, require, ...
479
- // merge to currentPath
480
- paths[currentPath] = {
481
- ...paths[currentPath],
482
- [exportPath]: exportJsBundlePath
483
- };
529
+ if (suffixedExportConventions.has(exportPath)) {
530
+ const specialPath = joinExportAndCondition(currentPath, exportPath);
531
+ paths[specialPath] = {
532
+ ...paths[specialPath],
533
+ ...exportCondition
534
+ };
535
+ } else {
536
+ // exportPath is exportType, import, require, ...
537
+ // merge to currentPath
538
+ paths[currentPath] = {
539
+ ...paths[currentPath],
540
+ [exportPath]: exportJsBundlePath
541
+ };
542
+ }
484
543
  }
485
544
  return;
486
545
  }
@@ -493,6 +552,25 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
493
552
  } else {
494
553
  // subpath is exportType, import, require, ...
495
554
  const exportType = subpath;
555
+ if (typeof exportCondition[subpath] === 'object') {
556
+ const defaultPath = exportCondition[subpath].default;
557
+ if (defaultPath) {
558
+ const nestedExportCondition = {
559
+ [exportType]: defaultPath
560
+ };
561
+ findExport(exportPath, nestedExportCondition, paths, packageType, currentPath);
562
+ }
563
+ // Find special export type, such as import: { development: './dev.js', production: './prod.js' }
564
+ const conditionSpecialTypes = Object.keys(exportCondition[exportType]).filter((key)=>suffixedExportConventions.has(key));
565
+ if (conditionSpecialTypes.length > 0) {
566
+ for (const conditionSpecialType of conditionSpecialTypes){
567
+ const nestedExportConditionPath = {
568
+ [exportType]: exportCondition[exportType][conditionSpecialType]
569
+ };
570
+ findExport(conditionSpecialType, nestedExportConditionPath, paths, packageType, currentPath);
571
+ }
572
+ }
573
+ }
496
574
  const defaultPath = typeof exportCondition[subpath] === 'object' ? exportCondition[subpath].default : exportCondition[subpath];
497
575
  const nestedExportCondition = {
498
576
  [exportType]: defaultPath
@@ -605,7 +683,7 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
605
683
  const defaultMainExport = constructFullExportCondition({
606
684
  ...mainExportCondition,
607
685
  module: pkg.module,
608
- types: getTypings(pkg)
686
+ types: getPackageTypings(pkg)
609
687
  }, packageType);
610
688
  if (!isEsmPackage && ((_pathsMap_ = pathsMap['.']) == null ? void 0 : _pathsMap_['require'])) {
611
689
  // pathsMap's exports.require are prioritized.
@@ -635,7 +713,7 @@ function constructDefaultExportCondition(value, packageType) {
635
713
  const isEsmPackage = isESModulePackage(packageType);
636
714
  let exportCondition;
637
715
  if (typeof value === 'string') {
638
- const types = getTypings(value);
716
+ const types = getPackageTypings(value);
639
717
  exportCondition = {
640
718
  [isEsmPackage ? 'import' : 'require']: value,
641
719
  ...types && {
@@ -655,10 +733,12 @@ function isEsmExportName(name, ext) {
655
733
  }
656
734
  function isCjsExportName(pkg, exportCondition, ext) {
657
735
  const isESModule = isESModulePackage(pkg.type);
658
- return !isESModule && [
736
+ const isCjsCondition = [
659
737
  'require',
660
738
  'main'
661
- ].includes(exportCondition) && ext !== 'mjs' || ext === 'cjs';
739
+ ].includes(exportCondition);
740
+ const isNotEsmExportName = !isEsmExportName(exportCondition, ext);
741
+ return !isESModule && isNotEsmExportName && (ext !== 'mjs' || isCjsCondition) || ext === 'cjs';
662
742
  }
663
743
  function getExportsDistFilesOfCondition(pkg, parsedExportCondition, cwd) {
664
744
  const dist = [];
@@ -709,7 +789,7 @@ const swcMinifyOptions = {
709
789
  }
710
790
  };
711
791
  // return { 'process.env.<key>': '<value>' }
712
- function getBuildEnv(envs, exportConditions) {
792
+ function getDefinedInlineVariables(envs, parsedExportCondition) {
713
793
  if (!envs.includes('NODE_ENV')) {
714
794
  envs.push('NODE_ENV');
715
795
  }
@@ -720,13 +800,18 @@ function getBuildEnv(envs, exportConditions) {
720
800
  }
721
801
  return acc;
722
802
  }, {});
803
+ // handle .development, .production
804
+ const condName = parsedExportCondition.name.startsWith('.') ? parsedExportCondition.name.slice(1) : parsedExportCondition.name;
805
+ const exportConditionNames = new Set(Object.keys(parsedExportCondition.export).concat(condName));
723
806
  // For development and production convention, we override the NODE_ENV value
724
- const exportConditionNames = new Set(Object.keys(exportConditions));
725
807
  if (exportConditionNames.has('development')) {
726
808
  envVars['process.env.NODE_ENV'] = JSON.stringify('development');
727
809
  } else if (exportConditionNames.has('production')) {
728
810
  envVars['process.env.NODE_ENV'] = JSON.stringify('production');
729
811
  }
812
+ if (exportConditionNames.has('edge-light')) {
813
+ envVars['EdgeRuntime'] = JSON.stringify('edge-runtime');
814
+ }
730
815
  return envVars;
731
816
  }
732
817
  /**
@@ -744,15 +829,16 @@ function getBuildEnv(envs, exportConditions) {
744
829
  }
745
830
  return alias;
746
831
  }
747
- async function buildInputConfig(entry, options, buildContext, exportCondition, dts) {
832
+ async function buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts) {
833
+ var _bundleConfig_file;
748
834
  const { entries, pkg, cwd, tsOptions: { tsConfigPath, tsCompilerOptions }, pluginContext } = buildContext;
749
- const hasNoExternal = options.external === null;
750
- var _options_external;
835
+ const hasNoExternal = bundleConfig.external === null;
836
+ var _bundleConfig_external;
751
837
  const externals = hasNoExternal ? [] : [
752
838
  pkg.peerDependencies,
753
839
  pkg.dependencies,
754
840
  pkg.peerDependenciesMeta
755
- ].filter((n)=>Boolean(n)).map((o)=>Object.keys(o)).reduce((a, b)=>a.concat(b), []).concat((_options_external = options.external) != null ? _options_external : []);
841
+ ].filter((n)=>Boolean(n)).map((o)=>Object.keys(o)).reduce((a, b)=>a.concat(b), []).concat((_bundleConfig_external = bundleConfig.external) != null ? _bundleConfig_external : []);
756
842
  for (const [exportImportPath, exportCondition] of Object.entries(entries)){
757
843
  const entryFilePath = exportCondition.source;
758
844
  if (entryFilePath !== entry) {
@@ -760,9 +846,9 @@ async function buildInputConfig(entry, options, buildContext, exportCondition, d
760
846
  externals.push(entryFilePath);
761
847
  }
762
848
  }
763
- const envValues = getBuildEnv(options.env || [], exportCondition.export);
849
+ const inlineDefinedValues = getDefinedInlineVariables(bundleConfig.env || [], exportCondition);
764
850
  const { useTypeScript } = buildContext;
765
- const { runtime, target: jscTarget, minify: shouldMinify } = options;
851
+ const { runtime, target: jscTarget, minify: shouldMinify } = bundleConfig;
766
852
  const hasSpecifiedTsTarget = Boolean(tsCompilerOptions.target && tsConfigPath);
767
853
  const swcParserConfig = {
768
854
  syntax: useTypeScript ? 'typescript' : 'ecmascript',
@@ -780,24 +866,25 @@ async function buildInputConfig(entry, options, buildContext, exportCondition, d
780
866
  ...shouldMinify && {
781
867
  minify: {
782
868
  ...swcMinifyOptions,
783
- sourceMap: options.sourcemap
869
+ sourceMap: bundleConfig.sourcemap
784
870
  }
785
871
  }
786
872
  },
787
- sourceMaps: options.sourcemap,
873
+ sourceMaps: bundleConfig.sourcemap,
788
874
  inlineSourcesContent: false,
789
875
  isModule: true
790
876
  };
791
877
  const sizePlugin = pluginContext.outputState.plugin(cwd);
792
878
  // common plugins for both dts and ts assets that need to be processed
879
+ const aliasFormat = dts ? ((_bundleConfig_file = bundleConfig.file) == null ? void 0 : _bundleConfig_file.endsWith('.d.cts')) ? 'cjs' : 'esm' : bundleConfig.format;
793
880
  const commonPlugins = [
794
881
  sizePlugin,
795
882
  aliasEntries({
796
- entries: {
797
- ...pluginContext.entriesAlias,
798
- // Do not alias current alias of package
799
- [entry]: null
800
- }
883
+ entry,
884
+ entries,
885
+ entriesAlias: pluginContext.entriesAlias,
886
+ format: aliasFormat,
887
+ dts
801
888
  })
802
889
  ];
803
890
  const typesPlugins = [
@@ -811,7 +898,7 @@ async function buildInputConfig(entry, options, buildContext, exportCondition, d
811
898
  const incrementalOptions = enableIncrementalWithoutBuildInfo ? {
812
899
  incremental: false
813
900
  } : undefined;
814
- const compositeOptions = tsCompilerOptions.composite && enableIncrementalWithoutBuildInfo ? {
901
+ const compositeOptions = tsCompilerOptions.composite ? {
815
902
  composite: false
816
903
  } : undefined;
817
904
  const { options: overrideResolvedTsOptions } = await convertCompilerOptions(cwd, {
@@ -850,7 +937,7 @@ async function buildInputConfig(entry, options, buildContext, exportCondition, d
850
937
  preserveDirectives__default.default(),
851
938
  prependDirectives(),
852
939
  replace__default.default({
853
- values: envValues,
940
+ values: inlineDefinedValues,
854
941
  preventAssignment: true
855
942
  }),
856
943
  pluginNodeResolve.nodeResolve({
@@ -866,7 +953,7 @@ async function buildInputConfig(entry, options, buildContext, exportCondition, d
866
953
  ...swcOptions
867
954
  }),
868
955
  commonjs__default.default({
869
- exclude: options.external || null
956
+ exclude: bundleConfig.external || null
870
957
  }),
871
958
  json__default.default()
872
959
  ]).filter(isNotNull);
@@ -976,20 +1063,21 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
976
1063
  return;
977
1064
  };
978
1065
  }
979
- function buildOutputConfigs(options, exportCondition, buildContext, dts) {
980
- const { format } = options;
1066
+ async function buildOutputConfigs(entry, bundleConfig, exportCondition, buildContext, dts) {
1067
+ const { format } = bundleConfig;
981
1068
  const { entries, pkg, exportPaths, cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
982
1069
  // Add esm mark and interop helper if esm export is detected
983
1070
  const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions);
984
- const absoluteOutputFile = path.resolve(cwd, options.file);
1071
+ const absoluteOutputFile = path.resolve(cwd, bundleConfig.file);
985
1072
  const name = filePathWithoutExtension(absoluteOutputFile);
986
1073
  var _exportCondition_export_types;
987
- const dtsFile = path.resolve(cwd, dts ? options.file : (_exportCondition_export_types = exportCondition.export.types) != null ? _exportCondition_export_types : getExportFileTypePath(options.file));
1074
+ const dtsFile = path.resolve(cwd, dts ? bundleConfig.file : (_exportCondition_export_types = exportCondition.export.types) != null ? _exportCondition_export_types : getExportFileTypePath(bundleConfig.file));
988
1075
  const typesDir = path.dirname(dtsFile);
989
1076
  const jsDir = path.dirname(absoluteOutputFile);
990
1077
  const outputFile = dts ? dtsFile : absoluteOutputFile;
991
1078
  const entryFiles = new Set(Object.values(entries).map((entry)=>entry.source));
992
- return {
1079
+ const inputOptions = await buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts);
1080
+ const outputOptions = {
993
1081
  name: pkg.name || name,
994
1082
  dir: dts ? typesDir : jsDir,
995
1083
  format,
@@ -998,7 +1086,7 @@ function buildOutputConfigs(options, exportCondition, buildContext, dts) {
998
1086
  interop: 'auto',
999
1087
  freeze: false,
1000
1088
  strict: false,
1001
- sourcemap: options.sourcemap,
1089
+ sourcemap: bundleConfig.sourcemap,
1002
1090
  manualChunks: createSplitChunks(pluginContext.moduleDirectiveLayerMap, entryFiles),
1003
1091
  chunkFileNames: '[name]-[hash].js',
1004
1092
  // By default in rollup, when creating multiple chunks, transitive imports of entry chunks
@@ -1006,19 +1094,24 @@ function buildOutputConfigs(options, exportCondition, buildContext, dts) {
1006
1094
  hoistTransitiveImports: false,
1007
1095
  entryFileNames: path.basename(outputFile)
1008
1096
  };
1097
+ return {
1098
+ input: inputOptions,
1099
+ output: outputOptions
1100
+ };
1009
1101
  }
1010
1102
  async function buildEntryConfig(bundleConfig, pluginContext, dts) {
1011
1103
  const configs = [];
1012
1104
  const { entries } = pluginContext;
1013
1105
  for (const exportCondition of Object.values(entries)){
1014
- const rollupConfig = buildConfig(bundleConfig, exportCondition, pluginContext, dts);
1015
- configs.push(rollupConfig);
1106
+ const rollupConfigs = await buildConfig(bundleConfig, exportCondition, pluginContext, dts);
1107
+ configs.push(...rollupConfigs);
1016
1108
  }
1017
- return await Promise.all(configs);
1109
+ return configs;
1018
1110
  }
1019
1111
  async function collectEntry(// export type, e.g. react-server, edge-light those special cases required suffix
1020
1112
  exportType, options) {
1021
- const { cwd, pkg, entries, entryPath, exportCondRef, entryExport } = options;
1113
+ const { cwd, pkg, entries, entryPath, exportCondRef, entryExport: originEntryExport } = options;
1114
+ let entryExport = originEntryExport;
1022
1115
  let exportCondForType = {
1023
1116
  ...exportCondRef
1024
1117
  };
@@ -1027,8 +1120,13 @@ exportType, options) {
1027
1120
  exportCondForType = {
1028
1121
  [exportType]: exportCondRef[exportType]
1029
1122
  };
1030
- // Basic export type, pass down the exportPaths with erasing the special ones
1123
+ } else if (exportType[0] === '.' && suffixedExportConventions.has(exportType.slice(1))) {
1124
+ // e.g. .development, .production that has both esm and cjs export
1125
+ exportCondForType = exportCondRef;
1126
+ exportType = exportType.slice(1);
1127
+ entryExport = entryExport.replace(exportType, '');
1031
1128
  } else {
1129
+ // Basic export type, pass down the exportPaths with erasing the special ones
1032
1130
  for (const exportType of suffixedExportConventions){
1033
1131
  delete exportCondForType[exportType];
1034
1132
  }
@@ -1044,7 +1142,7 @@ exportType, options) {
1044
1142
  }
1045
1143
  const exportCondition = {
1046
1144
  source,
1047
- name: entryExport,
1145
+ name: originEntryExport,
1048
1146
  export: exportCondForType
1049
1147
  };
1050
1148
  const nameWithExportPath = pkg.name ? path__default.default.join(pkg.name, exportCondition.name) : exportCondition.name;
@@ -1106,6 +1204,8 @@ exportType, options) {
1106
1204
  for (const exportCondType of suffixedExportConventions){
1107
1205
  if (exportCond[exportCondType]) {
1108
1206
  await collectEntry(exportCondType, collectEntryOptions);
1207
+ } else if (entryExport === '.' + exportCondType) {
1208
+ await collectEntry(entryExport, collectEntryOptions);
1109
1209
  }
1110
1210
  }
1111
1211
  }
@@ -1115,14 +1215,8 @@ exportType, options) {
1115
1215
  }
1116
1216
  async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1117
1217
  const { file } = bundleConfig;
1118
- const { pkg, cwd, tsOptions } = pluginContext;
1119
- const useTypescript = Boolean(tsOptions.tsConfigPath);
1120
- const options = {
1121
- ...bundleConfig,
1122
- useTypescript
1123
- };
1218
+ const { pkg, cwd } = pluginContext;
1124
1219
  const entry = exportCondition.source;
1125
- const inputOptions = await buildInputConfig(entry, options, pluginContext, exportCondition, dts);
1126
1220
  const outputExports = getExportsDistFilesOfCondition(pkg, exportCondition, cwd);
1127
1221
  // If there's nothing found, give a default output
1128
1222
  if (outputExports.length === 0 && !pkg.bin) {
@@ -1166,26 +1260,18 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1166
1260
  bundleOptions = Array.from(uniqTypes).map((typeFile)=>{
1167
1261
  return {
1168
1262
  resolvedFile: typeFile,
1169
- format: 'es'
1263
+ format: 'esm'
1170
1264
  };
1171
1265
  });
1172
1266
  }
1173
- const outputConfigs = bundleOptions.map((bundleOption)=>{
1174
- return buildOutputConfigs({
1267
+ const outputConfigs = bundleOptions.map(async (bundleOption)=>{
1268
+ return await buildOutputConfigs(entry, {
1175
1269
  ...bundleConfig,
1176
1270
  file: bundleOption.resolvedFile,
1177
1271
  format: bundleOption.format
1178
1272
  }, exportCondition, pluginContext, dts);
1179
1273
  });
1180
- return {
1181
- input: inputOptions,
1182
- output: outputConfigs,
1183
- exportName: exportCondition.name || '.'
1184
- };
1185
- }
1186
-
1187
- function relativify(path) {
1188
- return path.startsWith('.') ? path : `./${path}`;
1274
+ return Promise.all(outputConfigs);
1189
1275
  }
1190
1276
 
1191
1277
  // Example: @foo/bar -> bar
@@ -1377,7 +1463,7 @@ function hasMultiEntryExport(exportPaths) {
1377
1463
  }
1378
1464
  async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1379
1465
  const cwd = path.resolve(process.cwd(), _cwd || '');
1380
- assignDefault(options, 'format', 'es');
1466
+ assignDefault(options, 'format', 'esm');
1381
1467
  assignDefault(options, 'minify', false);
1382
1468
  assignDefault(options, 'target', 'es2015');
1383
1469
  const pkg = await getPackageMeta(cwd);
@@ -1421,11 +1507,11 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1421
1507
  const bundleOrWatch = async (rollupConfig)=>{
1422
1508
  if (options.clean) {
1423
1509
  if (!isFromCli) {
1424
- await removeOutputDir(rollupConfig.output);
1510
+ await removeOutputDir(rollupConfig.output, cwd);
1425
1511
  }
1426
1512
  }
1427
1513
  if (options.watch) {
1428
- return Promise.resolve(runWatch(rollupConfig));
1514
+ return runWatch(rollupConfig);
1429
1515
  }
1430
1516
  return runBundle(rollupConfig);
1431
1517
  };
@@ -1474,12 +1560,15 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1474
1560
  const buildConfigs = await buildEntryConfig(options, buildContext, false);
1475
1561
  const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
1476
1562
  const typesJobs = hasTsConfig ? (await buildEntryConfig(options, buildContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
1477
- const result = await Promise.all(assetsJobs.concat(typesJobs));
1563
+ const totalJobs = assetsJobs.concat(typesJobs);
1564
+ const result = await Promise.all(totalJobs);
1478
1565
  if (result.length === 0) {
1479
1566
  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');
1480
1567
  }
1481
1568
  if (!options.watch) {
1482
1569
  logOutputState(sizeCollector);
1570
+ } else {
1571
+ logWatcherBuildTime(result);
1483
1572
  }
1484
1573
  return result;
1485
1574
  }
@@ -1496,37 +1585,49 @@ function runWatch({ input, output }) {
1496
1585
  }
1497
1586
  ];
1498
1587
  const watcher = rollup.watch(watchOptions);
1499
- watcher.on('event', (event)=>{
1500
- switch(event.code){
1501
- case 'ERROR':
1502
- {
1503
- logError(event.error);
1504
- break;
1505
- }
1506
- case 'START':
1507
- {
1508
- break;
1509
- }
1510
- case 'END':
1511
- {
1512
- break;
1513
- }
1514
- default:
1515
- return;
1588
+ return watcher;
1589
+ }
1590
+ function logWatcherBuildTime(result) {
1591
+ let watcherCounter = 0;
1592
+ let startTime = 0;
1593
+ result.map((watcher)=>{
1594
+ function start() {
1595
+ if (startTime === 0) startTime = perf_hooks.performance.now();
1596
+ }
1597
+ function end() {
1598
+ watcherCounter++;
1599
+ if (watcherCounter === result.length) {
1600
+ logger.info(`Build in ${(perf_hooks.performance.now() - startTime).toFixed(2)}ms`);
1601
+ }
1516
1602
  }
1603
+ watcher.on('event', (event)=>{
1604
+ switch(event.code){
1605
+ case 'ERROR':
1606
+ {
1607
+ logError(event.error);
1608
+ break;
1609
+ }
1610
+ case 'START':
1611
+ {
1612
+ start();
1613
+ break;
1614
+ }
1615
+ case 'END':
1616
+ {
1617
+ end();
1618
+ break;
1619
+ }
1620
+ }
1621
+ });
1517
1622
  });
1518
- return watcher;
1519
1623
  }
1520
- async function removeOutputDir(output) {
1521
- const dirs = new Set(output.map(({ dir })=>dir));
1522
- for (const dir of dirs){
1523
- if (dir) await removeDir(dir);
1524
- }
1624
+ async function removeOutputDir(output, cwd) {
1625
+ const dir = output.dir;
1626
+ if (dir && dir !== cwd) await removeDir(dir);
1525
1627
  }
1526
1628
  function runBundle({ input, output }) {
1527
1629
  return rollup.rollup(input).then((bundle)=>{
1528
- const writeJobs = output.map((options)=>bundle.write(options));
1529
- return Promise.all(writeJobs);
1630
+ return bundle.write(output);
1530
1631
  }, catchErrorHandler);
1531
1632
  }
1532
1633
  function logError(error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "4.4.1",
3
+ "version": "4.4.3",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",
@@ -54,7 +54,7 @@
54
54
  "@rollup/plugin-replace": "^5.0.5",
55
55
  "@rollup/plugin-wasm": "^6.2.2",
56
56
  "@rollup/pluginutils": "^5.1.0",
57
- "@swc/core": "^1.3.102",
57
+ "@swc/core": "^1.3.106",
58
58
  "@swc/helpers": "^0.5.3",
59
59
  "arg": "^5.0.2",
60
60
  "clean-css": "^5.3.3",
@@ -79,7 +79,7 @@
79
79
  },
80
80
  "devDependencies": {
81
81
  "@huozhi/testing-package": "1.0.0",
82
- "@swc/jest": "^0.2.29",
82
+ "@swc/jest": "^0.2.31",
83
83
  "@swc/types": "^0.1.5",
84
84
  "@types/clean-css": "^4.2.11",
85
85
  "@types/jest": "29.0.0",