bunchee 6.0.4 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/cli.js CHANGED
@@ -74,6 +74,7 @@ const DEFAULT_TS_CONFIG = {
74
74
  }
75
75
  };
76
76
  const BINARY_TAG = '$binary';
77
+ const PRIVATE_GLOB_PATTERN = '**/_*/**';
77
78
 
78
79
  function getDefaultExportFromCjs (x) {
79
80
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -158,6 +159,36 @@ function posixRelativify(path) {
158
159
  return path.startsWith('.') ? path : `./${path}`;
159
160
  }
160
161
 
162
+ // Example: ./src/util/foo.development.ts -> foo.development
163
+ // Example: ./src/util/foo.react-server.ts -> foo.react-server
164
+ const baseNameWithoutExtension = (filePath)=>{
165
+ return path__default.default.basename(filePath, path__default.default.extname(filePath));
166
+ };
167
+ function validateEntryFiles(entryFiles) {
168
+ const fileBasePaths = new Set();
169
+ const duplicatePaths = new Set();
170
+ for (const filePath of entryFiles){
171
+ // Check if there are multiple files with the same base name
172
+ const filePathWithoutExt = filePath.slice(0, -path__default.default.extname(filePath).length).replace(/\\/g, '/');
173
+ const segments = filePathWithoutExt.split('/');
174
+ const lastSegment = segments.pop() || '';
175
+ if (lastSegment !== 'index' && lastSegment !== '') {
176
+ segments.push(lastSegment);
177
+ }
178
+ const fileBasePath = segments.join('/');
179
+ if (fileBasePaths.has(fileBasePath)) {
180
+ duplicatePaths.add(// Add a dot if the base name is empty, 'foo' -> './foo', '' -> '.'
181
+ './' + filePath.replace(/\\/g, '/'));
182
+ }
183
+ fileBasePaths.add(fileBasePath);
184
+ }
185
+ if (duplicatePaths.size > 0) {
186
+ throw new Error(`Conflicted entry files found for entries: ${[
187
+ ...duplicatePaths
188
+ ].join(', ')}`);
189
+ }
190
+ }
191
+
161
192
  function exit(err) {
162
193
  logger.error(err);
163
194
  process.exit(1);
@@ -188,8 +219,6 @@ const getMainFieldExportType = (pkg)=>{
188
219
  const mainExportType = isEsmPkg && pkg.main ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
189
220
  return mainExportType;
190
221
  };
191
- // TODO: add unit test
192
- const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
193
222
  const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
194
223
  function joinRelativePath(...segments) {
195
224
  let result = path__default.default.join(...segments);
@@ -612,7 +641,7 @@ function lint$1(pkg) {
612
641
  }
613
642
  }
614
643
 
615
- var version = "6.0.4";
644
+ var version = "6.1.0";
616
645
 
617
646
  async function writeDefaultTsconfig(tsConfigPath) {
618
647
  await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
@@ -678,7 +707,7 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
678
707
  ;
679
708
  const dirPath = path__default.default.join(sourceFolderPath, dirName);
680
709
  // Match <name>{,/index}.{<ext>,<runtime>.<ext>}
681
- const globalPatterns = [
710
+ const entryFilesPatterns = [
682
711
  `${baseName}.{${[
683
712
  ...availableExtensions
684
713
  ].join(',')}}`,
@@ -696,12 +725,13 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
696
725
  ...availableExtensions
697
726
  ].join(',')}}`
698
727
  ];
699
- const files = await glob.glob(globalPatterns, {
728
+ const entryFiles = await glob.glob(entryFilesPatterns, {
700
729
  cwd: dirPath,
701
730
  nodir: true,
702
- ignore: '**/_*'
731
+ ignore: PRIVATE_GLOB_PATTERN
703
732
  });
704
- for (const file of files){
733
+ validateEntryFiles(entryFiles);
734
+ for (const file of entryFiles){
705
735
  const ext = path__default.default.extname(file).slice(1);
706
736
  if (!availableExtensions.has(ext) || isTestFile(file)) continue;
707
737
  const sourceFileAbsolutePath = path__default.default.join(dirPath, file);
@@ -746,12 +776,12 @@ async function collectSourceEntries(sourceFolderPath) {
746
776
  const binMatches = await glob.glob(binPattern, {
747
777
  cwd: sourceFolderPath,
748
778
  nodir: true,
749
- ignore: '**/_*'
779
+ ignore: PRIVATE_GLOB_PATTERN
750
780
  });
751
781
  const srcMatches = await glob.glob(srcPattern, {
752
782
  cwd: sourceFolderPath,
753
783
  nodir: true,
754
- ignore: '**/_*'
784
+ ignore: PRIVATE_GLOB_PATTERN
755
785
  });
756
786
  for (const file of binMatches){
757
787
  // convert relative path to export path
package/dist/index.js CHANGED
@@ -241,11 +241,42 @@ const DEFAULT_TS_CONFIG = {
241
241
  }
242
242
  };
243
243
  const BINARY_TAG = '$binary';
244
+ const PRIVATE_GLOB_PATTERN = '**/_*/**';
244
245
 
245
246
  function posixRelativify(path) {
246
247
  return path.startsWith('.') ? path : `./${path}`;
247
248
  }
248
249
 
250
+ // Example: ./src/util/foo.development.ts -> foo.development
251
+ // Example: ./src/util/foo.react-server.ts -> foo.react-server
252
+ const baseNameWithoutExtension = (filePath)=>{
253
+ return path__default.default.basename(filePath, path__default.default.extname(filePath));
254
+ };
255
+ function validateEntryFiles(entryFiles) {
256
+ const fileBasePaths = new Set();
257
+ const duplicatePaths = new Set();
258
+ for (const filePath of entryFiles){
259
+ // Check if there are multiple files with the same base name
260
+ const filePathWithoutExt = filePath.slice(0, -path__default.default.extname(filePath).length).replace(/\\/g, '/');
261
+ const segments = filePathWithoutExt.split('/');
262
+ const lastSegment = segments.pop() || '';
263
+ if (lastSegment !== 'index' && lastSegment !== '') {
264
+ segments.push(lastSegment);
265
+ }
266
+ const fileBasePath = segments.join('/');
267
+ if (fileBasePaths.has(fileBasePath)) {
268
+ duplicatePaths.add(// Add a dot if the base name is empty, 'foo' -> './foo', '' -> '.'
269
+ './' + filePath.replace(/\\/g, '/'));
270
+ }
271
+ fileBasePaths.add(fileBasePath);
272
+ }
273
+ if (duplicatePaths.size > 0) {
274
+ throw new Error(`Conflicted entry files found for entries: ${[
275
+ ...duplicatePaths
276
+ ].join(', ')}`);
277
+ }
278
+ }
279
+
249
280
  function exit(err) {
250
281
  logger.error(err);
251
282
  process.exit(1);
@@ -325,8 +356,6 @@ const getMainFieldExportType = (pkg)=>{
325
356
  const mainExportType = isEsmPkg && pkg.main ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
326
357
  return mainExportType;
327
358
  };
328
- // TODO: add unit test
329
- const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
330
359
  const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
331
360
  function joinRelativePath(...segments) {
332
361
  let result = path__default.default.join(...segments);
@@ -752,7 +781,7 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
752
781
  ;
753
782
  const dirPath = path__default.default.join(sourceFolderPath, dirName);
754
783
  // Match <name>{,/index}.{<ext>,<runtime>.<ext>}
755
- const globalPatterns = [
784
+ const entryFilesPatterns = [
756
785
  `${baseName}.{${[
757
786
  ...availableExtensions
758
787
  ].join(',')}}`,
@@ -770,12 +799,13 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
770
799
  ...availableExtensions
771
800
  ].join(',')}}`
772
801
  ];
773
- const files = await glob.glob(globalPatterns, {
802
+ const entryFiles = await glob.glob(entryFilesPatterns, {
774
803
  cwd: dirPath,
775
804
  nodir: true,
776
- ignore: '**/_*'
805
+ ignore: PRIVATE_GLOB_PATTERN
777
806
  });
778
- for (const file of files){
807
+ validateEntryFiles(entryFiles);
808
+ for (const file of entryFiles){
779
809
  const ext = path__default.default.extname(file).slice(1);
780
810
  if (!availableExtensions.has(ext) || isTestFile(file)) continue;
781
811
  const sourceFileAbsolutePath = path__default.default.join(dirPath, file);
@@ -826,18 +856,16 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
826
856
  }
827
857
  }
828
858
  // Search private shared module files which are not in the parsedExportsInfo, but start with _.
829
- // e.g. _utils.ts, _utils/index.ts
830
- // e.g. _utils.development.ts, _utils/index.development.js
831
- const privatePattern = [
832
- `**/_*{,/index}.{${[
833
- ...availableExtensions
834
- ].join(',')}}`,
835
- `**/_*{,/index}.{${[
836
- ...runtimeExportConventions
837
- ].join(',')}}.{${[
838
- ...availableExtensions
839
- ].join(',')}}`
840
- ];
859
+ // Leading underscore: e.g. _utils.ts, _utils/index.ts
860
+ // Segment contains leading underscore: e.g. a/_b/_c.ts, a/b/_c/index.ts
861
+ // Contains special suffix: e.g. _utils.development.ts, _utils/index.development.js
862
+ const suffixPattern = [
863
+ ...runtimeExportConventions
864
+ ].join(',');
865
+ const extPattern = [
866
+ ...availableExtensions
867
+ ].join(',');
868
+ const privatePattern = `**/_*{,/*}{,{.${suffixPattern}}}.{${extPattern}}`;
841
869
  const privateFiles = await glob.glob(privatePattern, {
842
870
  cwd: sourceFolderPath,
843
871
  nodir: true
@@ -855,6 +883,7 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
855
883
  const condPart = isSpecialExport ? specialExportType + '.' : '';
856
884
  // Map private shared files to the dist directory
857
885
  // e.g. ./_utils.ts -> ./dist/_utils.js
886
+ // TODO: improve the logic to only generate the required files, not all possible files
858
887
  const privateExportInfo = [
859
888
  [
860
889
  posixRelativify(path.posix.join('./dist', exportPath + (isEsmPkg ? '.js' : '.mjs'))),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "6.0.4",
3
+ "version": "6.1.0",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",