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.
- package/README.md +0 -55
- package/dist/bin/cli.js +320 -317
- package/dist/index.js +442 -496
- 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
|
|
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 (
|
|
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
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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(
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
const
|
|
662
|
-
|
|
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
|
-
|
|
723
|
-
|
|
724
|
-
|
|
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
|
-
*
|
|
641
|
+
* parseExports - parse package.exports field and other fields like main,module to a map
|
|
732
642
|
*
|
|
733
|
-
*
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
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
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
890
|
-
|
|
891
|
-
|
|
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
|
-
|
|
911
|
-
|
|
912
|
-
|
|
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 [
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
1348
|
-
const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format;
|
|
1341
|
+
const fallbackExport = outputExports[0];
|
|
1349
1342
|
bundleOptions = [
|
|
1350
1343
|
{
|
|
1351
|
-
|
|
1352
|
-
format: bundleConfig.format ||
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
1386
|
+
file: bundleOption.file,
|
|
1385
1387
|
format: bundleOption.format
|
|
1386
|
-
},
|
|
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 ===
|
|
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(
|
|
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
|
-
|
|
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
|
|
1585
|
-
const
|
|
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
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1542
|
+
let mainExportPath;
|
|
1543
|
+
let typesEntryPath;
|
|
1544
|
+
if (isFromCli) {
|
|
1607
1545
|
// with -o option
|
|
1608
1546
|
if (options.file) {
|
|
1609
|
-
|
|
1547
|
+
mainExportPath = options.file;
|
|
1610
1548
|
}
|
|
1611
|
-
if (
|
|
1549
|
+
if (mainExportPath) {
|
|
1612
1550
|
if (options.dts) {
|
|
1613
|
-
typesEntryPath = getExportFileTypePath(
|
|
1551
|
+
typesEntryPath = getExportFileTypePath(mainExportPath);
|
|
1614
1552
|
}
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
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
|
|
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(
|
|
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) {
|