bunchee 4.4.8 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -55
- package/dist/bin/cli.js +320 -317
- package/dist/index.js +439 -494
- 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,17 +801,243 @@ function getDefinedInlineVariables(envs, parsedExportCondition) {
|
|
|
921
801
|
}
|
|
922
802
|
return envVars;
|
|
923
803
|
}
|
|
804
|
+
|
|
805
|
+
// shared.ts -> ./shared
|
|
806
|
+
// shared.<export condition>.ts -> ./shared
|
|
807
|
+
// index.ts -> ./index
|
|
808
|
+
// index.development.ts -> ./index.development
|
|
809
|
+
function sourceFilenameToExportPath(filename) {
|
|
810
|
+
const baseName = baseNameWithoutExtension(filename);
|
|
811
|
+
let exportPath = baseName;
|
|
812
|
+
return relativify(exportPath);
|
|
813
|
+
}
|
|
814
|
+
async function collectEntriesFromParsedExports(cwd, parsedExportsInfo, sourceFile) {
|
|
815
|
+
const entries = {};
|
|
816
|
+
if (sourceFile) {
|
|
817
|
+
const defaultExport = parsedExportsInfo.get('.')[0];
|
|
818
|
+
entries['.'] = {
|
|
819
|
+
source: sourceFile,
|
|
820
|
+
name: '.',
|
|
821
|
+
export: {
|
|
822
|
+
default: defaultExport[0]
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
// Find source files
|
|
827
|
+
const { bins, exportsEntries } = await collectSourceEntries(path.join(cwd, SRC));
|
|
828
|
+
// A mapping between each export path and its related special export conditions,
|
|
829
|
+
// excluding the 'default' export condition.
|
|
830
|
+
// { '.' => Set('development') }
|
|
831
|
+
const pathSpecialConditionsMap = {};
|
|
832
|
+
for (const [exportPath] of exportsEntries){
|
|
833
|
+
const normalizedExportPath = normalizeExportPath(exportPath);
|
|
834
|
+
if (!pathSpecialConditionsMap[normalizedExportPath]) {
|
|
835
|
+
pathSpecialConditionsMap[normalizedExportPath] = new Set();
|
|
836
|
+
}
|
|
837
|
+
const exportType = getExportTypeFromExportPath(exportPath);
|
|
838
|
+
if (exportType !== 'default') {
|
|
839
|
+
pathSpecialConditionsMap[normalizedExportPath].add(exportType);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
// Traverse source files and try to match the entries
|
|
843
|
+
// Find exports from parsed exports info
|
|
844
|
+
// entryExportPath can be: '.', './index.development', './shared.edge-light', etc.
|
|
845
|
+
for (const [entryExportPath, sourceFilesMap] of exportsEntries){
|
|
846
|
+
const normalizedExportPath = normalizeExportPath(entryExportPath);
|
|
847
|
+
const entryExportPathType = getExportTypeFromExportPath(entryExportPath);
|
|
848
|
+
const outputExports = parsedExportsInfo.get(normalizedExportPath);
|
|
849
|
+
if (!outputExports) {
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
for (const [outputPath, composedExportType] of outputExports){
|
|
853
|
+
const matchedExportType = getSpecialExportTypeFromExportPath(composedExportType);
|
|
854
|
+
// export type can be: default, development, react-server, etc.
|
|
855
|
+
const sourceFile = sourceFilesMap[matchedExportType] || sourceFilesMap.default;
|
|
856
|
+
if (!sourceFile) {
|
|
857
|
+
continue;
|
|
858
|
+
}
|
|
859
|
+
if (!entries[entryExportPath]) {
|
|
860
|
+
entries[entryExportPath] = {
|
|
861
|
+
source: sourceFile,
|
|
862
|
+
name: normalizedExportPath,
|
|
863
|
+
export: {}
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
const exportMap = entries[entryExportPath].export;
|
|
867
|
+
if (entryExportPathType === 'default' && matchedExportType !== 'default' && pathSpecialConditionsMap[normalizedExportPath].size > 0) {
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
exportMap[composedExportType] = outputPath;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
// Handling binaries
|
|
874
|
+
for (const [exportPath, sourceFile] of bins){
|
|
875
|
+
const normalizedExportPath = normalizeExportPath(exportPath);
|
|
876
|
+
const outputExports = parsedExportsInfo.get(normalizedExportPath);
|
|
877
|
+
if (!outputExports) {
|
|
878
|
+
continue;
|
|
879
|
+
}
|
|
880
|
+
for (const [outputPath, exportType] of outputExports){
|
|
881
|
+
entries[exportPath] = {
|
|
882
|
+
source: sourceFile,
|
|
883
|
+
name: exportPath,
|
|
884
|
+
export: {
|
|
885
|
+
[exportType]: outputPath
|
|
886
|
+
}
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
return entries;
|
|
891
|
+
}
|
|
892
|
+
// ./index -> import|require|default
|
|
893
|
+
// ./index.development -> development
|
|
894
|
+
// ./index.react-server -> react-server
|
|
895
|
+
function getExportTypeFromExportPath(exportPath) {
|
|
896
|
+
// Skip the first two segments: `.` and `index`
|
|
897
|
+
const exportTypes = exportPath.split('.').slice(2);
|
|
898
|
+
return getExportTypeFromExportTypes(exportTypes);
|
|
899
|
+
}
|
|
900
|
+
function getSpecialExportTypeFromExportPath(composedExportType) {
|
|
901
|
+
const exportTypes = composedExportType.split('.');
|
|
902
|
+
for (const exportType of exportTypes){
|
|
903
|
+
if (specialExportConventions.has(exportType)) {
|
|
904
|
+
return exportType;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return 'default';
|
|
908
|
+
}
|
|
909
|
+
function getExportTypeFromExportTypes(types) {
|
|
910
|
+
let exportType = 'default';
|
|
911
|
+
new Set(types).forEach((value)=>{
|
|
912
|
+
if (specialExportConventions.has(value)) {
|
|
913
|
+
exportType = value;
|
|
914
|
+
} else if (value === 'import' || value === 'require') {
|
|
915
|
+
exportType = value;
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
return exportType;
|
|
919
|
+
}
|
|
920
|
+
// ./index -> .
|
|
921
|
+
// ./index.development -> .
|
|
922
|
+
// ./index.react-server -> .
|
|
923
|
+
// ./shared -> ./shared
|
|
924
|
+
// ./shared.development -> ./shared
|
|
925
|
+
// $binary -> $binary
|
|
926
|
+
// $binary/index -> $binary
|
|
927
|
+
// $binary/foo -> $binary/foo
|
|
928
|
+
function normalizeExportPath(exportPath) {
|
|
929
|
+
if (exportPath.startsWith(BINARY_TAG)) {
|
|
930
|
+
if (exportPath === `${BINARY_TAG}/index`) {
|
|
931
|
+
exportPath = BINARY_TAG;
|
|
932
|
+
}
|
|
933
|
+
return exportPath;
|
|
934
|
+
}
|
|
935
|
+
const baseName = exportPath.split('.').slice(0, 2).join('.');
|
|
936
|
+
if (baseName === './index') {
|
|
937
|
+
return '.';
|
|
938
|
+
}
|
|
939
|
+
return baseName;
|
|
940
|
+
}
|
|
941
|
+
async function collectSourceEntries(sourceFolderPath) {
|
|
942
|
+
const bins = new Map();
|
|
943
|
+
const exportsEntries = new Map();
|
|
944
|
+
if (!fs__default.default.existsSync(sourceFolderPath)) {
|
|
945
|
+
return {
|
|
946
|
+
bins,
|
|
947
|
+
exportsEntries
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
const entryFileDirentList = await fsp__default.default.readdir(sourceFolderPath, {
|
|
951
|
+
withFileTypes: true
|
|
952
|
+
});
|
|
953
|
+
for (const dirent of entryFileDirentList){
|
|
954
|
+
if (dirent.isDirectory()) {
|
|
955
|
+
if (dirent.name === 'bin') {
|
|
956
|
+
const binDirentList = await fsp__default.default.readdir(path__default.default.join(sourceFolderPath, dirent.name), {
|
|
957
|
+
withFileTypes: true
|
|
958
|
+
});
|
|
959
|
+
for (const binDirent of binDirentList){
|
|
960
|
+
if (binDirent.isFile()) {
|
|
961
|
+
const binFileAbsolutePath = path__default.default.join(sourceFolderPath, dirent.name, binDirent.name);
|
|
962
|
+
const binExportPath = sourceFilenameToExportPath(binDirent.name);
|
|
963
|
+
if (fs__default.default.existsSync(binFileAbsolutePath)) {
|
|
964
|
+
bins.set(path.posix.join(BINARY_TAG, binExportPath), binFileAbsolutePath);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
} else {
|
|
969
|
+
// Search folder/index.<ext> convention entries
|
|
970
|
+
for (const extension of availableExtensions){
|
|
971
|
+
const indexAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${extension}`);
|
|
972
|
+
// Search folder/index.<special type>.<ext> convention entries
|
|
973
|
+
for (const specialExportType of runtimeExportConventions){
|
|
974
|
+
const indexSpecialAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${specialExportType}.${extension}`);
|
|
975
|
+
if (fs__default.default.existsSync(indexSpecialAbsoluteFile)) {
|
|
976
|
+
// Add special export path
|
|
977
|
+
// { ./<export path>.<special cond>: { <special cond>: 'index.<special cond>.<ext>' } }
|
|
978
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
979
|
+
const specialExportPath = exportPath + '.' + specialExportType;
|
|
980
|
+
const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
|
|
981
|
+
sourceFilesMap[specialExportType] = indexSpecialAbsoluteFile;
|
|
982
|
+
exportsEntries.set(specialExportPath, sourceFilesMap);
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
if (fs__default.default.existsSync(indexAbsoluteFile) && !isTestFile(indexAbsoluteFile)) {
|
|
986
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
987
|
+
const sourceFilesMap = exportsEntries.get(exportPath) || {};
|
|
988
|
+
const exportType = getExportTypeFromExportPath(exportPath);
|
|
989
|
+
sourceFilesMap[exportType] = indexAbsoluteFile;
|
|
990
|
+
exportsEntries.set(exportPath, sourceFilesMap);
|
|
991
|
+
break;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
} else if (dirent.isFile()) {
|
|
996
|
+
const isAvailableExtension = availableExtensions.has(path__default.default.extname(dirent.name).slice(1));
|
|
997
|
+
if (isAvailableExtension) {
|
|
998
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
999
|
+
const isBinFile = exportPath === './bin';
|
|
1000
|
+
const fullPath = path__default.default.join(sourceFolderPath, dirent.name);
|
|
1001
|
+
if (isBinFile) {
|
|
1002
|
+
bins.set(BINARY_TAG, fullPath);
|
|
1003
|
+
} else {
|
|
1004
|
+
if (hasAvailableExtension(dirent.name) && !isTestFile(dirent.name)) {
|
|
1005
|
+
const sourceFilesMap = exportsEntries.get(exportPath) || {};
|
|
1006
|
+
const exportType = getExportTypeFromExportPath(exportPath);
|
|
1007
|
+
sourceFilesMap[exportType] = fullPath;
|
|
1008
|
+
exportsEntries.set(exportPath, sourceFilesMap);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return {
|
|
1015
|
+
bins,
|
|
1016
|
+
exportsEntries
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const swcMinifyOptions = {
|
|
1021
|
+
compress: true,
|
|
1022
|
+
format: {
|
|
1023
|
+
comments: 'some'
|
|
1024
|
+
},
|
|
1025
|
+
mangle: {
|
|
1026
|
+
toplevel: true
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
924
1029
|
/**
|
|
925
1030
|
* return {
|
|
926
1031
|
* <absolute source path>: <pkg>/<export>
|
|
927
1032
|
* }
|
|
928
|
-
*/ function getReversedAlias(entries) {
|
|
1033
|
+
*/ function getReversedAlias({ entries, name }) {
|
|
929
1034
|
const alias = {};
|
|
930
|
-
for (const [
|
|
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;
|
|
@@ -949,7 +1055,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
949
1055
|
for (const [exportImportPath, exportCondition] of Object.entries(entries)){
|
|
950
1056
|
const entryFilePath = exportCondition.source;
|
|
951
1057
|
if (entryFilePath !== entry) {
|
|
952
|
-
externals.push(exportImportPath);
|
|
1058
|
+
externals.push(path.posix.join(pkg.name || '', normalizeExportPath(exportImportPath)));
|
|
953
1059
|
externals.push(entryFilePath);
|
|
954
1060
|
}
|
|
955
1061
|
}
|
|
@@ -1090,18 +1196,6 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1090
1196
|
}
|
|
1091
1197
|
};
|
|
1092
1198
|
}
|
|
1093
|
-
function hasEsmExport(exportPaths, tsCompilerOptions) {
|
|
1094
|
-
let hasEsm = false;
|
|
1095
|
-
for(const key in exportPaths){
|
|
1096
|
-
const exportInfo = exportPaths[key];
|
|
1097
|
-
const exportInfoEntries = Object.entries(exportInfo);
|
|
1098
|
-
if (exportInfoEntries.some(([exportType, file])=>isEsmExportName(exportType, file))) {
|
|
1099
|
-
hasEsm = true;
|
|
1100
|
-
break;
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
return Boolean(hasEsm || (tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop));
|
|
1104
|
-
}
|
|
1105
1199
|
function getModuleLater(moduleMeta) {
|
|
1106
1200
|
const directives = (moduleMeta.preserveDirectives || {
|
|
1107
1201
|
directives: []
|
|
@@ -1176,9 +1270,11 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
|
|
|
1176
1270
|
}
|
|
1177
1271
|
async function buildOutputConfigs(entry, bundleConfig, exportCondition, buildContext, dts) {
|
|
1178
1272
|
const { format } = bundleConfig;
|
|
1179
|
-
const { entries, pkg, exportPaths,
|
|
1273
|
+
const { entries, pkg, // exportPaths,
|
|
1274
|
+
cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
|
|
1180
1275
|
// Add esm mark and interop helper if esm export is detected
|
|
1181
|
-
const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions)
|
|
1276
|
+
const useEsModuleMark = tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop // hasEsmExport(exportPaths, tsCompilerOptions)
|
|
1277
|
+
;
|
|
1182
1278
|
const absoluteOutputFile = path.resolve(cwd, bundleConfig.file);
|
|
1183
1279
|
const outputFileExtension = path.extname(absoluteOutputFile);
|
|
1184
1280
|
const name = filePathWithoutExtension(absoluteOutputFile);
|
|
@@ -1223,111 +1319,6 @@ async function buildEntryConfig(bundleConfig, pluginContext, dts) {
|
|
|
1223
1319
|
}
|
|
1224
1320
|
return configs;
|
|
1225
1321
|
}
|
|
1226
|
-
async function collectEntry(// export type, e.g. react-server, edge-light those special cases required suffix
|
|
1227
|
-
exportType, options) {
|
|
1228
|
-
const { cwd, pkg, entries, entryPath, exportCondRef, entryExport: originEntryExport } = options;
|
|
1229
|
-
let entryExport = originEntryExport;
|
|
1230
|
-
let exportCondForType = {
|
|
1231
|
-
...exportCondRef
|
|
1232
|
-
};
|
|
1233
|
-
// Special cases of export type, only pass down the exportPaths for the type
|
|
1234
|
-
if (suffixedExportConventions.has(exportType)) {
|
|
1235
|
-
exportCondForType = {
|
|
1236
|
-
[exportType]: exportCondRef[exportType]
|
|
1237
|
-
};
|
|
1238
|
-
} else if (exportType[0] === '.' && suffixedExportConventions.has(exportType.slice(1))) {
|
|
1239
|
-
// e.g. .development, .production that has both esm and cjs export
|
|
1240
|
-
exportCondForType = exportCondRef;
|
|
1241
|
-
exportType = exportType.slice(1);
|
|
1242
|
-
entryExport = entryExport.replace(exportType, '');
|
|
1243
|
-
} else {
|
|
1244
|
-
// Basic export type, pass down the exportPaths with erasing the special ones
|
|
1245
|
-
for (const exportType of suffixedExportConventions){
|
|
1246
|
-
delete exportCondForType[exportType];
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
let source = entryPath;
|
|
1250
|
-
if (source) {
|
|
1251
|
-
source = resolveSourceFile(cwd, source);
|
|
1252
|
-
} else {
|
|
1253
|
-
source = await getSourcePathFromExportPath(cwd, entryExport, exportType);
|
|
1254
|
-
}
|
|
1255
|
-
if (!source) {
|
|
1256
|
-
return;
|
|
1257
|
-
}
|
|
1258
|
-
const exportCondition = {
|
|
1259
|
-
source,
|
|
1260
|
-
name: originEntryExport,
|
|
1261
|
-
export: exportCondForType
|
|
1262
|
-
};
|
|
1263
|
-
const nameWithExportPath = pkg.name ? path__default.default.join(pkg.name, exportCondition.name) : exportCondition.name;
|
|
1264
|
-
const needsDelimiter = !nameWithExportPath.endsWith('.') && exportType;
|
|
1265
|
-
const entryImportPath = nameWithExportPath + (needsDelimiter ? '.' : '') + exportType;
|
|
1266
|
-
entries[entryImportPath] = exportCondition;
|
|
1267
|
-
}
|
|
1268
|
-
/*
|
|
1269
|
-
* build configs for each entry from package exports
|
|
1270
|
-
*
|
|
1271
|
-
* return { <pkg>/<export>: { input: InputOptions, output: OutputOptions[] }
|
|
1272
|
-
*/ async function collectEntries(pkg, entryPath, exportPaths, cwd) {
|
|
1273
|
-
const entries = {};
|
|
1274
|
-
const binaryExports = pkg.bin;
|
|
1275
|
-
if (binaryExports) {
|
|
1276
|
-
// binDistPaths: [ [ 'bin1', './dist/bin1.js'], [ 'bin2', './dist/bin2.js'] ]
|
|
1277
|
-
const binPairs = typeof binaryExports === 'string' ? [
|
|
1278
|
-
[
|
|
1279
|
-
'bin',
|
|
1280
|
-
binaryExports
|
|
1281
|
-
]
|
|
1282
|
-
] : Object.keys(binaryExports).map((key)=>[
|
|
1283
|
-
path.join('bin', key),
|
|
1284
|
-
binaryExports[key]
|
|
1285
|
-
]);
|
|
1286
|
-
const binExportPaths = binPairs.reduce((acc, [binName, binDistPath])=>{
|
|
1287
|
-
const exportType = getExportTypeFromFile(binDistPath, pkg.type);
|
|
1288
|
-
acc[binName] = {
|
|
1289
|
-
[exportType]: binDistPath
|
|
1290
|
-
};
|
|
1291
|
-
return acc;
|
|
1292
|
-
}, {});
|
|
1293
|
-
for (const [binName] of binPairs){
|
|
1294
|
-
const source = await getSourcePathFromExportPath(cwd, binName, '$binary');
|
|
1295
|
-
if (!source) {
|
|
1296
|
-
logger.warn(`Cannot find source file for ${binName}`);
|
|
1297
|
-
continue;
|
|
1298
|
-
}
|
|
1299
|
-
const binEntryPath = await resolveSourceFile(cwd, source);
|
|
1300
|
-
entries[binName] = {
|
|
1301
|
-
source: binEntryPath,
|
|
1302
|
-
name: binName,
|
|
1303
|
-
export: binExportPaths[binName]
|
|
1304
|
-
};
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
const collectEntriesPromises = Object.keys(exportPaths).map(async (entryExport)=>{
|
|
1308
|
-
const exportCond = exportPaths[entryExport];
|
|
1309
|
-
const collectEntryOptions = {
|
|
1310
|
-
cwd,
|
|
1311
|
-
pkg,
|
|
1312
|
-
entries,
|
|
1313
|
-
entryPath,
|
|
1314
|
-
exportCondRef: exportCond,
|
|
1315
|
-
entryExport
|
|
1316
|
-
};
|
|
1317
|
-
if (entryExport.startsWith('.')) {
|
|
1318
|
-
await collectEntry('', collectEntryOptions);
|
|
1319
|
-
for (const exportCondType of suffixedExportConventions){
|
|
1320
|
-
if (exportCond[exportCondType]) {
|
|
1321
|
-
await collectEntry(exportCondType, collectEntryOptions);
|
|
1322
|
-
} else if (entryExport === '.' + exportCondType) {
|
|
1323
|
-
await collectEntry(entryExport, collectEntryOptions);
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
});
|
|
1328
|
-
await Promise.all(collectEntriesPromises);
|
|
1329
|
-
return entries;
|
|
1330
|
-
}
|
|
1331
1322
|
async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
|
|
1332
1323
|
const { file } = bundleConfig;
|
|
1333
1324
|
const { pkg, cwd } = pluginContext;
|
|
@@ -1335,29 +1326,32 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
|
|
|
1335
1326
|
const outputExports = getExportsDistFilesOfCondition(pkg, exportCondition, cwd);
|
|
1336
1327
|
// If there's nothing found, give a default output
|
|
1337
1328
|
if (outputExports.length === 0 && !pkg.bin) {
|
|
1338
|
-
const
|
|
1329
|
+
const isEsmPkg = isESModulePackage(pkg.type);
|
|
1330
|
+
const defaultFormat = isEsmPkg ? 'esm' : 'cjs';
|
|
1339
1331
|
outputExports.push({
|
|
1340
1332
|
format: defaultFormat,
|
|
1341
|
-
file: path.join(cwd, 'dist/index.js')
|
|
1333
|
+
file: path.join(cwd, 'dist/index.js'.replace('/', path__default.default.sep)),
|
|
1334
|
+
exportCondition: 'default'
|
|
1342
1335
|
});
|
|
1343
1336
|
}
|
|
1344
1337
|
let bundleOptions = [];
|
|
1345
1338
|
// multi outputs with specified format
|
|
1346
1339
|
// CLI output option is always prioritized
|
|
1347
1340
|
if (file) {
|
|
1348
|
-
|
|
1349
|
-
const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format;
|
|
1341
|
+
const fallbackExport = outputExports[0];
|
|
1350
1342
|
bundleOptions = [
|
|
1351
1343
|
{
|
|
1352
|
-
|
|
1353
|
-
format: bundleConfig.format ||
|
|
1344
|
+
file: path.resolve(cwd, file),
|
|
1345
|
+
format: bundleConfig.format || fallbackExport.format,
|
|
1346
|
+
exportCondition: fallbackExport.exportCondition
|
|
1354
1347
|
}
|
|
1355
1348
|
];
|
|
1356
1349
|
} else {
|
|
1357
1350
|
bundleOptions = outputExports.map((exportDist)=>{
|
|
1358
1351
|
return {
|
|
1359
|
-
|
|
1360
|
-
format: exportDist.format
|
|
1352
|
+
file: path.resolve(cwd, exportDist.file),
|
|
1353
|
+
format: exportDist.format,
|
|
1354
|
+
exportCondition: exportDist.exportCondition
|
|
1361
1355
|
};
|
|
1362
1356
|
});
|
|
1363
1357
|
}
|
|
@@ -1369,22 +1363,29 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, dts) {
|
|
|
1369
1363
|
if (exportCondition.export.types) {
|
|
1370
1364
|
uniqTypes.add(path.resolve(cwd, exportCondition.export.types));
|
|
1371
1365
|
}
|
|
1372
|
-
const typeForExtension = getExportFileTypePath(bundleOption.
|
|
1366
|
+
const typeForExtension = getExportFileTypePath(bundleOption.file);
|
|
1373
1367
|
uniqTypes.add(typeForExtension);
|
|
1374
1368
|
});
|
|
1375
1369
|
bundleOptions = Array.from(uniqTypes).map((typeFile)=>{
|
|
1376
1370
|
return {
|
|
1377
|
-
|
|
1378
|
-
format: 'esm'
|
|
1371
|
+
file: typeFile,
|
|
1372
|
+
format: 'esm',
|
|
1373
|
+
exportCondition: 'types'
|
|
1379
1374
|
};
|
|
1380
1375
|
});
|
|
1381
1376
|
}
|
|
1382
1377
|
const outputConfigs = bundleOptions.map(async (bundleOption)=>{
|
|
1378
|
+
const targetExportCondition = {
|
|
1379
|
+
...exportCondition,
|
|
1380
|
+
export: {
|
|
1381
|
+
[bundleOption.exportCondition]: bundleOption.exportCondition === 'types' ? bundleOption.file : exportCondition.export[bundleOption.exportCondition]
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1383
1384
|
return await buildOutputConfigs(entry, {
|
|
1384
1385
|
...bundleConfig,
|
|
1385
|
-
file: bundleOption.
|
|
1386
|
+
file: bundleOption.file,
|
|
1386
1387
|
format: bundleOption.format
|
|
1387
|
-
},
|
|
1388
|
+
}, targetExportCondition, pluginContext, dts);
|
|
1388
1389
|
});
|
|
1389
1390
|
return Promise.all(outputConfigs);
|
|
1390
1391
|
}
|
|
@@ -1440,7 +1441,7 @@ function createOutputState({ entries }) {
|
|
|
1440
1441
|
};
|
|
1441
1442
|
}
|
|
1442
1443
|
function isBin(filename) {
|
|
1443
|
-
return filename ===
|
|
1444
|
+
return filename === BINARY_TAG || filename.startsWith(BINARY_TAG + '/');
|
|
1444
1445
|
}
|
|
1445
1446
|
function isTypeFile(filename) {
|
|
1446
1447
|
return filename.endsWith('.d.ts') || filename.endsWith('.d.mts') || filename.endsWith('.d.cts');
|
|
@@ -1448,20 +1449,12 @@ function isTypeFile(filename) {
|
|
|
1448
1449
|
function normalizeExportName(exportName) {
|
|
1449
1450
|
const isBinary = isBin(exportName);
|
|
1450
1451
|
let result = exportName;
|
|
1451
|
-
const isSubpathExport = exportName.includes('/');
|
|
1452
|
-
const isSpecialExport = exportName.includes('.');
|
|
1453
1452
|
if (isBinary) {
|
|
1454
|
-
result = (exportName.replace(
|
|
1455
|
-
} else if (isSubpathExport || isSpecialExport) {
|
|
1456
|
-
const subExportName = exportName.split('/')[1] || exportName;
|
|
1457
|
-
if (subExportName.includes('.') && subExportName !== '.') {
|
|
1458
|
-
const [originExportName, specialCondition] = subExportName.split('.');
|
|
1459
|
-
result = (isSubpathExport ? relativify(originExportName) : '.') + ' (' + specialCondition + ')';
|
|
1460
|
-
} else {
|
|
1461
|
-
result = isSubpathExport ? relativify(subExportName) : '.';
|
|
1462
|
-
}
|
|
1453
|
+
result = (exportName.replace(new RegExp(`^\\${BINARY_TAG}\\/?`), '') || '.') + ' (bin)';
|
|
1463
1454
|
} else {
|
|
1464
|
-
|
|
1455
|
+
const normalizedExportPath = normalizeExportPath(exportName);
|
|
1456
|
+
const specialConditionName = getSpecialExportTypeFromExportPath(exportName);
|
|
1457
|
+
result = normalizedExportPath + (specialConditionName !== 'default' ? ` (${specialConditionName})` : '');
|
|
1465
1458
|
}
|
|
1466
1459
|
return result;
|
|
1467
1460
|
}
|
|
@@ -1512,61 +1505,6 @@ function logOutputState(sizeCollector) {
|
|
|
1512
1505
|
});
|
|
1513
1506
|
}
|
|
1514
1507
|
|
|
1515
|
-
// TODO: support nested wildcard exportsCondition (e.g. './foo/*')
|
|
1516
|
-
const getWildcardExports = (exportsCondition)=>{
|
|
1517
|
-
return {
|
|
1518
|
-
'./*': exportsCondition['./*']
|
|
1519
|
-
};
|
|
1520
|
-
};
|
|
1521
|
-
const isExportable = async (dirent, pathname)=>{
|
|
1522
|
-
if (dirent.isDirectory()) {
|
|
1523
|
-
const innerDirents = await fsp__default.default.readdir(path__default.default.join(pathname, dirent.name), {
|
|
1524
|
-
withFileTypes: true
|
|
1525
|
-
});
|
|
1526
|
-
return innerDirents.some(({ name })=>name.startsWith('index') && hasAvailableExtension(name));
|
|
1527
|
-
}
|
|
1528
|
-
return dirent.isFile() && !dirent.name.startsWith('index') && hasAvailableExtension(dirent.name);
|
|
1529
|
-
};
|
|
1530
|
-
async function getExportables(cwd, excludeKeys) {
|
|
1531
|
-
const pathname = path__default.default.resolve(cwd, SRC);
|
|
1532
|
-
const dirents = await fsp__default.default.readdir(pathname, {
|
|
1533
|
-
withFileTypes: true
|
|
1534
|
-
});
|
|
1535
|
-
const exportables = await Promise.all(dirents.map(async (dirent)=>await isExportable(dirent, pathname) && !excludeKeys.includes(dirent.name) ? dirent.name : undefined));
|
|
1536
|
-
return exportables.filter(nonNullable);
|
|
1537
|
-
}
|
|
1538
|
-
function mapWildcard(wildcardExports, exportables) {
|
|
1539
|
-
return exportables.map((exportable)=>{
|
|
1540
|
-
const isFile = exportable.includes('.');
|
|
1541
|
-
const filename = isFile ? filePathWithoutExtension(exportable) : exportable;
|
|
1542
|
-
return {
|
|
1543
|
-
[`./${filename}`]: Object.fromEntries(Object.entries(wildcardExports['./*']).map(([key, value])=>[
|
|
1544
|
-
key,
|
|
1545
|
-
value.replace(/\*/g, isFile ? filename : `${filename}/index`)
|
|
1546
|
-
]))
|
|
1547
|
-
};
|
|
1548
|
-
});
|
|
1549
|
-
}
|
|
1550
|
-
async function resolveWildcardExports(exportsCondition, cwd) {
|
|
1551
|
-
if (!exportsCondition || typeof exportsCondition === 'string') return undefined;
|
|
1552
|
-
const hasWildcard = !!exportsCondition['./*'];
|
|
1553
|
-
if (hasWildcard) {
|
|
1554
|
-
logger.warn(`The wildcard export "./*" is experimental and may change or be removed at any time.\n` + 'To open an issue, please visit https://github.com/huozhi/bunchee/issues' + '.\n');
|
|
1555
|
-
// './foo' -> ['foo']; './foo/bar' -> ['bar']
|
|
1556
|
-
// will contain '*' also but it's not a problem
|
|
1557
|
-
const excludeKeys = Object.keys(exportsCondition).map((key)=>key.split('/').pop());
|
|
1558
|
-
const exportables = await getExportables(cwd, excludeKeys);
|
|
1559
|
-
if (exportables.length > 0) {
|
|
1560
|
-
const wildcardExports = getWildcardExports(exportsCondition);
|
|
1561
|
-
const resolvedWildcardExports = mapWildcard(wildcardExports, exportables);
|
|
1562
|
-
const resolvedExports = Object.assign({}, exportsCondition, ...resolvedWildcardExports);
|
|
1563
|
-
delete resolvedExports['./*'];
|
|
1564
|
-
return resolvedExports;
|
|
1565
|
-
}
|
|
1566
|
-
}
|
|
1567
|
-
return undefined;
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
1508
|
function assignDefault(options, name, defaultValue) {
|
|
1571
1509
|
if (!(name in options) || options[name] == null) {
|
|
1572
1510
|
options[name] = defaultValue;
|
|
@@ -1582,12 +1520,11 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1582
1520
|
assignDefault(options, 'minify', false);
|
|
1583
1521
|
assignDefault(options, 'target', 'es2015');
|
|
1584
1522
|
const pkg = await getPackageMeta(cwd);
|
|
1585
|
-
const
|
|
1586
|
-
const
|
|
1587
|
-
const exportPaths = getExportPaths(pkg, resolvedWildcardExports);
|
|
1588
|
-
const isMultiEntries = hasMultiEntryExport(exportPaths) // exportPathsLength > 1
|
|
1589
|
-
;
|
|
1523
|
+
const parsedExportsInfo = parseExports(pkg);
|
|
1524
|
+
const isMultiEntries = hasMultiEntryExport(parsedExportsInfo);
|
|
1590
1525
|
const hasBin = Boolean(pkg.bin);
|
|
1526
|
+
// Original input file path, client path might change later
|
|
1527
|
+
const inputFile = cliEntryPath;
|
|
1591
1528
|
const isFromCli = Boolean(cliEntryPath);
|
|
1592
1529
|
let tsConfig = resolveTsConfig(cwd);
|
|
1593
1530
|
let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
|
|
@@ -1602,21 +1539,27 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1602
1539
|
cliEntryPath = cliEntryPath || await getSourcePathFromExportPath(cwd, '.', 'default') || '';
|
|
1603
1540
|
}
|
|
1604
1541
|
// Handle CLI input
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1542
|
+
let mainExportPath;
|
|
1543
|
+
let typesEntryPath;
|
|
1544
|
+
if (isFromCli) {
|
|
1608
1545
|
// with -o option
|
|
1609
1546
|
if (options.file) {
|
|
1610
|
-
|
|
1547
|
+
mainExportPath = options.file;
|
|
1611
1548
|
}
|
|
1612
|
-
if (
|
|
1549
|
+
if (mainExportPath) {
|
|
1613
1550
|
if (options.dts) {
|
|
1614
|
-
typesEntryPath = getExportFileTypePath(
|
|
1551
|
+
typesEntryPath = getExportFileTypePath(mainExportPath);
|
|
1615
1552
|
}
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1553
|
+
parsedExportsInfo.set('.', [
|
|
1554
|
+
[
|
|
1555
|
+
mainExportPath,
|
|
1556
|
+
'default'
|
|
1557
|
+
],
|
|
1558
|
+
Boolean(typesEntryPath) && [
|
|
1559
|
+
typesEntryPath,
|
|
1560
|
+
'types'
|
|
1561
|
+
]
|
|
1562
|
+
].filter(Boolean));
|
|
1620
1563
|
}
|
|
1621
1564
|
}
|
|
1622
1565
|
const bundleOrWatch = async (rollupConfig)=>{
|
|
@@ -1646,7 +1589,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1646
1589
|
}
|
|
1647
1590
|
}
|
|
1648
1591
|
}
|
|
1649
|
-
const entries = await
|
|
1592
|
+
const entries = await collectEntriesFromParsedExports(cwd, parsedExportsInfo, inputFile);
|
|
1650
1593
|
const hasTypeScriptFiles = Object.values(entries).some((entry)=>isTypescriptFile(entry.source));
|
|
1651
1594
|
if (hasTypeScriptFiles && !hasTsConfig) {
|
|
1652
1595
|
const tsConfigPath = path.resolve(cwd, 'tsconfig.json');
|
|
@@ -1657,11 +1600,13 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1657
1600
|
const sizeCollector = createOutputState({
|
|
1658
1601
|
entries
|
|
1659
1602
|
});
|
|
1660
|
-
const entriesAlias = getReversedAlias(
|
|
1603
|
+
const entriesAlias = getReversedAlias({
|
|
1604
|
+
entries,
|
|
1605
|
+
name: pkg.name
|
|
1606
|
+
});
|
|
1661
1607
|
const buildContext = {
|
|
1662
1608
|
entries,
|
|
1663
1609
|
pkg,
|
|
1664
|
-
exportPaths,
|
|
1665
1610
|
cwd,
|
|
1666
1611
|
tsOptions: defaultTsOptions,
|
|
1667
1612
|
useTypeScript: hasTsConfig,
|
|
@@ -1673,7 +1618,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1673
1618
|
};
|
|
1674
1619
|
const buildConfigs = await buildEntryConfig(options, buildContext, false);
|
|
1675
1620
|
const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
|
|
1676
|
-
const typesJobs = hasTsConfig ? (await buildEntryConfig(options, buildContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
|
|
1621
|
+
const typesJobs = hasTsConfig && options.dts !== false ? (await buildEntryConfig(options, buildContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
|
|
1677
1622
|
const totalJobs = assetsJobs.concat(typesJobs);
|
|
1678
1623
|
const result = await Promise.all(totalJobs);
|
|
1679
1624
|
if (result.length === 0) {
|