bunchee 4.4.8 → 5.0.0-beta.1

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.
Files changed (4) hide show
  1. package/README.md +0 -55
  2. package/dist/bin/cli.js +320 -317
  3. package/dist/index.js +439 -494
  4. package/package.json +14 -16
package/dist/index.js CHANGED
@@ -105,13 +105,19 @@ const nodeResolveExtensions = [
105
105
  '.node',
106
106
  '.jsx'
107
107
  ];
108
- const suffixedExportConventions = new Set([
108
+ const runtimeExportConventions = new Set([
109
109
  'react-server',
110
110
  'react-native',
111
- 'edge-light',
111
+ 'edge-light'
112
+ ]);
113
+ const optimizeConventions = new Set([
112
114
  'development',
113
115
  'production'
114
116
  ]);
117
+ const specialExportConventions = new Set([
118
+ ...runtimeExportConventions,
119
+ ...optimizeConventions
120
+ ]);
115
121
  const availableESExtensionsRegex = /\.(m|c)?[jt]sx?$/;
116
122
  const SRC = 'src';
117
123
  const dtsExtensionsMap = {
@@ -139,6 +145,7 @@ const DEFAULT_TS_CONFIG = {
139
145
  moduleResolution: 'bundler'
140
146
  }
141
147
  };
148
+ const BINARY_TAG = '$binary';
142
149
 
143
150
  const defaultColorFn = (text)=>text;
144
151
  function color(prefixColor) {
@@ -219,10 +226,15 @@ async function getSourcePathFromExportPath(cwd, exportPath, exportType) {
219
226
  if (exportPath === '.') exportPath = './index';
220
227
  // Find convention-based source file for specific export types
221
228
  // $binary represents `pkg.bin`
222
- if (suffixedExportConventions.has(exportType) && exportType !== '$binary') {
229
+ if (runtimeExportConventions.has(exportType) && exportType !== BINARY_TAG) {
223
230
  const filename = await findSourceEntryFile(cwd, exportPath, exportType, ext);
224
231
  if (filename) return filename;
225
232
  }
233
+ const [, optimizeType] = exportType.split('.');
234
+ if (optimizeConventions.has(optimizeType)) {
235
+ const filename = await findSourceEntryFile(cwd, exportPath, optimizeType, ext);
236
+ if (filename) return filename;
237
+ }
226
238
  const filename = await findSourceEntryFile(cwd, exportPath, null, ext);
227
239
  if (filename) return filename;
228
240
  }
@@ -239,11 +251,16 @@ function filePathWithoutExtension(filePath) {
239
251
  }
240
252
  return filePath;
241
253
  }
242
- const nonNullable = (n)=>Boolean(n);
243
254
  const hasAvailableExtension = (filename)=>availableExtensions.has(path__default.default.extname(filename).slice(1));
244
255
  const hasCjsExtension = (filename)=>path__default.default.extname(filename) === '.cjs';
256
+ const getMainFieldExportType = (pkg)=>{
257
+ const isEsmPkg = isESModulePackage(pkg.type);
258
+ const mainExportType = isEsmPkg && pkg.main ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
259
+ return mainExportType;
260
+ };
245
261
  // TODO: add unit test
246
262
  const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
263
+ const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
247
264
  const memoize = (fn, resolver)=>{
248
265
  const cache = new Map();
249
266
  return (...args)=>{
@@ -259,6 +276,17 @@ const memoize = (fn, resolver)=>{
259
276
  return result;
260
277
  };
261
278
  };
279
+ function joinRelativePath(...segments) {
280
+ let result = path__default.default.join(...segments);
281
+ // If the first segment starts with '.', ensure the result does too.
282
+ if (segments[0] === '.' && !result.startsWith('.')) {
283
+ result = './' + result;
284
+ }
285
+ return result;
286
+ }
287
+ function isESModulePackage(packageType) {
288
+ return packageType === 'module';
289
+ }
262
290
 
263
291
  let hasLoggedTsWarning = false;
264
292
  function resolveTypescriptHandler(cwd) {
@@ -569,268 +597,122 @@ function prependDirectives() {
569
597
  };
570
598
  }
571
599
 
572
- function getPackageTypings(pkg) {
573
- return pkg.types || pkg.typings;
574
- }
575
- // Reached the end of the export path
576
- function isExportLike(field) {
577
- if (typeof field === 'string') return true;
578
- return Object.entries(field).every(// Every value is string and key is not start with '.'
579
- ([key, value])=>typeof value === 'string' && !key.startsWith('.'));
580
- }
581
- function constructFullExportCondition(exportCondition, packageType) {
582
- let fullExportCond;
583
- if (typeof exportCondition === 'string') {
584
- const exportType = getExportTypeFromFile(exportCondition, packageType);
585
- fullExportCond = {
586
- [exportType]: exportCondition
587
- };
588
- } else {
589
- const exportTypes = Object.keys(exportCondition);
590
- fullExportCond = {};
591
- exportTypes.forEach((exportType)=>{
592
- const condition = exportCondition[exportType];
593
- // Filter out nullable value
594
- if (condition) {
595
- fullExportCond[exportType] = condition;
596
- }
597
- });
598
- }
599
- return fullExportCond;
600
- }
601
- function joinRelativePath(...segments) {
602
- let result = path.join(...segments);
603
- // If the first segment starts with '.', ensure the result does too.
604
- if (segments[0] === '.' && !result.startsWith('.')) {
605
- result = './' + result;
606
- }
607
- return result;
608
- }
609
- const getFirstExportPath = (fullExportCondition)=>{
610
- // Handle all export cond { <require|import|default>: ... }
611
- if (typeof fullExportCondition === 'object') {
612
- for (const key of Object.keys(fullExportCondition)){
613
- if (key.startsWith('.') || key === 'types') {
614
- continue;
615
- }
616
- return fullExportCondition[key];
617
- }
618
- }
619
- return fullExportCondition;
620
- };
621
- const joinExportAndCondition = (exportPath, condition)=>{
622
- return (exportPath === '.' ? '' : exportPath) + '.' + condition;
623
- };
624
- function findExport(exportPath, exportCondition, paths, packageType, currentPath) {
625
- // Skip `types` field, it cannot be the entry point
626
- if (exportPath === 'types') return;
627
- if (isExportLike(exportCondition)) {
628
- const fullExportCondition = constructFullExportCondition(exportCondition, packageType);
629
- if (exportPath.startsWith('.')) {
630
- paths[exportPath] = {
631
- ...paths[exportPath],
632
- ...fullExportCondition
633
- };
600
+ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exportToDist) {
601
+ // End of searching, export value is file path.
602
+ // <export key>: <export value> (string)
603
+ if (typeof exportValue === 'string') {
604
+ exportTypes.add(exportKey.startsWith('./') ? 'default' : exportKey);
605
+ const exportInfo = exportToDist.get(currentPath);
606
+ const exportCondition = Array.from(exportTypes).join('.');
607
+ if (!exportInfo) {
608
+ const outputConditionPair = [
609
+ exportValue,
610
+ exportCondition
611
+ ];
612
+ exportToDist.set(currentPath, [
613
+ outputConditionPair
614
+ ]);
634
615
  } else {
635
- const exportJsBundlePath = getFirstExportPath(fullExportCondition);
636
- if (suffixedExportConventions.has(exportPath)) {
637
- const specialPath = joinExportAndCondition(currentPath, exportPath);
638
- paths[specialPath] = {
639
- ...paths[specialPath],
640
- ...exportCondition
641
- };
642
- } else {
643
- // exportPath is exportType, import, require, ...
644
- // merge to currentPath
645
- paths[currentPath] = {
646
- ...paths[currentPath],
647
- [exportPath]: exportJsBundlePath
648
- };
649
- }
616
+ exportInfo.push([
617
+ exportValue,
618
+ exportCondition
619
+ ]);
650
620
  }
651
621
  return;
652
622
  }
653
- Object.keys(exportCondition).forEach((subpath)=>{
654
- if (subpath.startsWith('.')) {
655
- // subpath is actual export path, ./a, ./b, ...
656
- const nestedExportPath = joinRelativePath(currentPath, subpath);
657
- const nestedExportCondition = exportCondition[subpath];
658
- findExport(nestedExportPath, nestedExportCondition, paths, packageType, nestedExportPath);
659
- } else {
660
- // subpath is exportType, import, require, ...
661
- const exportType = subpath;
662
- if (typeof exportCondition[subpath] === 'object') {
663
- const defaultPath = exportCondition[subpath].default;
664
- if (defaultPath) {
665
- const nestedExportCondition = {
666
- [exportType]: defaultPath
667
- };
668
- findExport(exportPath, nestedExportCondition, paths, packageType, currentPath);
669
- }
670
- // Find special export type, such as import: { development: './dev.js', production: './prod.js' }
671
- const conditionSpecialTypes = Object.keys(exportCondition[exportType]).filter((key)=>suffixedExportConventions.has(key));
672
- if (conditionSpecialTypes.length > 0) {
673
- for (const conditionSpecialType of conditionSpecialTypes){
674
- const nestedExportConditionPath = {
675
- [exportType]: exportCondition[exportType][conditionSpecialType]
676
- };
677
- findExport(conditionSpecialType, nestedExportConditionPath, paths, packageType, currentPath);
678
- }
679
- }
680
- }
681
- const defaultPath = typeof exportCondition[subpath] === 'object' ? exportCondition[subpath].default : exportCondition[subpath];
682
- const nestedExportCondition = {
683
- [exportType]: defaultPath
684
- };
685
- findExport(exportPath, nestedExportCondition, paths, packageType, currentPath);
686
- }
687
- });
688
- }
689
- /**
690
- *
691
- * Convert package.exports field to paths mapping
692
- * Example
693
- *
694
- * Input:
695
- * {
696
- * "./sub": {
697
- * "import": {
698
- * "types": "./sub.js",
699
- * "default": "./sub.cjs",
700
- * }
701
- * }
702
- * }
703
- *
704
- * Output:
705
- * {
706
- * "./sub": {
707
- * "import": "./sub.js",
708
- * "require": "./sub.cjs",
709
- * "types": "./sub.d.ts",
710
- * }
711
- * }
712
- *
713
- */ function parseExport(exportsCondition, packageType) {
714
- const paths = {};
715
- const initialPath = '.';
716
- if (typeof exportsCondition === 'string') {
717
- paths[initialPath] = constructFullExportCondition(exportsCondition, packageType);
718
- } else if (typeof exportsCondition === 'object') {
719
- if (isExportLike(exportsCondition)) {
720
- paths[initialPath] = constructFullExportCondition(exportsCondition, packageType);
623
+ const exportKeys = Object.keys(exportValue);
624
+ for (const exportKey of exportKeys){
625
+ // Clone the set to avoid modifying the parent set
626
+ const childExports = new Set(exportTypes);
627
+ // Normalize child export value to a map
628
+ const childExportValue = exportValue[exportKey];
629
+ // Visit export path: ./subpath, ./subpath2, ...
630
+ if (exportKey.startsWith('.')) {
631
+ const childPath = joinRelativePath(currentPath, exportKey);
632
+ collectExportPath(childExportValue, exportKey, childPath, childExports, exportToDist);
721
633
  } else {
722
- Object.keys(exportsCondition).forEach((key)=>{
723
- const exportCondition = exportsCondition[key];
724
- findExport(key, exportCondition, paths, packageType, initialPath);
725
- });
634
+ // Visit export type: import, require, ...
635
+ childExports.add(exportKey);
636
+ collectExportPath(childExportValue, exportKey, currentPath, childExports, exportToDist);
726
637
  }
727
638
  }
728
- return paths;
729
639
  }
730
640
  /**
731
- * Get package exports paths
641
+ * parseExports - parse package.exports field and other fields like main,module to a map
732
642
  *
733
- * Example:
734
- *
735
- * ```json
736
- * {
737
- * "exports": {
738
- * ".": {
739
- * "require": "./dist/index.cjs",
740
- * "module": "./dist/index.esm.js",
741
- * "default": "./dist/index.esm.js"
742
- * },
743
- * "./foo": {
744
- * "require": "./dist/foo.cjs",
745
- * "module": "./dist/foo.esm.js",
746
- * "default": "./dist/foo.esm.js"
747
- * }
748
- * }
749
- *
750
- * ```
751
- *
752
- * will be parsed to:
753
- *
754
- * ```js
755
- * {
756
- * '.': {
757
- * main: './dist/index.cjs',
758
- * module: './dist/index.esm.js',
759
- * export: './dist/index.esm.js'
760
- * },
761
- * './foo': {
762
- * main: './dist/foo.cjs',
763
- * module: './dist/foo.esm.js',
764
- * export: './dist/foo.esm.js'
765
- * }
766
- *
767
- *
768
- * pkg.main and pkg.module will be added to ['.'] if exists
769
- */ function getExportPaths(pkg, resolvedWildcardExports) {
770
- var _pathsMap_;
771
- let pathsMap = {};
772
- const packageType = getPackageType(pkg);
773
- const isEsmPackage = isESModulePackage(packageType);
774
- const exportsConditions = resolvedWildcardExports != null ? resolvedWildcardExports : pkg.exports;
775
- if (exportsConditions) {
776
- const paths = parseExport(exportsConditions, packageType);
777
- pathsMap = {
778
- ...pathsMap,
779
- ...paths
780
- };
781
- }
782
- // main export '.' from main/module/typings
783
- let mainExportCondition;
784
- if (pkg.main) {
785
- const mainExportType = isEsmPackage ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
786
- mainExportCondition = {
787
- [mainExportType]: pkg.main
788
- };
789
- }
790
- const defaultMainExport = constructFullExportCondition({
791
- ...mainExportCondition,
792
- module: pkg.module,
793
- types: getPackageTypings(pkg)
794
- }, packageType);
795
- if (!isEsmPackage && ((_pathsMap_ = pathsMap['.']) == null ? void 0 : _pathsMap_['require'])) {
796
- // pathsMap's exports.require are prioritized.
797
- defaultMainExport['require'] = pathsMap['.']['require'];
798
- }
799
- // Merge the main export into '.' paths
800
- const mainExport = {
801
- ...pathsMap['.'],
802
- ...defaultMainExport
803
- };
804
- // main export is not empty
805
- if (Object.keys(mainExport).length > 0) {
806
- pathsMap['.'] = {
807
- ...pathsMap['.'],
808
- ...mainExport
809
- };
643
+ * map from export path to output path and export conditions
644
+ */ function parseExports(pkg) {
645
+ var _pkg_exports;
646
+ const exportsField = (_pkg_exports = pkg.exports) != null ? _pkg_exports : {};
647
+ var _pkg_bin;
648
+ const bins = (_pkg_bin = pkg.bin) != null ? _pkg_bin : {};
649
+ const exportToDist = new Map();
650
+ const isEsmPkg = isESModulePackage(pkg.type);
651
+ const defaultCondition = isEsmPkg ? 'import' : 'require';
652
+ let currentPath = '.';
653
+ if (typeof exportsField === 'string') {
654
+ const outputConditionPair = [
655
+ exportsField,
656
+ defaultCondition
657
+ ];
658
+ exportToDist.set(currentPath, [
659
+ outputConditionPair
660
+ ]);
661
+ } else {
662
+ // keys means unknown if they're relative path or export type
663
+ const exportConditionKeys = Object.keys(exportsField);
664
+ for (const exportKey of exportConditionKeys){
665
+ const exportValue = exportsField[exportKey];
666
+ const exportTypes = new Set();
667
+ const isExportPath = exportKey.startsWith('.');
668
+ const childPath = isExportPath ? joinRelativePath(currentPath, exportKey) : currentPath;
669
+ collectExportPath(exportValue, exportKey, childPath, exportTypes, exportToDist);
670
+ }
810
671
  }
811
- return pathsMap;
812
- }
813
- function getPackageType(pkg) {
814
- return pkg.type || 'commonjs';
815
- }
816
- function isESModulePackage(packageType) {
817
- return packageType === 'module';
818
- }
819
- function constructDefaultExportCondition(value, packageType) {
820
- const isEsmPackage = isESModulePackage(packageType);
821
- let exportCondition;
822
- if (typeof value === 'string') {
823
- const types = getPackageTypings(value);
824
- exportCondition = {
825
- [isEsmPackage ? 'import' : 'require']: value,
826
- ...types && {
827
- types
828
- }
829
- };
672
+ if (typeof bins === 'string') {
673
+ const outputConditionPair = [
674
+ bins,
675
+ defaultCondition
676
+ ];
677
+ exportToDist.set(BINARY_TAG, [
678
+ outputConditionPair
679
+ ]);
830
680
  } else {
831
- exportCondition = value;
681
+ for (const binName of Object.keys(bins)){
682
+ const binDistPath = bins[binName];
683
+ const exportType = getExportTypeFromFile(binDistPath, pkg.type);
684
+ const exportPath = path.posix.join(BINARY_TAG, binName);
685
+ const outputConditionPair = [
686
+ binDistPath,
687
+ exportType
688
+ ];
689
+ exportToDist.set(exportPath, [
690
+ outputConditionPair
691
+ ]);
692
+ }
693
+ }
694
+ if (pkg.main || pkg.module) {
695
+ const mainExportPath = pkg.main;
696
+ const moduleExportPath = pkg.module;
697
+ const typesEntryPath = pkg.types;
698
+ const existingExportInfo = exportToDist.get('.');
699
+ exportToDist.set('.', [
700
+ ...existingExportInfo || [],
701
+ [
702
+ mainExportPath,
703
+ getMainFieldExportType(pkg)
704
+ ],
705
+ Boolean(moduleExportPath) && [
706
+ moduleExportPath,
707
+ 'import'
708
+ ],
709
+ Boolean(typesEntryPath) && [
710
+ typesEntryPath,
711
+ 'types'
712
+ ]
713
+ ].filter(Boolean));
832
714
  }
833
- return constructFullExportCondition(exportCondition, packageType);
715
+ return exportToDist;
834
716
  }
835
717
  function isEsmExportName(name, ext) {
836
718
  return [
@@ -866,7 +748,8 @@ function getExportsDistFilesOfCondition(pkg, parsedExportCondition, cwd) {
866
748
  uniqueFiles.add(distFile);
867
749
  dist.push({
868
750
  format,
869
- file: distFile
751
+ file: distFile,
752
+ exportCondition
870
753
  });
871
754
  }
872
755
  return dist;
@@ -886,17 +769,9 @@ function getExportTypeFromFile(filename, pkgType) {
886
769
  return exportType;
887
770
  }
888
771
 
889
- const swcMinifyOptions = {
890
- compress: true,
891
- format: {
892
- comments: 'some'
893
- },
894
- mangle: {
895
- toplevel: true
896
- }
897
- };
898
- // return { 'process.env.<key>': '<value>' }
899
- function getDefinedInlineVariables(envs, parsedExportCondition) {
772
+ /**
773
+ * @return {Record<string, string>} env { 'process.env.<key>': '<value>' }
774
+ */ function getDefinedInlineVariables(envs, parsedExportCondition) {
900
775
  if (!envs.includes('NODE_ENV')) {
901
776
  envs.push('NODE_ENV');
902
777
  }
@@ -907,9 +782,14 @@ function getDefinedInlineVariables(envs, parsedExportCondition) {
907
782
  }
908
783
  return acc;
909
784
  }, {});
910
- // handle .development, .production
911
- const condName = parsedExportCondition.name.startsWith('.') ? parsedExportCondition.name.slice(1) : parsedExportCondition.name;
912
- const exportConditionNames = new Set(Object.keys(parsedExportCondition.export).concat(condName));
785
+ const exportConditionNames = Object.keys(parsedExportCondition.export).reduce((acc, key)=>{
786
+ // key could be 'require' or 'import.development' etc.
787
+ const exportTypes = key.split('.');
788
+ for (const exportType of exportTypes){
789
+ acc.add(exportType);
790
+ }
791
+ return acc;
792
+ }, new Set());
913
793
  // For development and production convention, we override the NODE_ENV value
914
794
  if (exportConditionNames.has('development')) {
915
795
  envVars['process.env.NODE_ENV'] = JSON.stringify('development');
@@ -921,17 +801,243 @@ function getDefinedInlineVariables(envs, parsedExportCondition) {
921
801
  }
922
802
  return envVars;
923
803
  }
804
+
805
+ // shared.ts -> ./shared
806
+ // shared.<export condition>.ts -> ./shared
807
+ // index.ts -> ./index
808
+ // index.development.ts -> ./index.development
809
+ function sourceFilenameToExportPath(filename) {
810
+ const baseName = baseNameWithoutExtension(filename);
811
+ let exportPath = baseName;
812
+ return relativify(exportPath);
813
+ }
814
+ async function collectEntriesFromParsedExports(cwd, parsedExportsInfo, sourceFile) {
815
+ const entries = {};
816
+ if (sourceFile) {
817
+ const defaultExport = parsedExportsInfo.get('.')[0];
818
+ entries['.'] = {
819
+ source: sourceFile,
820
+ name: '.',
821
+ export: {
822
+ default: defaultExport[0]
823
+ }
824
+ };
825
+ }
826
+ // Find source files
827
+ const { bins, exportsEntries } = await collectSourceEntries(path.join(cwd, SRC));
828
+ // A mapping between each export path and its related special export conditions,
829
+ // excluding the 'default' export condition.
830
+ // { '.' => Set('development') }
831
+ const pathSpecialConditionsMap = {};
832
+ for (const [exportPath] of exportsEntries){
833
+ const normalizedExportPath = normalizeExportPath(exportPath);
834
+ if (!pathSpecialConditionsMap[normalizedExportPath]) {
835
+ pathSpecialConditionsMap[normalizedExportPath] = new Set();
836
+ }
837
+ const exportType = getExportTypeFromExportPath(exportPath);
838
+ if (exportType !== 'default') {
839
+ pathSpecialConditionsMap[normalizedExportPath].add(exportType);
840
+ }
841
+ }
842
+ // Traverse source files and try to match the entries
843
+ // Find exports from parsed exports info
844
+ // entryExportPath can be: '.', './index.development', './shared.edge-light', etc.
845
+ for (const [entryExportPath, sourceFilesMap] of exportsEntries){
846
+ const normalizedExportPath = normalizeExportPath(entryExportPath);
847
+ const entryExportPathType = getExportTypeFromExportPath(entryExportPath);
848
+ const outputExports = parsedExportsInfo.get(normalizedExportPath);
849
+ if (!outputExports) {
850
+ continue;
851
+ }
852
+ for (const [outputPath, composedExportType] of outputExports){
853
+ const matchedExportType = getSpecialExportTypeFromExportPath(composedExportType);
854
+ // export type can be: default, development, react-server, etc.
855
+ const sourceFile = sourceFilesMap[matchedExportType] || sourceFilesMap.default;
856
+ if (!sourceFile) {
857
+ continue;
858
+ }
859
+ if (!entries[entryExportPath]) {
860
+ entries[entryExportPath] = {
861
+ source: sourceFile,
862
+ name: normalizedExportPath,
863
+ export: {}
864
+ };
865
+ }
866
+ const exportMap = entries[entryExportPath].export;
867
+ if (entryExportPathType === 'default' && matchedExportType !== 'default' && pathSpecialConditionsMap[normalizedExportPath].size > 0) {
868
+ continue;
869
+ }
870
+ exportMap[composedExportType] = outputPath;
871
+ }
872
+ }
873
+ // Handling binaries
874
+ for (const [exportPath, sourceFile] of bins){
875
+ const normalizedExportPath = normalizeExportPath(exportPath);
876
+ const outputExports = parsedExportsInfo.get(normalizedExportPath);
877
+ if (!outputExports) {
878
+ continue;
879
+ }
880
+ for (const [outputPath, exportType] of outputExports){
881
+ entries[exportPath] = {
882
+ source: sourceFile,
883
+ name: exportPath,
884
+ export: {
885
+ [exportType]: outputPath
886
+ }
887
+ };
888
+ }
889
+ }
890
+ return entries;
891
+ }
892
+ // ./index -> import|require|default
893
+ // ./index.development -> development
894
+ // ./index.react-server -> react-server
895
+ function getExportTypeFromExportPath(exportPath) {
896
+ // Skip the first two segments: `.` and `index`
897
+ const exportTypes = exportPath.split('.').slice(2);
898
+ return getExportTypeFromExportTypes(exportTypes);
899
+ }
900
+ function getSpecialExportTypeFromExportPath(composedExportType) {
901
+ const exportTypes = composedExportType.split('.');
902
+ for (const exportType of exportTypes){
903
+ if (specialExportConventions.has(exportType)) {
904
+ return exportType;
905
+ }
906
+ }
907
+ return 'default';
908
+ }
909
+ function getExportTypeFromExportTypes(types) {
910
+ let exportType = 'default';
911
+ new Set(types).forEach((value)=>{
912
+ if (specialExportConventions.has(value)) {
913
+ exportType = value;
914
+ } else if (value === 'import' || value === 'require') {
915
+ exportType = value;
916
+ }
917
+ });
918
+ return exportType;
919
+ }
920
+ // ./index -> .
921
+ // ./index.development -> .
922
+ // ./index.react-server -> .
923
+ // ./shared -> ./shared
924
+ // ./shared.development -> ./shared
925
+ // $binary -> $binary
926
+ // $binary/index -> $binary
927
+ // $binary/foo -> $binary/foo
928
+ function normalizeExportPath(exportPath) {
929
+ if (exportPath.startsWith(BINARY_TAG)) {
930
+ if (exportPath === `${BINARY_TAG}/index`) {
931
+ exportPath = BINARY_TAG;
932
+ }
933
+ return exportPath;
934
+ }
935
+ const baseName = exportPath.split('.').slice(0, 2).join('.');
936
+ if (baseName === './index') {
937
+ return '.';
938
+ }
939
+ return baseName;
940
+ }
941
+ async function collectSourceEntries(sourceFolderPath) {
942
+ const bins = new Map();
943
+ const exportsEntries = new Map();
944
+ if (!fs__default.default.existsSync(sourceFolderPath)) {
945
+ return {
946
+ bins,
947
+ exportsEntries
948
+ };
949
+ }
950
+ const entryFileDirentList = await fsp__default.default.readdir(sourceFolderPath, {
951
+ withFileTypes: true
952
+ });
953
+ for (const dirent of entryFileDirentList){
954
+ if (dirent.isDirectory()) {
955
+ if (dirent.name === 'bin') {
956
+ const binDirentList = await fsp__default.default.readdir(path__default.default.join(sourceFolderPath, dirent.name), {
957
+ withFileTypes: true
958
+ });
959
+ for (const binDirent of binDirentList){
960
+ if (binDirent.isFile()) {
961
+ const binFileAbsolutePath = path__default.default.join(sourceFolderPath, dirent.name, binDirent.name);
962
+ const binExportPath = sourceFilenameToExportPath(binDirent.name);
963
+ if (fs__default.default.existsSync(binFileAbsolutePath)) {
964
+ bins.set(path.posix.join(BINARY_TAG, binExportPath), binFileAbsolutePath);
965
+ }
966
+ }
967
+ }
968
+ } else {
969
+ // Search folder/index.<ext> convention entries
970
+ for (const extension of availableExtensions){
971
+ const indexAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${extension}`);
972
+ // Search folder/index.<special type>.<ext> convention entries
973
+ for (const specialExportType of runtimeExportConventions){
974
+ const indexSpecialAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${specialExportType}.${extension}`);
975
+ if (fs__default.default.existsSync(indexSpecialAbsoluteFile)) {
976
+ // Add special export path
977
+ // { ./<export path>.<special cond>: { <special cond>: 'index.<special cond>.<ext>' } }
978
+ const exportPath = sourceFilenameToExportPath(dirent.name);
979
+ const specialExportPath = exportPath + '.' + specialExportType;
980
+ const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
981
+ sourceFilesMap[specialExportType] = indexSpecialAbsoluteFile;
982
+ exportsEntries.set(specialExportPath, sourceFilesMap);
983
+ }
984
+ }
985
+ if (fs__default.default.existsSync(indexAbsoluteFile) && !isTestFile(indexAbsoluteFile)) {
986
+ const exportPath = sourceFilenameToExportPath(dirent.name);
987
+ const sourceFilesMap = exportsEntries.get(exportPath) || {};
988
+ const exportType = getExportTypeFromExportPath(exportPath);
989
+ sourceFilesMap[exportType] = indexAbsoluteFile;
990
+ exportsEntries.set(exportPath, sourceFilesMap);
991
+ break;
992
+ }
993
+ }
994
+ }
995
+ } else if (dirent.isFile()) {
996
+ const isAvailableExtension = availableExtensions.has(path__default.default.extname(dirent.name).slice(1));
997
+ if (isAvailableExtension) {
998
+ const exportPath = sourceFilenameToExportPath(dirent.name);
999
+ const isBinFile = exportPath === './bin';
1000
+ const fullPath = path__default.default.join(sourceFolderPath, dirent.name);
1001
+ if (isBinFile) {
1002
+ bins.set(BINARY_TAG, fullPath);
1003
+ } else {
1004
+ if (hasAvailableExtension(dirent.name) && !isTestFile(dirent.name)) {
1005
+ const sourceFilesMap = exportsEntries.get(exportPath) || {};
1006
+ const exportType = getExportTypeFromExportPath(exportPath);
1007
+ sourceFilesMap[exportType] = fullPath;
1008
+ exportsEntries.set(exportPath, sourceFilesMap);
1009
+ }
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+ return {
1015
+ bins,
1016
+ exportsEntries
1017
+ };
1018
+ }
1019
+
1020
+ const swcMinifyOptions = {
1021
+ compress: true,
1022
+ format: {
1023
+ comments: 'some'
1024
+ },
1025
+ mangle: {
1026
+ toplevel: true
1027
+ }
1028
+ };
924
1029
  /**
925
1030
  * return {
926
1031
  * <absolute source path>: <pkg>/<export>
927
1032
  * }
928
- */ function getReversedAlias(entries) {
1033
+ */ function getReversedAlias({ entries, name }) {
929
1034
  const alias = {};
930
- for (const [entryImportPath, exportCondition] of Object.entries(entries)){
931
- const exportType = entryImportPath.split('.')[1] // e.g. index.react-server, pick react-server
932
- ;
933
- if (!exportType) {
934
- alias[exportCondition.source] = entryImportPath;
1035
+ for (const [entryExportPath, exportCondition] of Object.entries(entries)){
1036
+ const normalizedExportPath = normalizeExportPath(entryExportPath);
1037
+ // entryExportPath format: ./index, ./shared, etc.
1038
+ const specialExportType = getSpecialExportTypeFromExportPath(entryExportPath);
1039
+ if (specialExportType === 'default') {
1040
+ alias[exportCondition.source] = path.posix.join(name || '', normalizedExportPath);
935
1041
  }
936
1042
  }
937
1043
  return alias;
@@ -949,7 +1055,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
949
1055
  for (const [exportImportPath, exportCondition] of Object.entries(entries)){
950
1056
  const entryFilePath = exportCondition.source;
951
1057
  if (entryFilePath !== entry) {
952
- externals.push(exportImportPath);
1058
+ externals.push(path.posix.join(pkg.name || '', normalizeExportPath(exportImportPath)));
953
1059
  externals.push(entryFilePath);
954
1060
  }
955
1061
  }
@@ -1090,18 +1196,6 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1090
1196
  }
1091
1197
  };
1092
1198
  }
1093
- function hasEsmExport(exportPaths, tsCompilerOptions) {
1094
- let hasEsm = false;
1095
- for(const key in exportPaths){
1096
- const exportInfo = exportPaths[key];
1097
- const exportInfoEntries = Object.entries(exportInfo);
1098
- if (exportInfoEntries.some(([exportType, file])=>isEsmExportName(exportType, file))) {
1099
- hasEsm = true;
1100
- break;
1101
- }
1102
- }
1103
- return Boolean(hasEsm || (tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop));
1104
- }
1105
1199
  function getModuleLater(moduleMeta) {
1106
1200
  const directives = (moduleMeta.preserveDirectives || {
1107
1201
  directives: []
@@ -1176,9 +1270,11 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
1176
1270
  }
1177
1271
  async function buildOutputConfigs(entry, bundleConfig, exportCondition, buildContext, dts) {
1178
1272
  const { format } = bundleConfig;
1179
- const { entries, pkg, exportPaths, cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1273
+ const { entries, pkg, // exportPaths,
1274
+ cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1180
1275
  // Add esm mark and interop helper if esm export is detected
1181
- const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions);
1276
+ const useEsModuleMark = tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop // hasEsmExport(exportPaths, tsCompilerOptions)
1277
+ ;
1182
1278
  const absoluteOutputFile = path.resolve(cwd, bundleConfig.file);
1183
1279
  const outputFileExtension = path.extname(absoluteOutputFile);
1184
1280
  const name = filePathWithoutExtension(absoluteOutputFile);
@@ -1223,111 +1319,6 @@ async function buildEntryConfig(bundleConfig, pluginContext, dts) {
1223
1319
  }
1224
1320
  return configs;
1225
1321
  }
1226
- async function collectEntry(// export type, e.g. react-server, edge-light those special cases required suffix
1227
- exportType, options) {
1228
- const { cwd, pkg, entries, entryPath, exportCondRef, entryExport: originEntryExport } = options;
1229
- let entryExport = originEntryExport;
1230
- let exportCondForType = {
1231
- ...exportCondRef
1232
- };
1233
- // Special cases of export type, only pass down the exportPaths for the type
1234
- if (suffixedExportConventions.has(exportType)) {
1235
- exportCondForType = {
1236
- [exportType]: exportCondRef[exportType]
1237
- };
1238
- } else if (exportType[0] === '.' && suffixedExportConventions.has(exportType.slice(1))) {
1239
- // e.g. .development, .production that has both esm and cjs export
1240
- exportCondForType = exportCondRef;
1241
- exportType = exportType.slice(1);
1242
- entryExport = entryExport.replace(exportType, '');
1243
- } else {
1244
- // Basic export type, pass down the exportPaths with erasing the special ones
1245
- for (const exportType of suffixedExportConventions){
1246
- delete exportCondForType[exportType];
1247
- }
1248
- }
1249
- let source = entryPath;
1250
- if (source) {
1251
- source = resolveSourceFile(cwd, source);
1252
- } else {
1253
- source = await getSourcePathFromExportPath(cwd, entryExport, exportType);
1254
- }
1255
- if (!source) {
1256
- return;
1257
- }
1258
- const exportCondition = {
1259
- source,
1260
- name: originEntryExport,
1261
- export: exportCondForType
1262
- };
1263
- const nameWithExportPath = pkg.name ? path__default.default.join(pkg.name, exportCondition.name) : exportCondition.name;
1264
- const needsDelimiter = !nameWithExportPath.endsWith('.') && exportType;
1265
- const entryImportPath = nameWithExportPath + (needsDelimiter ? '.' : '') + exportType;
1266
- entries[entryImportPath] = exportCondition;
1267
- }
1268
- /*
1269
- * build configs for each entry from package exports
1270
- *
1271
- * return { <pkg>/<export>: { input: InputOptions, output: OutputOptions[] }
1272
- */ async function collectEntries(pkg, entryPath, exportPaths, cwd) {
1273
- const entries = {};
1274
- const binaryExports = pkg.bin;
1275
- if (binaryExports) {
1276
- // binDistPaths: [ [ 'bin1', './dist/bin1.js'], [ 'bin2', './dist/bin2.js'] ]
1277
- const binPairs = typeof binaryExports === 'string' ? [
1278
- [
1279
- 'bin',
1280
- binaryExports
1281
- ]
1282
- ] : Object.keys(binaryExports).map((key)=>[
1283
- path.join('bin', key),
1284
- binaryExports[key]
1285
- ]);
1286
- const binExportPaths = binPairs.reduce((acc, [binName, binDistPath])=>{
1287
- const exportType = getExportTypeFromFile(binDistPath, pkg.type);
1288
- acc[binName] = {
1289
- [exportType]: binDistPath
1290
- };
1291
- return acc;
1292
- }, {});
1293
- for (const [binName] of binPairs){
1294
- const source = await getSourcePathFromExportPath(cwd, binName, '$binary');
1295
- if (!source) {
1296
- logger.warn(`Cannot find source file for ${binName}`);
1297
- continue;
1298
- }
1299
- const binEntryPath = await resolveSourceFile(cwd, source);
1300
- entries[binName] = {
1301
- source: binEntryPath,
1302
- name: binName,
1303
- export: binExportPaths[binName]
1304
- };
1305
- }
1306
- }
1307
- const collectEntriesPromises = Object.keys(exportPaths).map(async (entryExport)=>{
1308
- const exportCond = exportPaths[entryExport];
1309
- const collectEntryOptions = {
1310
- cwd,
1311
- pkg,
1312
- entries,
1313
- entryPath,
1314
- exportCondRef: exportCond,
1315
- entryExport
1316
- };
1317
- if (entryExport.startsWith('.')) {
1318
- await collectEntry('', collectEntryOptions);
1319
- for (const exportCondType of suffixedExportConventions){
1320
- if (exportCond[exportCondType]) {
1321
- await collectEntry(exportCondType, collectEntryOptions);
1322
- } else if (entryExport === '.' + exportCondType) {
1323
- await collectEntry(entryExport, collectEntryOptions);
1324
- }
1325
- }
1326
- }
1327
- });
1328
- await Promise.all(collectEntriesPromises);
1329
- return entries;
1330
- }
1331
1322
  async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1332
1323
  const { file } = bundleConfig;
1333
1324
  const { pkg, cwd } = pluginContext;
@@ -1335,29 +1326,32 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1335
1326
  const outputExports = getExportsDistFilesOfCondition(pkg, exportCondition, cwd);
1336
1327
  // If there's nothing found, give a default output
1337
1328
  if (outputExports.length === 0 && !pkg.bin) {
1338
- const defaultFormat = isESModulePackage(pkg.type) ? 'esm' : 'cjs';
1329
+ const isEsmPkg = isESModulePackage(pkg.type);
1330
+ const defaultFormat = isEsmPkg ? 'esm' : 'cjs';
1339
1331
  outputExports.push({
1340
1332
  format: defaultFormat,
1341
- file: path.join(cwd, 'dist/index.js')
1333
+ file: path.join(cwd, 'dist/index.js'.replace('/', path__default.default.sep)),
1334
+ exportCondition: 'default'
1342
1335
  });
1343
1336
  }
1344
1337
  let bundleOptions = [];
1345
1338
  // multi outputs with specified format
1346
1339
  // CLI output option is always prioritized
1347
1340
  if (file) {
1348
- var _outputExports_;
1349
- const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format;
1341
+ const fallbackExport = outputExports[0];
1350
1342
  bundleOptions = [
1351
1343
  {
1352
- resolvedFile: path.resolve(cwd, file),
1353
- format: bundleConfig.format || fallbackFormat
1344
+ file: path.resolve(cwd, file),
1345
+ format: bundleConfig.format || fallbackExport.format,
1346
+ exportCondition: fallbackExport.exportCondition
1354
1347
  }
1355
1348
  ];
1356
1349
  } else {
1357
1350
  bundleOptions = outputExports.map((exportDist)=>{
1358
1351
  return {
1359
- resolvedFile: path.resolve(cwd, exportDist.file),
1360
- format: exportDist.format
1352
+ file: path.resolve(cwd, exportDist.file),
1353
+ format: exportDist.format,
1354
+ exportCondition: exportDist.exportCondition
1361
1355
  };
1362
1356
  });
1363
1357
  }
@@ -1369,22 +1363,29 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1369
1363
  if (exportCondition.export.types) {
1370
1364
  uniqTypes.add(path.resolve(cwd, exportCondition.export.types));
1371
1365
  }
1372
- const typeForExtension = getExportFileTypePath(bundleOption.resolvedFile);
1366
+ const typeForExtension = getExportFileTypePath(bundleOption.file);
1373
1367
  uniqTypes.add(typeForExtension);
1374
1368
  });
1375
1369
  bundleOptions = Array.from(uniqTypes).map((typeFile)=>{
1376
1370
  return {
1377
- resolvedFile: typeFile,
1378
- format: 'esm'
1371
+ file: typeFile,
1372
+ format: 'esm',
1373
+ exportCondition: 'types'
1379
1374
  };
1380
1375
  });
1381
1376
  }
1382
1377
  const outputConfigs = bundleOptions.map(async (bundleOption)=>{
1378
+ const targetExportCondition = {
1379
+ ...exportCondition,
1380
+ export: {
1381
+ [bundleOption.exportCondition]: bundleOption.exportCondition === 'types' ? bundleOption.file : exportCondition.export[bundleOption.exportCondition]
1382
+ }
1383
+ };
1383
1384
  return await buildOutputConfigs(entry, {
1384
1385
  ...bundleConfig,
1385
- file: bundleOption.resolvedFile,
1386
+ file: bundleOption.file,
1386
1387
  format: bundleOption.format
1387
- }, exportCondition, pluginContext, dts);
1388
+ }, targetExportCondition, pluginContext, dts);
1388
1389
  });
1389
1390
  return Promise.all(outputConfigs);
1390
1391
  }
@@ -1440,7 +1441,7 @@ function createOutputState({ entries }) {
1440
1441
  };
1441
1442
  }
1442
1443
  function isBin(filename) {
1443
- return filename === 'bin' || filename.startsWith('bin/');
1444
+ return filename === BINARY_TAG || filename.startsWith(BINARY_TAG + '/');
1444
1445
  }
1445
1446
  function isTypeFile(filename) {
1446
1447
  return filename.endsWith('.d.ts') || filename.endsWith('.d.mts') || filename.endsWith('.d.cts');
@@ -1448,20 +1449,12 @@ function isTypeFile(filename) {
1448
1449
  function normalizeExportName(exportName) {
1449
1450
  const isBinary = isBin(exportName);
1450
1451
  let result = exportName;
1451
- const isSubpathExport = exportName.includes('/');
1452
- const isSpecialExport = exportName.includes('.');
1453
1452
  if (isBinary) {
1454
- result = (exportName.replace(/bin(\/|$)/, '') || '.') + ' (bin)';
1455
- } else if (isSubpathExport || isSpecialExport) {
1456
- const subExportName = exportName.split('/')[1] || exportName;
1457
- if (subExportName.includes('.') && subExportName !== '.') {
1458
- const [originExportName, specialCondition] = subExportName.split('.');
1459
- result = (isSubpathExport ? relativify(originExportName) : '.') + ' (' + specialCondition + ')';
1460
- } else {
1461
- result = isSubpathExport ? relativify(subExportName) : '.';
1462
- }
1453
+ result = (exportName.replace(new RegExp(`^\\${BINARY_TAG}\\/?`), '') || '.') + ' (bin)';
1463
1454
  } else {
1464
- result = '.';
1455
+ const normalizedExportPath = normalizeExportPath(exportName);
1456
+ const specialConditionName = getSpecialExportTypeFromExportPath(exportName);
1457
+ result = normalizedExportPath + (specialConditionName !== 'default' ? ` (${specialConditionName})` : '');
1465
1458
  }
1466
1459
  return result;
1467
1460
  }
@@ -1512,61 +1505,6 @@ function logOutputState(sizeCollector) {
1512
1505
  });
1513
1506
  }
1514
1507
 
1515
- // TODO: support nested wildcard exportsCondition (e.g. './foo/*')
1516
- const getWildcardExports = (exportsCondition)=>{
1517
- return {
1518
- './*': exportsCondition['./*']
1519
- };
1520
- };
1521
- const isExportable = async (dirent, pathname)=>{
1522
- if (dirent.isDirectory()) {
1523
- const innerDirents = await fsp__default.default.readdir(path__default.default.join(pathname, dirent.name), {
1524
- withFileTypes: true
1525
- });
1526
- return innerDirents.some(({ name })=>name.startsWith('index') && hasAvailableExtension(name));
1527
- }
1528
- return dirent.isFile() && !dirent.name.startsWith('index') && hasAvailableExtension(dirent.name);
1529
- };
1530
- async function getExportables(cwd, excludeKeys) {
1531
- const pathname = path__default.default.resolve(cwd, SRC);
1532
- const dirents = await fsp__default.default.readdir(pathname, {
1533
- withFileTypes: true
1534
- });
1535
- const exportables = await Promise.all(dirents.map(async (dirent)=>await isExportable(dirent, pathname) && !excludeKeys.includes(dirent.name) ? dirent.name : undefined));
1536
- return exportables.filter(nonNullable);
1537
- }
1538
- function mapWildcard(wildcardExports, exportables) {
1539
- return exportables.map((exportable)=>{
1540
- const isFile = exportable.includes('.');
1541
- const filename = isFile ? filePathWithoutExtension(exportable) : exportable;
1542
- return {
1543
- [`./${filename}`]: Object.fromEntries(Object.entries(wildcardExports['./*']).map(([key, value])=>[
1544
- key,
1545
- value.replace(/\*/g, isFile ? filename : `${filename}/index`)
1546
- ]))
1547
- };
1548
- });
1549
- }
1550
- async function resolveWildcardExports(exportsCondition, cwd) {
1551
- if (!exportsCondition || typeof exportsCondition === 'string') return undefined;
1552
- const hasWildcard = !!exportsCondition['./*'];
1553
- if (hasWildcard) {
1554
- logger.warn(`The wildcard export "./*" is experimental and may change or be removed at any time.\n` + 'To open an issue, please visit https://github.com/huozhi/bunchee/issues' + '.\n');
1555
- // './foo' -> ['foo']; './foo/bar' -> ['bar']
1556
- // will contain '*' also but it's not a problem
1557
- const excludeKeys = Object.keys(exportsCondition).map((key)=>key.split('/').pop());
1558
- const exportables = await getExportables(cwd, excludeKeys);
1559
- if (exportables.length > 0) {
1560
- const wildcardExports = getWildcardExports(exportsCondition);
1561
- const resolvedWildcardExports = mapWildcard(wildcardExports, exportables);
1562
- const resolvedExports = Object.assign({}, exportsCondition, ...resolvedWildcardExports);
1563
- delete resolvedExports['./*'];
1564
- return resolvedExports;
1565
- }
1566
- }
1567
- return undefined;
1568
- }
1569
-
1570
1508
  function assignDefault(options, name, defaultValue) {
1571
1509
  if (!(name in options) || options[name] == null) {
1572
1510
  options[name] = defaultValue;
@@ -1582,12 +1520,11 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1582
1520
  assignDefault(options, 'minify', false);
1583
1521
  assignDefault(options, 'target', 'es2015');
1584
1522
  const pkg = await getPackageMeta(cwd);
1585
- const resolvedWildcardExports = await resolveWildcardExports(pkg.exports, cwd);
1586
- const packageType = getPackageType(pkg);
1587
- const exportPaths = getExportPaths(pkg, resolvedWildcardExports);
1588
- const isMultiEntries = hasMultiEntryExport(exportPaths) // exportPathsLength > 1
1589
- ;
1523
+ const parsedExportsInfo = parseExports(pkg);
1524
+ const isMultiEntries = hasMultiEntryExport(parsedExportsInfo);
1590
1525
  const hasBin = Boolean(pkg.bin);
1526
+ // Original input file path, client path might change later
1527
+ const inputFile = cliEntryPath;
1591
1528
  const isFromCli = Boolean(cliEntryPath);
1592
1529
  let tsConfig = resolveTsConfig(cwd);
1593
1530
  let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
@@ -1602,21 +1539,27 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1602
1539
  cliEntryPath = cliEntryPath || await getSourcePathFromExportPath(cwd, '.', 'default') || '';
1603
1540
  }
1604
1541
  // Handle CLI input
1605
- if (cliEntryPath) {
1606
- let mainEntryPath;
1607
- let typesEntryPath;
1542
+ let mainExportPath;
1543
+ let typesEntryPath;
1544
+ if (isFromCli) {
1608
1545
  // with -o option
1609
1546
  if (options.file) {
1610
- mainEntryPath = options.file;
1547
+ mainExportPath = options.file;
1611
1548
  }
1612
- if (mainEntryPath) {
1549
+ if (mainExportPath) {
1613
1550
  if (options.dts) {
1614
- typesEntryPath = getExportFileTypePath(mainEntryPath);
1551
+ typesEntryPath = getExportFileTypePath(mainExportPath);
1615
1552
  }
1616
- exportPaths['.'] = constructDefaultExportCondition({
1617
- main: mainEntryPath,
1618
- types: typesEntryPath
1619
- }, packageType);
1553
+ parsedExportsInfo.set('.', [
1554
+ [
1555
+ mainExportPath,
1556
+ 'default'
1557
+ ],
1558
+ Boolean(typesEntryPath) && [
1559
+ typesEntryPath,
1560
+ 'types'
1561
+ ]
1562
+ ].filter(Boolean));
1620
1563
  }
1621
1564
  }
1622
1565
  const bundleOrWatch = async (rollupConfig)=>{
@@ -1646,7 +1589,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1646
1589
  }
1647
1590
  }
1648
1591
  }
1649
- const entries = await collectEntries(pkg, cliEntryPath, exportPaths, cwd);
1592
+ const entries = await collectEntriesFromParsedExports(cwd, parsedExportsInfo, inputFile);
1650
1593
  const hasTypeScriptFiles = Object.values(entries).some((entry)=>isTypescriptFile(entry.source));
1651
1594
  if (hasTypeScriptFiles && !hasTsConfig) {
1652
1595
  const tsConfigPath = path.resolve(cwd, 'tsconfig.json');
@@ -1657,11 +1600,13 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1657
1600
  const sizeCollector = createOutputState({
1658
1601
  entries
1659
1602
  });
1660
- const entriesAlias = getReversedAlias(entries);
1603
+ const entriesAlias = getReversedAlias({
1604
+ entries,
1605
+ name: pkg.name
1606
+ });
1661
1607
  const buildContext = {
1662
1608
  entries,
1663
1609
  pkg,
1664
- exportPaths,
1665
1610
  cwd,
1666
1611
  tsOptions: defaultTsOptions,
1667
1612
  useTypeScript: hasTsConfig,
@@ -1673,7 +1618,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1673
1618
  };
1674
1619
  const buildConfigs = await buildEntryConfig(options, buildContext, false);
1675
1620
  const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
1676
- const typesJobs = hasTsConfig ? (await buildEntryConfig(options, buildContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
1621
+ const typesJobs = hasTsConfig && options.dts !== false ? (await buildEntryConfig(options, buildContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
1677
1622
  const totalJobs = assetsJobs.concat(typesJobs);
1678
1623
  const result = await Promise.all(totalJobs);
1679
1624
  if (result.length === 0) {