bunchee 6.0.4 → 6.1.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.
- package/README.md +1 -1
- package/dist/bin/cli.js +46 -9
- package/dist/index.js +50 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -290,7 +290,7 @@ If you're using `"use client"` or `"use server"` in a file that used as a depend
|
|
|
290
290
|
|
|
291
291
|
### Shared Modules
|
|
292
292
|
|
|
293
|
-
In some cases, you may need to share code across multiple bundles without promoting them to separate entries or exports. These modules should be bundled into shared chunks that can be reused by various bundles. By convention, files or directories prefixed with an underscore (`_<name>.<ext>` or `_<name
|
|
293
|
+
In some cases, you may need to share code across multiple bundles without promoting them to separate entries or exports. These modules should be bundled into shared chunks that can be reused by various bundles. By convention, files or directories **prefixed with an underscore** (`_<name>.<ext>` or `_<name>/**`) are treated as **shared modules**. They're private and not exposed publicly as entry points or exports. Testing, mocking related files are ignored. e.g. `_foo/a.test.ts` will not be treated as shared module.
|
|
294
294
|
|
|
295
295
|
<details>
|
|
296
296
|
<summary>Shared Utils Example</summary>
|
package/dist/bin/cli.js
CHANGED
|
@@ -74,6 +74,8 @@ const DEFAULT_TS_CONFIG = {
|
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
76
|
const BINARY_TAG = '$binary';
|
|
77
|
+
const PRIVATE_GLOB_PATTERN = '**/_*/**';
|
|
78
|
+
const TESTS_GLOB_PATTERN = '**/{__tests__/**,__mocks__/**,*.{test,spec}.*}';
|
|
77
79
|
|
|
78
80
|
function getDefaultExportFromCjs (x) {
|
|
79
81
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -158,6 +160,36 @@ function posixRelativify(path) {
|
|
|
158
160
|
return path.startsWith('.') ? path : `./${path}`;
|
|
159
161
|
}
|
|
160
162
|
|
|
163
|
+
// Example: ./src/util/foo.development.ts -> foo.development
|
|
164
|
+
// Example: ./src/util/foo.react-server.ts -> foo.react-server
|
|
165
|
+
const baseNameWithoutExtension = (filePath)=>{
|
|
166
|
+
return path__default.default.basename(filePath, path__default.default.extname(filePath));
|
|
167
|
+
};
|
|
168
|
+
function validateEntryFiles(entryFiles) {
|
|
169
|
+
const fileBasePaths = new Set();
|
|
170
|
+
const duplicatePaths = new Set();
|
|
171
|
+
for (const filePath of entryFiles){
|
|
172
|
+
// Check if there are multiple files with the same base name
|
|
173
|
+
const filePathWithoutExt = filePath.slice(0, -path__default.default.extname(filePath).length).replace(/\\/g, '/');
|
|
174
|
+
const segments = filePathWithoutExt.split('/');
|
|
175
|
+
const lastSegment = segments.pop() || '';
|
|
176
|
+
if (lastSegment !== 'index' && lastSegment !== '') {
|
|
177
|
+
segments.push(lastSegment);
|
|
178
|
+
}
|
|
179
|
+
const fileBasePath = segments.join('/');
|
|
180
|
+
if (fileBasePaths.has(fileBasePath)) {
|
|
181
|
+
duplicatePaths.add(// Add a dot if the base name is empty, 'foo' -> './foo', '' -> '.'
|
|
182
|
+
'./' + filePath.replace(/\\/g, '/'));
|
|
183
|
+
}
|
|
184
|
+
fileBasePaths.add(fileBasePath);
|
|
185
|
+
}
|
|
186
|
+
if (duplicatePaths.size > 0) {
|
|
187
|
+
throw new Error(`Conflicted entry files found for entries: ${[
|
|
188
|
+
...duplicatePaths
|
|
189
|
+
].join(', ')}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
161
193
|
function exit(err) {
|
|
162
194
|
logger.error(err);
|
|
163
195
|
process.exit(1);
|
|
@@ -188,8 +220,6 @@ const getMainFieldExportType = (pkg)=>{
|
|
|
188
220
|
const mainExportType = isEsmPkg && pkg.main ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
|
|
189
221
|
return mainExportType;
|
|
190
222
|
};
|
|
191
|
-
// TODO: add unit test
|
|
192
|
-
const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
|
|
193
223
|
const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
|
|
194
224
|
function joinRelativePath(...segments) {
|
|
195
225
|
let result = path__default.default.join(...segments);
|
|
@@ -612,7 +642,7 @@ function lint$1(pkg) {
|
|
|
612
642
|
}
|
|
613
643
|
}
|
|
614
644
|
|
|
615
|
-
var version = "6.
|
|
645
|
+
var version = "6.1.1";
|
|
616
646
|
|
|
617
647
|
async function writeDefaultTsconfig(tsConfigPath) {
|
|
618
648
|
await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
|
|
@@ -678,7 +708,7 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
|
|
|
678
708
|
;
|
|
679
709
|
const dirPath = path__default.default.join(sourceFolderPath, dirName);
|
|
680
710
|
// Match <name>{,/index}.{<ext>,<runtime>.<ext>}
|
|
681
|
-
const
|
|
711
|
+
const entryFilesPatterns = [
|
|
682
712
|
`${baseName}.{${[
|
|
683
713
|
...availableExtensions
|
|
684
714
|
].join(',')}}`,
|
|
@@ -696,12 +726,13 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
|
|
|
696
726
|
...availableExtensions
|
|
697
727
|
].join(',')}}`
|
|
698
728
|
];
|
|
699
|
-
const
|
|
729
|
+
const entryFiles = await glob.glob(entryFilesPatterns, {
|
|
700
730
|
cwd: dirPath,
|
|
701
731
|
nodir: true,
|
|
702
|
-
ignore:
|
|
732
|
+
ignore: PRIVATE_GLOB_PATTERN
|
|
703
733
|
});
|
|
704
|
-
|
|
734
|
+
validateEntryFiles(entryFiles);
|
|
735
|
+
for (const file of entryFiles){
|
|
705
736
|
const ext = path__default.default.extname(file).slice(1);
|
|
706
737
|
if (!availableExtensions.has(ext) || isTestFile(file)) continue;
|
|
707
738
|
const sourceFileAbsolutePath = path__default.default.join(dirPath, file);
|
|
@@ -746,12 +777,18 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
746
777
|
const binMatches = await glob.glob(binPattern, {
|
|
747
778
|
cwd: sourceFolderPath,
|
|
748
779
|
nodir: true,
|
|
749
|
-
ignore:
|
|
780
|
+
ignore: [
|
|
781
|
+
PRIVATE_GLOB_PATTERN,
|
|
782
|
+
TESTS_GLOB_PATTERN
|
|
783
|
+
]
|
|
750
784
|
});
|
|
751
785
|
const srcMatches = await glob.glob(srcPattern, {
|
|
752
786
|
cwd: sourceFolderPath,
|
|
753
787
|
nodir: true,
|
|
754
|
-
ignore:
|
|
788
|
+
ignore: [
|
|
789
|
+
PRIVATE_GLOB_PATTERN,
|
|
790
|
+
TESTS_GLOB_PATTERN
|
|
791
|
+
]
|
|
755
792
|
});
|
|
756
793
|
for (const file of binMatches){
|
|
757
794
|
// convert relative path to export path
|
package/dist/index.js
CHANGED
|
@@ -241,11 +241,43 @@ const DEFAULT_TS_CONFIG = {
|
|
|
241
241
|
}
|
|
242
242
|
};
|
|
243
243
|
const BINARY_TAG = '$binary';
|
|
244
|
+
const PRIVATE_GLOB_PATTERN = '**/_*/**';
|
|
245
|
+
const TESTS_GLOB_PATTERN = '**/{__tests__/**,__mocks__/**,*.{test,spec}.*}';
|
|
244
246
|
|
|
245
247
|
function posixRelativify(path) {
|
|
246
248
|
return path.startsWith('.') ? path : `./${path}`;
|
|
247
249
|
}
|
|
248
250
|
|
|
251
|
+
// Example: ./src/util/foo.development.ts -> foo.development
|
|
252
|
+
// Example: ./src/util/foo.react-server.ts -> foo.react-server
|
|
253
|
+
const baseNameWithoutExtension = (filePath)=>{
|
|
254
|
+
return path__default.default.basename(filePath, path__default.default.extname(filePath));
|
|
255
|
+
};
|
|
256
|
+
function validateEntryFiles(entryFiles) {
|
|
257
|
+
const fileBasePaths = new Set();
|
|
258
|
+
const duplicatePaths = new Set();
|
|
259
|
+
for (const filePath of entryFiles){
|
|
260
|
+
// Check if there are multiple files with the same base name
|
|
261
|
+
const filePathWithoutExt = filePath.slice(0, -path__default.default.extname(filePath).length).replace(/\\/g, '/');
|
|
262
|
+
const segments = filePathWithoutExt.split('/');
|
|
263
|
+
const lastSegment = segments.pop() || '';
|
|
264
|
+
if (lastSegment !== 'index' && lastSegment !== '') {
|
|
265
|
+
segments.push(lastSegment);
|
|
266
|
+
}
|
|
267
|
+
const fileBasePath = segments.join('/');
|
|
268
|
+
if (fileBasePaths.has(fileBasePath)) {
|
|
269
|
+
duplicatePaths.add(// Add a dot if the base name is empty, 'foo' -> './foo', '' -> '.'
|
|
270
|
+
'./' + filePath.replace(/\\/g, '/'));
|
|
271
|
+
}
|
|
272
|
+
fileBasePaths.add(fileBasePath);
|
|
273
|
+
}
|
|
274
|
+
if (duplicatePaths.size > 0) {
|
|
275
|
+
throw new Error(`Conflicted entry files found for entries: ${[
|
|
276
|
+
...duplicatePaths
|
|
277
|
+
].join(', ')}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
249
281
|
function exit(err) {
|
|
250
282
|
logger.error(err);
|
|
251
283
|
process.exit(1);
|
|
@@ -325,8 +357,6 @@ const getMainFieldExportType = (pkg)=>{
|
|
|
325
357
|
const mainExportType = isEsmPkg && pkg.main ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
|
|
326
358
|
return mainExportType;
|
|
327
359
|
};
|
|
328
|
-
// TODO: add unit test
|
|
329
|
-
const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
|
|
330
360
|
const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
|
|
331
361
|
function joinRelativePath(...segments) {
|
|
332
362
|
let result = path__default.default.join(...segments);
|
|
@@ -752,7 +782,7 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
|
|
|
752
782
|
;
|
|
753
783
|
const dirPath = path__default.default.join(sourceFolderPath, dirName);
|
|
754
784
|
// Match <name>{,/index}.{<ext>,<runtime>.<ext>}
|
|
755
|
-
const
|
|
785
|
+
const entryFilesPatterns = [
|
|
756
786
|
`${baseName}.{${[
|
|
757
787
|
...availableExtensions
|
|
758
788
|
].join(',')}}`,
|
|
@@ -770,12 +800,13 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
|
|
|
770
800
|
...availableExtensions
|
|
771
801
|
].join(',')}}`
|
|
772
802
|
];
|
|
773
|
-
const
|
|
803
|
+
const entryFiles = await glob.glob(entryFilesPatterns, {
|
|
774
804
|
cwd: dirPath,
|
|
775
805
|
nodir: true,
|
|
776
|
-
ignore:
|
|
806
|
+
ignore: PRIVATE_GLOB_PATTERN
|
|
777
807
|
});
|
|
778
|
-
|
|
808
|
+
validateEntryFiles(entryFiles);
|
|
809
|
+
for (const file of entryFiles){
|
|
779
810
|
const ext = path__default.default.extname(file).slice(1);
|
|
780
811
|
if (!availableExtensions.has(ext) || isTestFile(file)) continue;
|
|
781
812
|
const sourceFileAbsolutePath = path__default.default.join(dirPath, file);
|
|
@@ -826,21 +857,20 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
|
|
|
826
857
|
}
|
|
827
858
|
}
|
|
828
859
|
// 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.
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
].join(',')}}`
|
|
840
|
-
];
|
|
860
|
+
// Leading underscore: e.g. _utils.ts, _utils/index.ts
|
|
861
|
+
// Segment contains leading underscore: e.g. a/_b/_c.ts, a/b/_c/index.ts
|
|
862
|
+
// Contains special suffix: e.g. _utils.development.ts, _utils/index.development.js
|
|
863
|
+
const suffixPattern = [
|
|
864
|
+
...runtimeExportConventions
|
|
865
|
+
].join(',');
|
|
866
|
+
const extPattern = [
|
|
867
|
+
...availableExtensions
|
|
868
|
+
].join(',');
|
|
869
|
+
const privatePattern = `**/_*{,/*}{,{.${suffixPattern}}}.{${extPattern}}`;
|
|
841
870
|
const privateFiles = await glob.glob(privatePattern, {
|
|
842
871
|
cwd: sourceFolderPath,
|
|
843
|
-
nodir: true
|
|
872
|
+
nodir: true,
|
|
873
|
+
ignore: TESTS_GLOB_PATTERN
|
|
844
874
|
});
|
|
845
875
|
for (const file of privateFiles){
|
|
846
876
|
const sourceFileAbsolutePath = path__default.default.join(sourceFolderPath, file);
|
|
@@ -855,6 +885,7 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
|
|
|
855
885
|
const condPart = isSpecialExport ? specialExportType + '.' : '';
|
|
856
886
|
// Map private shared files to the dist directory
|
|
857
887
|
// e.g. ./_utils.ts -> ./dist/_utils.js
|
|
888
|
+
// TODO: improve the logic to only generate the required files, not all possible files
|
|
858
889
|
const privateExportInfo = [
|
|
859
890
|
[
|
|
860
891
|
posixRelativify(path.posix.join('./dist', exportPath + (isEsmPkg ? '.js' : '.mjs'))),
|