bunchee 4.4.7 → 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 +442 -496
  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,23 +801,249 @@ 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;
938
1044
  }
939
1045
  async function buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts) {
940
- var _bundleConfig_file;
1046
+ var _bundleConfig_file, _bundleConfig_file1;
941
1047
  const { entries, pkg, cwd, tsOptions: { tsConfigPath, tsCompilerOptions }, pluginContext } = buildContext;
942
1048
  const hasNoExternal = bundleConfig.external === null;
943
1049
  var _bundleConfig_external;
@@ -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
  }
@@ -983,7 +1089,8 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
983
1089
  };
984
1090
  const sizePlugin = pluginContext.outputState.plugin(cwd);
985
1091
  // common plugins for both dts and ts assets that need to be processed
986
- const aliasFormat = dts ? ((_bundleConfig_file = bundleConfig.file) == null ? void 0 : _bundleConfig_file.endsWith('.d.cts')) ? 'cjs' : 'esm' : bundleConfig.format;
1092
+ // If it's a .d.ts file under non-ESM package or .d.cts file, use cjs types alias.
1093
+ const aliasFormat = dts ? ((_bundleConfig_file = bundleConfig.file) == null ? void 0 : _bundleConfig_file.endsWith('.d.cts')) || ((_bundleConfig_file1 = bundleConfig.file) == null ? void 0 : _bundleConfig_file1.endsWith('.d.ts')) && !isESModulePackage(pkg.type) ? 'cjs' : 'esm' : bundleConfig.format;
987
1094
  const commonPlugins = [
988
1095
  json__default.default(),
989
1096
  sizePlugin,
@@ -1089,18 +1196,6 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1089
1196
  }
1090
1197
  };
1091
1198
  }
1092
- function hasEsmExport(exportPaths, tsCompilerOptions) {
1093
- let hasEsm = false;
1094
- for(const key in exportPaths){
1095
- const exportInfo = exportPaths[key];
1096
- const exportInfoEntries = Object.entries(exportInfo);
1097
- if (exportInfoEntries.some(([exportType, file])=>isEsmExportName(exportType, file))) {
1098
- hasEsm = true;
1099
- break;
1100
- }
1101
- }
1102
- return Boolean(hasEsm || (tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop));
1103
- }
1104
1199
  function getModuleLater(moduleMeta) {
1105
1200
  const directives = (moduleMeta.preserveDirectives || {
1106
1201
  directives: []
@@ -1175,9 +1270,11 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
1175
1270
  }
1176
1271
  async function buildOutputConfigs(entry, bundleConfig, exportCondition, buildContext, dts) {
1177
1272
  const { format } = bundleConfig;
1178
- const { entries, pkg, exportPaths, cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1273
+ const { entries, pkg, // exportPaths,
1274
+ cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1179
1275
  // Add esm mark and interop helper if esm export is detected
1180
- const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions);
1276
+ const useEsModuleMark = tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop // hasEsmExport(exportPaths, tsCompilerOptions)
1277
+ ;
1181
1278
  const absoluteOutputFile = path.resolve(cwd, bundleConfig.file);
1182
1279
  const outputFileExtension = path.extname(absoluteOutputFile);
1183
1280
  const name = filePathWithoutExtension(absoluteOutputFile);
@@ -1222,111 +1319,6 @@ async function buildEntryConfig(bundleConfig, pluginContext, dts) {
1222
1319
  }
1223
1320
  return configs;
1224
1321
  }
1225
- async function collectEntry(// export type, e.g. react-server, edge-light those special cases required suffix
1226
- exportType, options) {
1227
- const { cwd, pkg, entries, entryPath, exportCondRef, entryExport: originEntryExport } = options;
1228
- let entryExport = originEntryExport;
1229
- let exportCondForType = {
1230
- ...exportCondRef
1231
- };
1232
- // Special cases of export type, only pass down the exportPaths for the type
1233
- if (suffixedExportConventions.has(exportType)) {
1234
- exportCondForType = {
1235
- [exportType]: exportCondRef[exportType]
1236
- };
1237
- } else if (exportType[0] === '.' && suffixedExportConventions.has(exportType.slice(1))) {
1238
- // e.g. .development, .production that has both esm and cjs export
1239
- exportCondForType = exportCondRef;
1240
- exportType = exportType.slice(1);
1241
- entryExport = entryExport.replace(exportType, '');
1242
- } else {
1243
- // Basic export type, pass down the exportPaths with erasing the special ones
1244
- for (const exportType of suffixedExportConventions){
1245
- delete exportCondForType[exportType];
1246
- }
1247
- }
1248
- let source = entryPath;
1249
- if (source) {
1250
- source = resolveSourceFile(cwd, source);
1251
- } else {
1252
- source = await getSourcePathFromExportPath(cwd, entryExport, exportType);
1253
- }
1254
- if (!source) {
1255
- return;
1256
- }
1257
- const exportCondition = {
1258
- source,
1259
- name: originEntryExport,
1260
- export: exportCondForType
1261
- };
1262
- const nameWithExportPath = pkg.name ? path__default.default.join(pkg.name, exportCondition.name) : exportCondition.name;
1263
- const needsDelimiter = !nameWithExportPath.endsWith('.') && exportType;
1264
- const entryImportPath = nameWithExportPath + (needsDelimiter ? '.' : '') + exportType;
1265
- entries[entryImportPath] = exportCondition;
1266
- }
1267
- /*
1268
- * build configs for each entry from package exports
1269
- *
1270
- * return { <pkg>/<export>: { input: InputOptions, output: OutputOptions[] }
1271
- */ async function collectEntries(pkg, entryPath, exportPaths, cwd) {
1272
- const entries = {};
1273
- const binaryExports = pkg.bin;
1274
- if (binaryExports) {
1275
- // binDistPaths: [ [ 'bin1', './dist/bin1.js'], [ 'bin2', './dist/bin2.js'] ]
1276
- const binPairs = typeof binaryExports === 'string' ? [
1277
- [
1278
- 'bin',
1279
- binaryExports
1280
- ]
1281
- ] : Object.keys(binaryExports).map((key)=>[
1282
- path.join('bin', key),
1283
- binaryExports[key]
1284
- ]);
1285
- const binExportPaths = binPairs.reduce((acc, [binName, binDistPath])=>{
1286
- const exportType = getExportTypeFromFile(binDistPath, pkg.type);
1287
- acc[binName] = {
1288
- [exportType]: binDistPath
1289
- };
1290
- return acc;
1291
- }, {});
1292
- for (const [binName] of binPairs){
1293
- const source = await getSourcePathFromExportPath(cwd, binName, '$binary');
1294
- if (!source) {
1295
- logger.warn(`Cannot find source file for ${binName}`);
1296
- continue;
1297
- }
1298
- const binEntryPath = await resolveSourceFile(cwd, source);
1299
- entries[binName] = {
1300
- source: binEntryPath,
1301
- name: binName,
1302
- export: binExportPaths[binName]
1303
- };
1304
- }
1305
- }
1306
- const collectEntriesPromises = Object.keys(exportPaths).map(async (entryExport)=>{
1307
- const exportCond = exportPaths[entryExport];
1308
- const collectEntryOptions = {
1309
- cwd,
1310
- pkg,
1311
- entries,
1312
- entryPath,
1313
- exportCondRef: exportCond,
1314
- entryExport
1315
- };
1316
- if (entryExport.startsWith('.')) {
1317
- await collectEntry('', collectEntryOptions);
1318
- for (const exportCondType of suffixedExportConventions){
1319
- if (exportCond[exportCondType]) {
1320
- await collectEntry(exportCondType, collectEntryOptions);
1321
- } else if (entryExport === '.' + exportCondType) {
1322
- await collectEntry(entryExport, collectEntryOptions);
1323
- }
1324
- }
1325
- }
1326
- });
1327
- await Promise.all(collectEntriesPromises);
1328
- return entries;
1329
- }
1330
1322
  async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1331
1323
  const { file } = bundleConfig;
1332
1324
  const { pkg, cwd } = pluginContext;
@@ -1334,29 +1326,32 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1334
1326
  const outputExports = getExportsDistFilesOfCondition(pkg, exportCondition, cwd);
1335
1327
  // If there's nothing found, give a default output
1336
1328
  if (outputExports.length === 0 && !pkg.bin) {
1337
- const defaultFormat = isESModulePackage(pkg.type) ? 'esm' : 'cjs';
1329
+ const isEsmPkg = isESModulePackage(pkg.type);
1330
+ const defaultFormat = isEsmPkg ? 'esm' : 'cjs';
1338
1331
  outputExports.push({
1339
1332
  format: defaultFormat,
1340
- file: path.join(cwd, 'dist/index.js')
1333
+ file: path.join(cwd, 'dist/index.js'.replace('/', path__default.default.sep)),
1334
+ exportCondition: 'default'
1341
1335
  });
1342
1336
  }
1343
1337
  let bundleOptions = [];
1344
1338
  // multi outputs with specified format
1345
1339
  // CLI output option is always prioritized
1346
1340
  if (file) {
1347
- var _outputExports_;
1348
- const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format;
1341
+ const fallbackExport = outputExports[0];
1349
1342
  bundleOptions = [
1350
1343
  {
1351
- resolvedFile: path.resolve(cwd, file),
1352
- format: bundleConfig.format || fallbackFormat
1344
+ file: path.resolve(cwd, file),
1345
+ format: bundleConfig.format || fallbackExport.format,
1346
+ exportCondition: fallbackExport.exportCondition
1353
1347
  }
1354
1348
  ];
1355
1349
  } else {
1356
1350
  bundleOptions = outputExports.map((exportDist)=>{
1357
1351
  return {
1358
- resolvedFile: path.resolve(cwd, exportDist.file),
1359
- format: exportDist.format
1352
+ file: path.resolve(cwd, exportDist.file),
1353
+ format: exportDist.format,
1354
+ exportCondition: exportDist.exportCondition
1360
1355
  };
1361
1356
  });
1362
1357
  }
@@ -1368,22 +1363,29 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
1368
1363
  if (exportCondition.export.types) {
1369
1364
  uniqTypes.add(path.resolve(cwd, exportCondition.export.types));
1370
1365
  }
1371
- const typeForExtension = getExportFileTypePath(bundleOption.resolvedFile);
1366
+ const typeForExtension = getExportFileTypePath(bundleOption.file);
1372
1367
  uniqTypes.add(typeForExtension);
1373
1368
  });
1374
1369
  bundleOptions = Array.from(uniqTypes).map((typeFile)=>{
1375
1370
  return {
1376
- resolvedFile: typeFile,
1377
- format: 'esm'
1371
+ file: typeFile,
1372
+ format: 'esm',
1373
+ exportCondition: 'types'
1378
1374
  };
1379
1375
  });
1380
1376
  }
1381
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
+ };
1382
1384
  return await buildOutputConfigs(entry, {
1383
1385
  ...bundleConfig,
1384
- file: bundleOption.resolvedFile,
1386
+ file: bundleOption.file,
1385
1387
  format: bundleOption.format
1386
- }, exportCondition, pluginContext, dts);
1388
+ }, targetExportCondition, pluginContext, dts);
1387
1389
  });
1388
1390
  return Promise.all(outputConfigs);
1389
1391
  }
@@ -1439,7 +1441,7 @@ function createOutputState({ entries }) {
1439
1441
  };
1440
1442
  }
1441
1443
  function isBin(filename) {
1442
- return filename === 'bin' || filename.startsWith('bin/');
1444
+ return filename === BINARY_TAG || filename.startsWith(BINARY_TAG + '/');
1443
1445
  }
1444
1446
  function isTypeFile(filename) {
1445
1447
  return filename.endsWith('.d.ts') || filename.endsWith('.d.mts') || filename.endsWith('.d.cts');
@@ -1447,20 +1449,12 @@ function isTypeFile(filename) {
1447
1449
  function normalizeExportName(exportName) {
1448
1450
  const isBinary = isBin(exportName);
1449
1451
  let result = exportName;
1450
- const isSubpathExport = exportName.includes('/');
1451
- const isSpecialExport = exportName.includes('.');
1452
1452
  if (isBinary) {
1453
- result = (exportName.replace(/bin(\/|$)/, '') || '.') + ' (bin)';
1454
- } else if (isSubpathExport || isSpecialExport) {
1455
- const subExportName = exportName.split('/')[1] || exportName;
1456
- if (subExportName.includes('.') && subExportName !== '.') {
1457
- const [originExportName, specialCondition] = subExportName.split('.');
1458
- result = (isSubpathExport ? relativify(originExportName) : '.') + ' (' + specialCondition + ')';
1459
- } else {
1460
- result = isSubpathExport ? relativify(subExportName) : '.';
1461
- }
1453
+ result = (exportName.replace(new RegExp(`^\\${BINARY_TAG}\\/?`), '') || '.') + ' (bin)';
1462
1454
  } else {
1463
- result = '.';
1455
+ const normalizedExportPath = normalizeExportPath(exportName);
1456
+ const specialConditionName = getSpecialExportTypeFromExportPath(exportName);
1457
+ result = normalizedExportPath + (specialConditionName !== 'default' ? ` (${specialConditionName})` : '');
1464
1458
  }
1465
1459
  return result;
1466
1460
  }
@@ -1511,61 +1505,6 @@ function logOutputState(sizeCollector) {
1511
1505
  });
1512
1506
  }
1513
1507
 
1514
- // TODO: support nested wildcard exportsCondition (e.g. './foo/*')
1515
- const getWildcardExports = (exportsCondition)=>{
1516
- return {
1517
- './*': exportsCondition['./*']
1518
- };
1519
- };
1520
- const isExportable = async (dirent, pathname)=>{
1521
- if (dirent.isDirectory()) {
1522
- const innerDirents = await fsp__default.default.readdir(path__default.default.join(pathname, dirent.name), {
1523
- withFileTypes: true
1524
- });
1525
- return innerDirents.some(({ name })=>name.startsWith('index') && hasAvailableExtension(name));
1526
- }
1527
- return dirent.isFile() && !dirent.name.startsWith('index') && hasAvailableExtension(dirent.name);
1528
- };
1529
- async function getExportables(cwd, excludeKeys) {
1530
- const pathname = path__default.default.resolve(cwd, SRC);
1531
- const dirents = await fsp__default.default.readdir(pathname, {
1532
- withFileTypes: true
1533
- });
1534
- const exportables = await Promise.all(dirents.map(async (dirent)=>await isExportable(dirent, pathname) && !excludeKeys.includes(dirent.name) ? dirent.name : undefined));
1535
- return exportables.filter(nonNullable);
1536
- }
1537
- function mapWildcard(wildcardExports, exportables) {
1538
- return exportables.map((exportable)=>{
1539
- const isFile = exportable.includes('.');
1540
- const filename = isFile ? filePathWithoutExtension(exportable) : exportable;
1541
- return {
1542
- [`./${filename}`]: Object.fromEntries(Object.entries(wildcardExports['./*']).map(([key, value])=>[
1543
- key,
1544
- value.replace(/\*/g, isFile ? filename : `${filename}/index`)
1545
- ]))
1546
- };
1547
- });
1548
- }
1549
- async function resolveWildcardExports(exportsCondition, cwd) {
1550
- if (!exportsCondition || typeof exportsCondition === 'string') return undefined;
1551
- const hasWildcard = !!exportsCondition['./*'];
1552
- if (hasWildcard) {
1553
- 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');
1554
- // './foo' -> ['foo']; './foo/bar' -> ['bar']
1555
- // will contain '*' also but it's not a problem
1556
- const excludeKeys = Object.keys(exportsCondition).map((key)=>key.split('/').pop());
1557
- const exportables = await getExportables(cwd, excludeKeys);
1558
- if (exportables.length > 0) {
1559
- const wildcardExports = getWildcardExports(exportsCondition);
1560
- const resolvedWildcardExports = mapWildcard(wildcardExports, exportables);
1561
- const resolvedExports = Object.assign({}, exportsCondition, ...resolvedWildcardExports);
1562
- delete resolvedExports['./*'];
1563
- return resolvedExports;
1564
- }
1565
- }
1566
- return undefined;
1567
- }
1568
-
1569
1508
  function assignDefault(options, name, defaultValue) {
1570
1509
  if (!(name in options) || options[name] == null) {
1571
1510
  options[name] = defaultValue;
@@ -1581,12 +1520,11 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1581
1520
  assignDefault(options, 'minify', false);
1582
1521
  assignDefault(options, 'target', 'es2015');
1583
1522
  const pkg = await getPackageMeta(cwd);
1584
- const resolvedWildcardExports = await resolveWildcardExports(pkg.exports, cwd);
1585
- const packageType = getPackageType(pkg);
1586
- const exportPaths = getExportPaths(pkg, resolvedWildcardExports);
1587
- const isMultiEntries = hasMultiEntryExport(exportPaths) // exportPathsLength > 1
1588
- ;
1523
+ const parsedExportsInfo = parseExports(pkg);
1524
+ const isMultiEntries = hasMultiEntryExport(parsedExportsInfo);
1589
1525
  const hasBin = Boolean(pkg.bin);
1526
+ // Original input file path, client path might change later
1527
+ const inputFile = cliEntryPath;
1590
1528
  const isFromCli = Boolean(cliEntryPath);
1591
1529
  let tsConfig = resolveTsConfig(cwd);
1592
1530
  let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
@@ -1601,21 +1539,27 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1601
1539
  cliEntryPath = cliEntryPath || await getSourcePathFromExportPath(cwd, '.', 'default') || '';
1602
1540
  }
1603
1541
  // Handle CLI input
1604
- if (cliEntryPath) {
1605
- let mainEntryPath;
1606
- let typesEntryPath;
1542
+ let mainExportPath;
1543
+ let typesEntryPath;
1544
+ if (isFromCli) {
1607
1545
  // with -o option
1608
1546
  if (options.file) {
1609
- mainEntryPath = options.file;
1547
+ mainExportPath = options.file;
1610
1548
  }
1611
- if (mainEntryPath) {
1549
+ if (mainExportPath) {
1612
1550
  if (options.dts) {
1613
- typesEntryPath = getExportFileTypePath(mainEntryPath);
1551
+ typesEntryPath = getExportFileTypePath(mainExportPath);
1614
1552
  }
1615
- exportPaths['.'] = constructDefaultExportCondition({
1616
- main: mainEntryPath,
1617
- types: typesEntryPath
1618
- }, packageType);
1553
+ parsedExportsInfo.set('.', [
1554
+ [
1555
+ mainExportPath,
1556
+ 'default'
1557
+ ],
1558
+ Boolean(typesEntryPath) && [
1559
+ typesEntryPath,
1560
+ 'types'
1561
+ ]
1562
+ ].filter(Boolean));
1619
1563
  }
1620
1564
  }
1621
1565
  const bundleOrWatch = async (rollupConfig)=>{
@@ -1645,7 +1589,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1645
1589
  }
1646
1590
  }
1647
1591
  }
1648
- const entries = await collectEntries(pkg, cliEntryPath, exportPaths, cwd);
1592
+ const entries = await collectEntriesFromParsedExports(cwd, parsedExportsInfo, inputFile);
1649
1593
  const hasTypeScriptFiles = Object.values(entries).some((entry)=>isTypescriptFile(entry.source));
1650
1594
  if (hasTypeScriptFiles && !hasTsConfig) {
1651
1595
  const tsConfigPath = path.resolve(cwd, 'tsconfig.json');
@@ -1656,11 +1600,13 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1656
1600
  const sizeCollector = createOutputState({
1657
1601
  entries
1658
1602
  });
1659
- const entriesAlias = getReversedAlias(entries);
1603
+ const entriesAlias = getReversedAlias({
1604
+ entries,
1605
+ name: pkg.name
1606
+ });
1660
1607
  const buildContext = {
1661
1608
  entries,
1662
1609
  pkg,
1663
- exportPaths,
1664
1610
  cwd,
1665
1611
  tsOptions: defaultTsOptions,
1666
1612
  useTypeScript: hasTsConfig,
@@ -1672,7 +1618,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1672
1618
  };
1673
1619
  const buildConfigs = await buildEntryConfig(options, buildContext, false);
1674
1620
  const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
1675
- 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)) : [];
1676
1622
  const totalJobs = assetsJobs.concat(typesJobs);
1677
1623
  const result = await Promise.all(totalJobs);
1678
1624
  if (result.length === 0) {