bunchee 4.1.1 → 4.2.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/dist/bin/cli.js +3 -3
- package/dist/index.js +307 -189
- package/package.json +6 -5
package/dist/bin/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var path = require('path');
|
|
3
3
|
var arg = require('arg');
|
|
4
4
|
var fs = require('fs/promises');
|
|
5
|
+
var bunchee = require('bunchee');
|
|
5
6
|
|
|
6
7
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
8
|
|
|
@@ -54,7 +55,7 @@ async function fileExists(filePath) {
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
var version = "4.
|
|
58
|
+
var version = "4.2.1";
|
|
58
59
|
|
|
59
60
|
const helpMessage = `
|
|
60
61
|
Usage: bunchee [options]
|
|
@@ -165,11 +166,10 @@ async function run(args) {
|
|
|
165
166
|
return help();
|
|
166
167
|
}
|
|
167
168
|
const entry = source ? path__default.default.resolve(cwd, source) : '';
|
|
168
|
-
const bundle = require('../index').bundle;
|
|
169
169
|
let timeStart = Date.now();
|
|
170
170
|
let timeEnd;
|
|
171
171
|
try {
|
|
172
|
-
await bundle(entry, bundleConfig);
|
|
172
|
+
await bunchee.bundle(entry, bundleConfig);
|
|
173
173
|
timeEnd = Date.now();
|
|
174
174
|
} catch (err) {
|
|
175
175
|
if (err.name === 'NOT_EXISTED') {
|
package/dist/index.js
CHANGED
|
@@ -10,9 +10,9 @@ var json = require('@rollup/plugin-json');
|
|
|
10
10
|
var pluginNodeResolve = require('@rollup/plugin-node-resolve');
|
|
11
11
|
var replace = require('@rollup/plugin-replace');
|
|
12
12
|
var esmShim = require('@rollup/plugin-esm-shim');
|
|
13
|
-
var prettyBytes = require('pretty-bytes');
|
|
14
|
-
var pluginutils = require('@rollup/pluginutils');
|
|
15
13
|
var preserveDirectives = require('rollup-preserve-directives');
|
|
14
|
+
var pluginutils = require('@rollup/pluginutils');
|
|
15
|
+
var prettyBytes = require('pretty-bytes');
|
|
16
16
|
var module$1 = require('module');
|
|
17
17
|
|
|
18
18
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -23,96 +23,8 @@ var commonjs__default = /*#__PURE__*/_interopDefault(commonjs);
|
|
|
23
23
|
var json__default = /*#__PURE__*/_interopDefault(json);
|
|
24
24
|
var replace__default = /*#__PURE__*/_interopDefault(replace);
|
|
25
25
|
var esmShim__default = /*#__PURE__*/_interopDefault(esmShim);
|
|
26
|
-
var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes);
|
|
27
26
|
var preserveDirectives__default = /*#__PURE__*/_interopDefault(preserveDirectives);
|
|
28
|
-
|
|
29
|
-
const availableExtensions = [
|
|
30
|
-
'js',
|
|
31
|
-
'cjs',
|
|
32
|
-
'mjs',
|
|
33
|
-
'jsx',
|
|
34
|
-
'ts',
|
|
35
|
-
'tsx',
|
|
36
|
-
'cts',
|
|
37
|
-
'mts'
|
|
38
|
-
];
|
|
39
|
-
const availableExportConventions = [
|
|
40
|
-
'react-server',
|
|
41
|
-
'react-native',
|
|
42
|
-
'edge-light'
|
|
43
|
-
];
|
|
44
|
-
const availableESExtensionsRegex = /\.(m|c)?[jt]sx?$/;
|
|
45
|
-
const dtsExtensionRegex = /\.d\.(m|c)?ts$/;
|
|
46
|
-
const SRC = 'src';
|
|
47
|
-
const dtsExtensions = {
|
|
48
|
-
js: '.d.ts',
|
|
49
|
-
cjs: '.d.cts',
|
|
50
|
-
mjs: '.d.mts'
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const logger = {
|
|
54
|
-
log (...arg) {
|
|
55
|
-
console.log(' ', ...arg);
|
|
56
|
-
},
|
|
57
|
-
warn (...arg) {
|
|
58
|
-
console.warn(' ⚠️', ...arg);
|
|
59
|
-
},
|
|
60
|
-
error (...arg) {
|
|
61
|
-
console.error(' ⨯', ...arg);
|
|
62
|
-
},
|
|
63
|
-
info (...arg) {
|
|
64
|
-
console.log(' ✓', ...arg);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
function createChunkSizeCollector() {
|
|
69
|
-
const sizes = new Map();
|
|
70
|
-
function addSize(name, size) {
|
|
71
|
-
sizes.set(name, size);
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
plugin: (cwd)=>{
|
|
75
|
-
return {
|
|
76
|
-
name: 'collect-sizes',
|
|
77
|
-
augmentChunkHash () {
|
|
78
|
-
// Do nothing, but use the hook to keep the plugin instance alive
|
|
79
|
-
},
|
|
80
|
-
renderChunk (code, chunk, options) {
|
|
81
|
-
const dir = options.dir || options.file && path__default.default.dirname(options.file);
|
|
82
|
-
let fileName = chunk.fileName;
|
|
83
|
-
if (dir) {
|
|
84
|
-
const filePath = path__default.default.join(dir, fileName);
|
|
85
|
-
fileName = filePath.startsWith(cwd) ? path__default.default.relative(cwd, filePath) : filePath;
|
|
86
|
-
}
|
|
87
|
-
addSize(fileName, code.length);
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
},
|
|
92
|
-
getSizeStats () {
|
|
93
|
-
const sizeStats = [];
|
|
94
|
-
sizes.forEach((size, name)=>{
|
|
95
|
-
sizeStats.push([
|
|
96
|
-
name,
|
|
97
|
-
prettyBytes__default.default(size),
|
|
98
|
-
size
|
|
99
|
-
]);
|
|
100
|
-
});
|
|
101
|
-
return sizeStats;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
// This can also be passed down as stats from top level
|
|
106
|
-
const sizeCollector = createChunkSizeCollector();
|
|
107
|
-
function logSizeStats() {
|
|
108
|
-
const stats = sizeCollector.getSizeStats();
|
|
109
|
-
const maxLength = Math.max(...stats.map(([filename])=>filename.length));
|
|
110
|
-
stats.forEach(([filename, prettiedSize])=>{
|
|
111
|
-
const padding = ' '.repeat(maxLength - filename.length);
|
|
112
|
-
const action = dtsExtensionRegex.test(filename) ? 'Typed' : 'Built';
|
|
113
|
-
logger.info(`${action} ${filename}${padding} - ${prettiedSize}`);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
27
|
+
var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes);
|
|
116
28
|
|
|
117
29
|
function minifyCSS(content) {
|
|
118
30
|
return content.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$|(?:^|\s)(\s+)|\s*([\{\};,:])\s*|\s+(!)\s+/g, (match, p1, p2, p3, p4)=>{
|
|
@@ -206,6 +118,31 @@ function rawContent({ exclude }) {
|
|
|
206
118
|
};
|
|
207
119
|
}
|
|
208
120
|
|
|
121
|
+
// Alias entries to import path
|
|
122
|
+
// e.g.
|
|
123
|
+
// For a resolved file, if it's one of the entries,
|
|
124
|
+
// aliases it as export path, such as <absolute file> -> <pkg>/<export path>
|
|
125
|
+
function aliasEntries({ entries }) {
|
|
126
|
+
return {
|
|
127
|
+
name: 'alias',
|
|
128
|
+
resolveId: {
|
|
129
|
+
async handler (source, importer, options) {
|
|
130
|
+
const resolvedId = await this.resolve(source, importer, options);
|
|
131
|
+
if (resolvedId != null) {
|
|
132
|
+
const aliasedId = entries[resolvedId.id];
|
|
133
|
+
if (aliasedId != null) {
|
|
134
|
+
return {
|
|
135
|
+
id: aliasedId,
|
|
136
|
+
external: true
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
209
146
|
function prependDirectives() {
|
|
210
147
|
return {
|
|
211
148
|
name: 'prependDirective',
|
|
@@ -231,6 +168,53 @@ function prependDirectives() {
|
|
|
231
168
|
};
|
|
232
169
|
}
|
|
233
170
|
|
|
171
|
+
const availableExtensions = [
|
|
172
|
+
'js',
|
|
173
|
+
'cjs',
|
|
174
|
+
'mjs',
|
|
175
|
+
'jsx',
|
|
176
|
+
'ts',
|
|
177
|
+
'tsx',
|
|
178
|
+
'cts',
|
|
179
|
+
'mts'
|
|
180
|
+
];
|
|
181
|
+
const nodeResolveExtensions = [
|
|
182
|
+
'.mjs',
|
|
183
|
+
'.cjs',
|
|
184
|
+
'.js',
|
|
185
|
+
'.json',
|
|
186
|
+
'.node',
|
|
187
|
+
'.jsx'
|
|
188
|
+
];
|
|
189
|
+
const availableExportConventions = [
|
|
190
|
+
'react-server',
|
|
191
|
+
'react-native',
|
|
192
|
+
'edge-light'
|
|
193
|
+
];
|
|
194
|
+
const availableESExtensionsRegex = /\.(m|c)?[jt]sx?$/;
|
|
195
|
+
const dtsExtensionRegex = /\.d\.(m|c)?ts$/;
|
|
196
|
+
const SRC = 'src';
|
|
197
|
+
const dtsExtensions = {
|
|
198
|
+
js: '.d.ts',
|
|
199
|
+
cjs: '.d.cts',
|
|
200
|
+
mjs: '.d.mts'
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const logger = {
|
|
204
|
+
log (...arg) {
|
|
205
|
+
console.log(' ', ...arg);
|
|
206
|
+
},
|
|
207
|
+
warn (...arg) {
|
|
208
|
+
console.warn(' ⚠️', ...arg);
|
|
209
|
+
},
|
|
210
|
+
error (...arg) {
|
|
211
|
+
console.error(' ⨯', ...arg);
|
|
212
|
+
},
|
|
213
|
+
info (...arg) {
|
|
214
|
+
console.log(' ✓', ...arg);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
234
218
|
function exit(err) {
|
|
235
219
|
logger.error(err);
|
|
236
220
|
process.exit(1);
|
|
@@ -521,28 +505,29 @@ function isEsmExportName(name, ext) {
|
|
|
521
505
|
'module'
|
|
522
506
|
].includes(name) || ext === 'mjs';
|
|
523
507
|
}
|
|
524
|
-
function isCjsExportName(name, ext) {
|
|
525
|
-
|
|
508
|
+
function isCjsExportName(pkg, name, ext) {
|
|
509
|
+
const isESModule = isESModulePackage(pkg.type);
|
|
510
|
+
return !isESModule && [
|
|
526
511
|
'require',
|
|
527
512
|
'main',
|
|
528
513
|
'node',
|
|
529
514
|
'default'
|
|
530
|
-
].includes(name) || ext === 'cjs';
|
|
515
|
+
].includes(name) && ext !== 'mjs' || ext === 'cjs';
|
|
531
516
|
}
|
|
532
517
|
function getExportConditionDist(pkg, parsedExportCondition, cwd) {
|
|
533
518
|
const dist = [];
|
|
534
519
|
const existed = new Set();
|
|
535
520
|
const exportTypes = Object.keys(parsedExportCondition.export);
|
|
536
|
-
for (const
|
|
537
|
-
if (
|
|
521
|
+
for (const exportType of exportTypes){
|
|
522
|
+
if (exportType === 'types') {
|
|
538
523
|
continue;
|
|
539
524
|
}
|
|
540
|
-
const filePath = parsedExportCondition.export[
|
|
525
|
+
const filePath = parsedExportCondition.export[exportType];
|
|
541
526
|
const ext = path.extname(filePath).slice(1);
|
|
542
|
-
const relativePath = parsedExportCondition.export[
|
|
527
|
+
const relativePath = parsedExportCondition.export[exportType];
|
|
543
528
|
const distFile = getDistPath(relativePath, cwd);
|
|
544
529
|
let format = 'esm';
|
|
545
|
-
if (isCjsExportName(
|
|
530
|
+
if (isCjsExportName(pkg, exportType, ext)) {
|
|
546
531
|
format = 'cjs';
|
|
547
532
|
}
|
|
548
533
|
// Deduplicate the same path jobs
|
|
@@ -595,16 +580,36 @@ function getBuildEnv(envs) {
|
|
|
595
580
|
}, {});
|
|
596
581
|
return envVars;
|
|
597
582
|
}
|
|
598
|
-
|
|
583
|
+
/**
|
|
584
|
+
* return { '<pkg>/<export>': '<absolute source path> }
|
|
585
|
+
*/ function getEntriesAlias(entries) {
|
|
586
|
+
const alias = {};
|
|
587
|
+
for (const [entryImportPath, exportCondition] of Object.entries(entries)){
|
|
588
|
+
alias[entryImportPath] = exportCondition.source;
|
|
589
|
+
}
|
|
590
|
+
return alias;
|
|
591
|
+
}
|
|
592
|
+
async function buildInputConfig(entry, entries, pkg, options, cwd, { tsConfigPath, tsCompilerOptions }, pluginContext, dts) {
|
|
593
|
+
const entriesAlias = getEntriesAlias(entries);
|
|
594
|
+
const reversedAlias = {};
|
|
595
|
+
for (const [key, value] of Object.entries(entriesAlias)){
|
|
596
|
+
if (value !== entry) {
|
|
597
|
+
reversedAlias[value] = key;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
599
600
|
const hasNoExternal = options.external === null;
|
|
600
601
|
var _options_external;
|
|
601
602
|
const externals = hasNoExternal ? [] : [
|
|
602
603
|
pkg.peerDependencies,
|
|
603
604
|
pkg.dependencies,
|
|
604
605
|
pkg.peerDependenciesMeta
|
|
605
|
-
].filter((n)=>Boolean(n)).map((o)=>Object.keys(o)).reduce((a, b)=>a.concat(b), []).concat((
|
|
606
|
-
|
|
607
|
-
|
|
606
|
+
].filter((n)=>Boolean(n)).map((o)=>Object.keys(o)).reduce((a, b)=>a.concat(b), []).concat((_options_external = options.external) != null ? _options_external : []);
|
|
607
|
+
for (const [exportImportPath, entryFilePath] of Object.entries(entriesAlias)){
|
|
608
|
+
if (entryFilePath !== entry) {
|
|
609
|
+
externals.push(exportImportPath);
|
|
610
|
+
externals.push(entryFilePath);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
608
613
|
const { useTypescript, runtime, target: jscTarget, minify: shouldMinify } = options;
|
|
609
614
|
const hasSpecifiedTsTarget = Boolean(tsCompilerOptions.target && tsConfigPath);
|
|
610
615
|
const swcParserConfig = {
|
|
@@ -631,10 +636,13 @@ async function buildInputConfig(entry, pkg, options, cwd, { tsConfigPath, tsComp
|
|
|
631
636
|
inlineSourcesContent: false,
|
|
632
637
|
isModule: true
|
|
633
638
|
};
|
|
634
|
-
const sizePlugin = sizeCollector.plugin(cwd);
|
|
639
|
+
const sizePlugin = pluginContext.sizeCollector.plugin(cwd);
|
|
635
640
|
// common plugins for both dts and ts assets that need to be processed
|
|
636
641
|
const commonPlugins = [
|
|
637
|
-
sizePlugin
|
|
642
|
+
sizePlugin,
|
|
643
|
+
aliasEntries({
|
|
644
|
+
entries: reversedAlias
|
|
645
|
+
})
|
|
638
646
|
];
|
|
639
647
|
const baseResolvedTsOptions = {
|
|
640
648
|
declaration: true,
|
|
@@ -692,14 +700,7 @@ async function buildInputConfig(entry, pkg, options, cwd, { tsConfigPath, tsComp
|
|
|
692
700
|
}),
|
|
693
701
|
pluginNodeResolve.nodeResolve({
|
|
694
702
|
preferBuiltins: runtime === 'node',
|
|
695
|
-
extensions:
|
|
696
|
-
'.mjs',
|
|
697
|
-
'.cjs',
|
|
698
|
-
'.js',
|
|
699
|
-
'.json',
|
|
700
|
-
'.node',
|
|
701
|
-
'.jsx'
|
|
702
|
-
]
|
|
703
|
+
extensions: nodeResolveExtensions
|
|
703
704
|
}),
|
|
704
705
|
commonjs__default.default({
|
|
705
706
|
exclude: options.external || null
|
|
@@ -731,7 +732,8 @@ async function buildInputConfig(entry, pkg, options, cwd, { tsConfigPath, tsComp
|
|
|
731
732
|
'MIXED_EXPORTS',
|
|
732
733
|
'PREFER_NAMED_EXPORTS',
|
|
733
734
|
'UNRESOLVED_IMPORT',
|
|
734
|
-
'THIS_IS_UNDEFINED'
|
|
735
|
+
'THIS_IS_UNDEFINED',
|
|
736
|
+
'INVALID_ANNOTATION'
|
|
735
737
|
].includes(code)) return;
|
|
736
738
|
// If the circular dependency warning is from node_modules, ignore it
|
|
737
739
|
if (code === 'CIRCULAR_DEPENDENCY' && /Circular dependency: node_modules/.test(warning.message)) {
|
|
@@ -753,23 +755,58 @@ function hasEsmExport(exportPaths, tsCompilerOptions) {
|
|
|
753
755
|
}
|
|
754
756
|
return Boolean(hasEsm || (tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop));
|
|
755
757
|
}
|
|
756
|
-
|
|
757
|
-
const moduleInfo = ctx.getModuleInfo(id);
|
|
758
|
-
const moduleMeta = moduleInfo == null ? void 0 : moduleInfo.meta;
|
|
759
|
-
if (!moduleInfo || !moduleMeta) {
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
758
|
+
function getModuleLater(moduleMeta) {
|
|
762
759
|
const directives = (moduleMeta.preserveDirectives || {
|
|
763
760
|
directives: []
|
|
764
761
|
}).directives.map((d)=>d.replace(/^use /, '')).filter((d)=>d !== 'strict');
|
|
765
762
|
const moduleLayer = directives[0];
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
return
|
|
771
|
-
|
|
772
|
-
|
|
763
|
+
return moduleLayer;
|
|
764
|
+
}
|
|
765
|
+
// dependencyGraphMap: Map<subModuleId, Set<entryParentId>>
|
|
766
|
+
function createSplitChunks(dependencyGraphMap) {
|
|
767
|
+
return function splitChunks(id, ctx) {
|
|
768
|
+
const moduleInfo = ctx.getModuleInfo(id);
|
|
769
|
+
if (!moduleInfo) {
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
const { isEntry } = moduleInfo;
|
|
773
|
+
const moduleMeta = moduleInfo.meta;
|
|
774
|
+
const moduleLayer = getModuleLater(moduleMeta);
|
|
775
|
+
// Collect the sub modules of the entry, if they're having layer, and the same layer with the entry, push them to the dependencyGraphMap.
|
|
776
|
+
if (isEntry) {
|
|
777
|
+
const subModuleIds = ctx.getModuleIds();
|
|
778
|
+
for (const subId of subModuleIds){
|
|
779
|
+
const subModuleInfo = ctx.getModuleInfo(subId);
|
|
780
|
+
if (!subModuleInfo) {
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
const subModuleLayer = getModuleLater(moduleMeta);
|
|
784
|
+
if (subModuleLayer === moduleLayer) {
|
|
785
|
+
if (!dependencyGraphMap.has(subId)) {
|
|
786
|
+
dependencyGraphMap.set(subId, new Set());
|
|
787
|
+
}
|
|
788
|
+
dependencyGraphMap.get(subId).add(id);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
// If current module has a layer, and it's not an entry
|
|
793
|
+
if (moduleLayer && !isEntry) {
|
|
794
|
+
// If the module is imported by the entry:
|
|
795
|
+
// when the module layer is same as entry layer, keep it as part of entry and don't split it;
|
|
796
|
+
// when the module layer is different from entry layer, split the module into a separate chunk as a separate boundary.
|
|
797
|
+
if (dependencyGraphMap.has(id)) {
|
|
798
|
+
const parentModuleLayers = Array.from(dependencyGraphMap.get(id));
|
|
799
|
+
if (parentModuleLayers.every((layer)=>layer === moduleLayer)) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
const chunkName = path__default.default.basename(id, path__default.default.extname(id));
|
|
803
|
+
return `${chunkName}-${moduleLayer}`;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return;
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
function buildOutputConfigs(pkg, exportPaths, options, exportCondition, cwd, { tsCompilerOptions }, pluginContext, dts) {
|
|
773
810
|
const { format } = options;
|
|
774
811
|
// Add esm mark and interop helper if esm export is detected
|
|
775
812
|
const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions);
|
|
@@ -795,7 +832,7 @@ function buildOutputConfigs(pkg, exportPaths, options, exportCondition, cwd, { t
|
|
|
795
832
|
freeze: false,
|
|
796
833
|
strict: false,
|
|
797
834
|
sourcemap: options.sourcemap,
|
|
798
|
-
manualChunks:
|
|
835
|
+
manualChunks: createSplitChunks(pluginContext.moduleDirectiveLayerMap),
|
|
799
836
|
chunkFileNames: '[name]-[hash].js',
|
|
800
837
|
// By default in rollup, when creating multiple chunks, transitive imports of entry chunks
|
|
801
838
|
// will be added as empty imports to the entry chunks. Disable to avoid imports hoist outside of boundaries
|
|
@@ -803,56 +840,54 @@ function buildOutputConfigs(pkg, exportPaths, options, exportCondition, cwd, { t
|
|
|
803
840
|
entryFileNames: path.basename(outputFile)
|
|
804
841
|
};
|
|
805
842
|
}
|
|
806
|
-
|
|
807
|
-
async function buildEntryConfig(pkg, entryPath, exportPaths, bundleConfig, cwd, tsOptions, dts) {
|
|
843
|
+
async function buildEntryConfig(entries, pkg, exportPaths, bundleConfig, cwd, tsOptions, pluginContext, dts) {
|
|
808
844
|
const configs = [];
|
|
809
|
-
Object.
|
|
810
|
-
const
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
845
|
+
for (const exportCondition of Object.values(entries)){
|
|
846
|
+
const rollupConfig = buildConfig(entries, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, pluginContext, dts);
|
|
847
|
+
configs.push(rollupConfig);
|
|
848
|
+
}
|
|
849
|
+
return await Promise.all(configs);
|
|
850
|
+
}
|
|
851
|
+
/*
|
|
852
|
+
* build configs for each entry from package exports
|
|
853
|
+
*
|
|
854
|
+
* return { <pkg>/<export>: { input: InputOptions, output: OutputOptions[] }
|
|
855
|
+
*/ async function collectEntries(pkg, entryPath, exportPaths, cwd) {
|
|
856
|
+
const entries = {};
|
|
857
|
+
async function collectEntry(// export type, e.g. react-server, edge-light those special cases required suffix
|
|
858
|
+
exportType, exportCondRef, // export name, e.g. ./<export-path> in exports field of package.json
|
|
859
|
+
entryExport) {
|
|
860
|
+
let exportCondForType = {
|
|
861
|
+
...exportCondRef
|
|
862
|
+
};
|
|
863
|
+
// Special cases of export type, only pass down the exportPaths for the type
|
|
864
|
+
if (availableExportConventions.includes(exportType)) {
|
|
865
|
+
exportCondForType = {
|
|
866
|
+
[entryExport]: exportCondRef[exportType]
|
|
867
|
+
};
|
|
868
|
+
// Basic export type, pass down the exportPaths with erasing the special ones
|
|
869
|
+
} else {
|
|
817
870
|
for (const exportType of availableExportConventions){
|
|
818
|
-
|
|
819
|
-
buildConfigs.push(createBuildConfig(exportType, exportCond));
|
|
820
|
-
}
|
|
871
|
+
delete exportCondForType[exportType];
|
|
821
872
|
}
|
|
822
873
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
if (availableExportConventions.includes(exportType)) {
|
|
829
|
-
exportCondForType = {
|
|
830
|
-
[entryExport]: exportCondRef[exportType]
|
|
831
|
-
};
|
|
832
|
-
// Basic export type, pass down the exportPaths with erasing the special ones
|
|
833
|
-
} else {
|
|
834
|
-
for (const exportType of availableExportConventions){
|
|
835
|
-
delete exportCondForType[exportType];
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
let source = entryPath;
|
|
839
|
-
if (!source) {
|
|
840
|
-
source = await getSourcePathFromExportPath(cwd, entryExport, exportType);
|
|
841
|
-
}
|
|
842
|
-
if (!source) {
|
|
843
|
-
return undefined;
|
|
844
|
-
}
|
|
845
|
-
const exportCondition = {
|
|
846
|
-
source,
|
|
847
|
-
name: entryExport,
|
|
848
|
-
export: exportCondForType
|
|
849
|
-
};
|
|
850
|
-
const entry = resolveSourceFile(cwd, source);
|
|
851
|
-
const rollupConfig = buildConfig(entry, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, dts);
|
|
852
|
-
return rollupConfig;
|
|
874
|
+
let source = entryPath;
|
|
875
|
+
if (source) {
|
|
876
|
+
source = resolveSourceFile(cwd, source);
|
|
877
|
+
} else {
|
|
878
|
+
source = await getSourcePathFromExportPath(cwd, entryExport, exportType);
|
|
853
879
|
}
|
|
854
|
-
|
|
855
|
-
|
|
880
|
+
if (!source) {
|
|
881
|
+
return undefined;
|
|
882
|
+
}
|
|
883
|
+
const exportCondition = {
|
|
884
|
+
source,
|
|
885
|
+
name: entryExport,
|
|
886
|
+
export: exportCondForType
|
|
887
|
+
};
|
|
888
|
+
const entryImportPath = path__default.default.join(pkg.name || '', exportCondition.name) + (exportType ? `.${exportType}` : '');
|
|
889
|
+
entries[entryImportPath] = exportCondition;
|
|
890
|
+
}
|
|
856
891
|
const binaryExports = pkg.bin;
|
|
857
892
|
if (binaryExports) {
|
|
858
893
|
// binDistPaths: [ [ 'bin1', './dist/bin1.js'], [ 'bin2', './dist/bin2.js'] ]
|
|
@@ -883,35 +918,45 @@ async function buildEntryConfig(pkg, entryPath, exportPaths, bundleConfig, cwd,
|
|
|
883
918
|
continue;
|
|
884
919
|
}
|
|
885
920
|
const binEntryPath = await resolveSourceFile(cwd, source);
|
|
886
|
-
|
|
921
|
+
entries[binName] = {
|
|
887
922
|
source: binEntryPath,
|
|
888
923
|
name: binName,
|
|
889
924
|
export: binExportPaths[binName]
|
|
890
|
-
}
|
|
891
|
-
configs.push(binEntryConfig);
|
|
925
|
+
};
|
|
892
926
|
}
|
|
893
927
|
}
|
|
894
|
-
|
|
928
|
+
const collectEntriesPromises = Object.keys(exportPaths).map(async (entryExport)=>{
|
|
929
|
+
const exportCond = exportPaths[entryExport];
|
|
930
|
+
await collectEntry('', exportCond, entryExport);
|
|
931
|
+
for (const exportType of availableExportConventions){
|
|
932
|
+
if (exportCond[exportType]) {
|
|
933
|
+
await collectEntry(exportType, exportCond, entryExport);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
await Promise.all(collectEntriesPromises);
|
|
938
|
+
return entries;
|
|
895
939
|
}
|
|
896
|
-
async function buildConfig(
|
|
940
|
+
async function buildConfig(entries, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, pluginContext, dts) {
|
|
897
941
|
const { file } = bundleConfig;
|
|
898
942
|
const useTypescript = Boolean(tsOptions.tsConfigPath);
|
|
899
943
|
const options = {
|
|
900
944
|
...bundleConfig,
|
|
901
945
|
useTypescript
|
|
902
946
|
};
|
|
903
|
-
const
|
|
947
|
+
const entry = exportCondition.source;
|
|
948
|
+
const inputOptions = await buildInputConfig(entry, entries, pkg, options, cwd, tsOptions, pluginContext, dts);
|
|
904
949
|
const outputExports = getExportConditionDist(pkg, exportCondition, cwd);
|
|
905
950
|
let outputConfigs = [];
|
|
906
951
|
// Generate dts job - single config
|
|
907
952
|
if (dts) {
|
|
908
953
|
const typeOutputExports = getExportTypeDist(exportCondition, cwd);
|
|
909
|
-
outputConfigs = typeOutputExports.map((
|
|
954
|
+
outputConfigs = typeOutputExports.map((typeFile)=>buildOutputConfigs(pkg, exportPaths, {
|
|
910
955
|
...bundleConfig,
|
|
911
956
|
format: 'es',
|
|
912
957
|
useTypescript,
|
|
913
|
-
file:
|
|
914
|
-
}, exportCondition, cwd, tsOptions, dts));
|
|
958
|
+
file: typeFile
|
|
959
|
+
}, exportCondition, cwd, tsOptions, pluginContext, dts));
|
|
915
960
|
} else {
|
|
916
961
|
// multi outputs with specified format
|
|
917
962
|
outputConfigs = outputExports.map((exportDist)=>{
|
|
@@ -920,7 +965,7 @@ async function buildConfig(entry, pkg, exportPaths, bundleConfig, exportConditio
|
|
|
920
965
|
file: exportDist.file,
|
|
921
966
|
format: exportDist.format,
|
|
922
967
|
useTypescript
|
|
923
|
-
}, exportCondition, cwd, tsOptions, dts);
|
|
968
|
+
}, exportCondition, cwd, tsOptions, pluginContext, dts);
|
|
924
969
|
});
|
|
925
970
|
// CLI output option is always prioritized
|
|
926
971
|
if (file) {
|
|
@@ -932,7 +977,7 @@ async function buildConfig(entry, pkg, exportPaths, bundleConfig, exportConditio
|
|
|
932
977
|
file,
|
|
933
978
|
format: bundleConfig.format || fallbackFormat,
|
|
934
979
|
useTypescript
|
|
935
|
-
}, exportCondition, cwd, tsOptions, dts)
|
|
980
|
+
}, exportCondition, cwd, tsOptions, pluginContext, dts)
|
|
936
981
|
];
|
|
937
982
|
}
|
|
938
983
|
}
|
|
@@ -943,6 +988,72 @@ async function buildConfig(entry, pkg, exportPaths, bundleConfig, exportConditio
|
|
|
943
988
|
};
|
|
944
989
|
}
|
|
945
990
|
|
|
991
|
+
function createChunkSizeCollector({ entries }) {
|
|
992
|
+
const sizeStats = new Map();
|
|
993
|
+
function addSize({ fileName, size, sourceFileName, exportPath }) {
|
|
994
|
+
if (!sizeStats.has(exportPath)) {
|
|
995
|
+
sizeStats.set(exportPath, []);
|
|
996
|
+
}
|
|
997
|
+
const distFilesStats = sizeStats.get(exportPath);
|
|
998
|
+
if (distFilesStats) {
|
|
999
|
+
distFilesStats.push([
|
|
1000
|
+
fileName,
|
|
1001
|
+
sourceFileName,
|
|
1002
|
+
size
|
|
1003
|
+
]);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
const reversedMapping = new Map();
|
|
1007
|
+
Object.entries(entries).forEach(([, entry])=>{
|
|
1008
|
+
reversedMapping.set(entry.source, entry.name || '.');
|
|
1009
|
+
});
|
|
1010
|
+
return {
|
|
1011
|
+
plugin: (cwd)=>{
|
|
1012
|
+
return {
|
|
1013
|
+
name: 'collect-sizes',
|
|
1014
|
+
augmentChunkHash () {
|
|
1015
|
+
// Do nothing, but use the hook to keep the plugin instance alive
|
|
1016
|
+
},
|
|
1017
|
+
renderChunk (code, chunk, options) {
|
|
1018
|
+
const sourceId = chunk.facadeModuleId || '';
|
|
1019
|
+
const dir = options.dir || options.file && path__default.default.dirname(options.file);
|
|
1020
|
+
let fileName = chunk.fileName;
|
|
1021
|
+
if (dir) {
|
|
1022
|
+
const filePath = path__default.default.join(dir, fileName);
|
|
1023
|
+
fileName = filePath.startsWith(cwd) ? path__default.default.relative(cwd, filePath) : filePath;
|
|
1024
|
+
}
|
|
1025
|
+
addSize({
|
|
1026
|
+
fileName,
|
|
1027
|
+
size: code.length,
|
|
1028
|
+
sourceFileName: sourceId,
|
|
1029
|
+
exportPath: reversedMapping.get(sourceId) || '.'
|
|
1030
|
+
});
|
|
1031
|
+
return null;
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
},
|
|
1035
|
+
getSizeStats () {
|
|
1036
|
+
return sizeStats;
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
function logSizeStats(sizeCollector) {
|
|
1041
|
+
const stats = sizeCollector.getSizeStats();
|
|
1042
|
+
const allFileNameLengths = Array.from(stats.values()).flat(1).map(([filename])=>filename.length);
|
|
1043
|
+
const maxLength = Math.max(...allFileNameLengths);
|
|
1044
|
+
[
|
|
1045
|
+
...stats.entries()
|
|
1046
|
+
].sort(([a], [b])=>a.length - b.length).forEach(([, filesList])=>{
|
|
1047
|
+
filesList.forEach((item)=>{
|
|
1048
|
+
const [filename, , size] = item;
|
|
1049
|
+
const padding = ' '.repeat(maxLength - filename.length);
|
|
1050
|
+
const action = dtsExtensionRegex.test(filename) ? 'Typed' : 'Built';
|
|
1051
|
+
const prettiedSize = prettyBytes__default.default(size);
|
|
1052
|
+
logger.info(`${action} ${filename}${padding} - ${prettiedSize}`);
|
|
1053
|
+
});
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
|
|
946
1057
|
let hasLoggedTsWarning = false;
|
|
947
1058
|
function resolveTypescript(cwd) {
|
|
948
1059
|
let ts;
|
|
@@ -1107,15 +1218,22 @@ async function bundle(entryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1107
1218
|
err.name = 'NOT_EXISTED';
|
|
1108
1219
|
return Promise.reject(err);
|
|
1109
1220
|
}
|
|
1110
|
-
|
|
1111
|
-
const
|
|
1221
|
+
const entries = await collectEntries(pkg, entryPath, exportPaths, cwd);
|
|
1222
|
+
const sizeCollector = createChunkSizeCollector({
|
|
1223
|
+
entries
|
|
1224
|
+
});
|
|
1225
|
+
const pluginContext = {
|
|
1226
|
+
sizeCollector,
|
|
1227
|
+
moduleDirectiveLayerMap: new Map()
|
|
1228
|
+
};
|
|
1229
|
+
const buildConfigs = await buildEntryConfig(entries, pkg, exportPaths, options, cwd, defaultTsOptions, pluginContext, false);
|
|
1112
1230
|
const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
|
|
1113
|
-
const typesJobs = hasTsConfig ? (await buildEntryConfig(
|
|
1114
|
-
result = await Promise.all(assetsJobs.concat(typesJobs));
|
|
1231
|
+
const typesJobs = hasTsConfig ? (await buildEntryConfig(entries, pkg, exportPaths, options, cwd, defaultTsOptions, pluginContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
|
|
1232
|
+
const result = await Promise.all(assetsJobs.concat(typesJobs));
|
|
1115
1233
|
if (result.length === 0) {
|
|
1116
1234
|
logger.warn('The "src" directory does not contain any entry files. ' + 'For proper usage, please refer to the following link: ' + 'https://github.com/huozhi/bunchee#usage');
|
|
1117
1235
|
}
|
|
1118
|
-
logSizeStats();
|
|
1236
|
+
logSizeStats(sizeCollector);
|
|
1119
1237
|
return result;
|
|
1120
1238
|
}
|
|
1121
1239
|
function runWatch({ input, output }, metadata) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bunchee",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.1",
|
|
4
4
|
"description": "zero config bundler for js/ts/jsx libraries",
|
|
5
5
|
"bin": "./dist/bin/cli.js",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
49
49
|
"@rollup/plugin-esm-shim": "^0.1.5",
|
|
50
|
-
"@rollup/plugin-json": "^6.0
|
|
50
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
51
51
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
52
52
|
"@rollup/plugin-replace": "^5.0.5",
|
|
53
53
|
"@rollup/plugin-wasm": "^6.2.2",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"@swc/helpers": "^0.5.3",
|
|
57
57
|
"arg": "^5.0.2",
|
|
58
58
|
"pretty-bytes": "^5.6.0",
|
|
59
|
-
"publint": "~0.2.
|
|
60
|
-
"rollup": "^4.
|
|
59
|
+
"publint": "~0.2.7",
|
|
60
|
+
"rollup": "^4.9.1",
|
|
61
61
|
"rollup-plugin-dts": "^6.1.0",
|
|
62
62
|
"rollup-plugin-swc3": "^0.11.0",
|
|
63
63
|
"rollup-preserve-directives": "^1.1.0",
|
|
@@ -86,7 +86,8 @@
|
|
|
86
86
|
"prettier": "^3.0.0",
|
|
87
87
|
"react": "^18.2.0",
|
|
88
88
|
"tsx": "^4.6.2",
|
|
89
|
-
"typescript": "^5.3.2"
|
|
89
|
+
"typescript": "^5.3.2",
|
|
90
|
+
"bunchee": "link:./"
|
|
90
91
|
},
|
|
91
92
|
"lint-staged": {
|
|
92
93
|
"*.{ts,tsx,js,jsx,md,json,yml}": "prettier --write"
|