bunchee 4.4.8 → 5.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -56
- package/dist/bin/cli.js +325 -317
- package/dist/index.js +524 -533
- package/package.json +14 -16
- package/dist/bin/cli.d.ts +0 -1
package/dist/bin/cli.js
CHANGED
|
@@ -26,13 +26,19 @@ const availableExtensions = new Set([
|
|
|
26
26
|
'cts',
|
|
27
27
|
'mts'
|
|
28
28
|
]);
|
|
29
|
-
const
|
|
29
|
+
const runtimeExportConventions = new Set([
|
|
30
30
|
'react-server',
|
|
31
31
|
'react-native',
|
|
32
|
-
'edge-light'
|
|
32
|
+
'edge-light'
|
|
33
|
+
]);
|
|
34
|
+
const optimizeConventions = new Set([
|
|
33
35
|
'development',
|
|
34
36
|
'production'
|
|
35
37
|
]);
|
|
38
|
+
const specialExportConventions = new Set([
|
|
39
|
+
...runtimeExportConventions,
|
|
40
|
+
...optimizeConventions
|
|
41
|
+
]);
|
|
36
42
|
const SRC = 'src';
|
|
37
43
|
const DIST = 'dist';
|
|
38
44
|
const dtsExtensionsMap = {
|
|
@@ -52,6 +58,7 @@ const DEFAULT_TS_CONFIG = {
|
|
|
52
58
|
moduleResolution: 'bundler'
|
|
53
59
|
}
|
|
54
60
|
};
|
|
61
|
+
const BINARY_TAG = '$binary';
|
|
55
62
|
|
|
56
63
|
function getDefaultExportFromCjs (x) {
|
|
57
64
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -158,256 +165,147 @@ function fileExists(filePath) {
|
|
|
158
165
|
}
|
|
159
166
|
const hasAvailableExtension = (filename)=>availableExtensions.has(path__default.default.extname(filename).slice(1));
|
|
160
167
|
const hasCjsExtension = (filename)=>path__default.default.extname(filename) === '.cjs';
|
|
168
|
+
const getMainFieldExportType = (pkg)=>{
|
|
169
|
+
const isEsmPkg = isESModulePackage(pkg.type);
|
|
170
|
+
const mainExportType = isEsmPkg && pkg.main ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
|
|
171
|
+
return mainExportType;
|
|
172
|
+
};
|
|
161
173
|
// TODO: add unit test
|
|
162
174
|
const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
|
|
163
175
|
const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
|
|
164
|
-
|
|
165
|
-
function getPackageTypings(pkg) {
|
|
166
|
-
return pkg.types || pkg.typings;
|
|
167
|
-
}
|
|
168
|
-
// Reached the end of the export path
|
|
169
|
-
function isExportLike(field) {
|
|
170
|
-
if (typeof field === 'string') return true;
|
|
171
|
-
return Object.entries(field).every(// Every value is string and key is not start with '.'
|
|
172
|
-
([key, value])=>typeof value === 'string' && !key.startsWith('.'));
|
|
173
|
-
}
|
|
174
|
-
function constructFullExportCondition(exportCondition, packageType) {
|
|
175
|
-
let fullExportCond;
|
|
176
|
-
if (typeof exportCondition === 'string') {
|
|
177
|
-
const exportType = getExportTypeFromFile(exportCondition, packageType);
|
|
178
|
-
fullExportCond = {
|
|
179
|
-
[exportType]: exportCondition
|
|
180
|
-
};
|
|
181
|
-
} else {
|
|
182
|
-
const exportTypes = Object.keys(exportCondition);
|
|
183
|
-
fullExportCond = {};
|
|
184
|
-
exportTypes.forEach((exportType)=>{
|
|
185
|
-
const condition = exportCondition[exportType];
|
|
186
|
-
// Filter out nullable value
|
|
187
|
-
if (condition) {
|
|
188
|
-
fullExportCond[exportType] = condition;
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
return fullExportCond;
|
|
193
|
-
}
|
|
194
176
|
function joinRelativePath(...segments) {
|
|
195
|
-
let result =
|
|
177
|
+
let result = path__default.default.join(...segments);
|
|
196
178
|
// If the first segment starts with '.', ensure the result does too.
|
|
197
179
|
if (segments[0] === '.' && !result.startsWith('.')) {
|
|
198
180
|
result = './' + result;
|
|
199
181
|
}
|
|
200
182
|
return result;
|
|
201
183
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if (exportPath.startsWith('.')) {
|
|
223
|
-
paths[exportPath] = {
|
|
224
|
-
...paths[exportPath],
|
|
225
|
-
...fullExportCondition
|
|
226
|
-
};
|
|
184
|
+
function isESModulePackage(packageType) {
|
|
185
|
+
return packageType === 'module';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exportToDist) {
|
|
189
|
+
// End of searching, export value is file path.
|
|
190
|
+
// <export key>: <export value> (string)
|
|
191
|
+
if (typeof exportValue === 'string') {
|
|
192
|
+
const composedTypes = new Set(exportTypes);
|
|
193
|
+
composedTypes.add(exportKey.startsWith('.') ? 'default' : exportKey);
|
|
194
|
+
const exportInfo = exportToDist.get(currentPath);
|
|
195
|
+
const exportCondition = Array.from(composedTypes).join('.');
|
|
196
|
+
if (!exportInfo) {
|
|
197
|
+
const outputConditionPair = [
|
|
198
|
+
exportValue,
|
|
199
|
+
exportCondition
|
|
200
|
+
];
|
|
201
|
+
exportToDist.set(currentPath, [
|
|
202
|
+
outputConditionPair
|
|
203
|
+
]);
|
|
227
204
|
} else {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
...paths[specialPath],
|
|
233
|
-
...exportCondition
|
|
234
|
-
};
|
|
235
|
-
} else {
|
|
236
|
-
// exportPath is exportType, import, require, ...
|
|
237
|
-
// merge to currentPath
|
|
238
|
-
paths[currentPath] = {
|
|
239
|
-
...paths[currentPath],
|
|
240
|
-
[exportPath]: exportJsBundlePath
|
|
241
|
-
};
|
|
242
|
-
}
|
|
205
|
+
exportInfo.push([
|
|
206
|
+
exportValue,
|
|
207
|
+
exportCondition
|
|
208
|
+
]);
|
|
243
209
|
}
|
|
244
210
|
return;
|
|
245
211
|
}
|
|
246
|
-
Object.keys(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
const defaultPath = exportCondition[subpath].default;
|
|
257
|
-
if (defaultPath) {
|
|
258
|
-
const nestedExportCondition = {
|
|
259
|
-
[exportType]: defaultPath
|
|
260
|
-
};
|
|
261
|
-
findExport(exportPath, nestedExportCondition, paths, packageType, currentPath);
|
|
262
|
-
}
|
|
263
|
-
// Find special export type, such as import: { development: './dev.js', production: './prod.js' }
|
|
264
|
-
const conditionSpecialTypes = Object.keys(exportCondition[exportType]).filter((key)=>suffixedExportConventions.has(key));
|
|
265
|
-
if (conditionSpecialTypes.length > 0) {
|
|
266
|
-
for (const conditionSpecialType of conditionSpecialTypes){
|
|
267
|
-
const nestedExportConditionPath = {
|
|
268
|
-
[exportType]: exportCondition[exportType][conditionSpecialType]
|
|
269
|
-
};
|
|
270
|
-
findExport(conditionSpecialType, nestedExportConditionPath, paths, packageType, currentPath);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
const defaultPath = typeof exportCondition[subpath] === 'object' ? exportCondition[subpath].default : exportCondition[subpath];
|
|
275
|
-
const nestedExportCondition = {
|
|
276
|
-
[exportType]: defaultPath
|
|
277
|
-
};
|
|
278
|
-
findExport(exportPath, nestedExportCondition, paths, packageType, currentPath);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
*
|
|
284
|
-
* Convert package.exports field to paths mapping
|
|
285
|
-
* Example
|
|
286
|
-
*
|
|
287
|
-
* Input:
|
|
288
|
-
* {
|
|
289
|
-
* "./sub": {
|
|
290
|
-
* "import": {
|
|
291
|
-
* "types": "./sub.js",
|
|
292
|
-
* "default": "./sub.cjs",
|
|
293
|
-
* }
|
|
294
|
-
* }
|
|
295
|
-
* }
|
|
296
|
-
*
|
|
297
|
-
* Output:
|
|
298
|
-
* {
|
|
299
|
-
* "./sub": {
|
|
300
|
-
* "import": "./sub.js",
|
|
301
|
-
* "require": "./sub.cjs",
|
|
302
|
-
* "types": "./sub.d.ts",
|
|
303
|
-
* }
|
|
304
|
-
* }
|
|
305
|
-
*
|
|
306
|
-
*/ function parseExport(exportsCondition, packageType) {
|
|
307
|
-
const paths = {};
|
|
308
|
-
const initialPath = '.';
|
|
309
|
-
if (typeof exportsCondition === 'string') {
|
|
310
|
-
paths[initialPath] = constructFullExportCondition(exportsCondition, packageType);
|
|
311
|
-
} else if (typeof exportsCondition === 'object') {
|
|
312
|
-
if (isExportLike(exportsCondition)) {
|
|
313
|
-
paths[initialPath] = constructFullExportCondition(exportsCondition, packageType);
|
|
212
|
+
const exportKeys = Object.keys(exportValue);
|
|
213
|
+
for (const exportKey of exportKeys){
|
|
214
|
+
// Clone the set to avoid modifying the parent set
|
|
215
|
+
const childExports = new Set(exportTypes);
|
|
216
|
+
// Normalize child export value to a map
|
|
217
|
+
const childExportValue = exportValue[exportKey];
|
|
218
|
+
// Visit export path: ./subpath, ./subpath2, ...
|
|
219
|
+
if (exportKey.startsWith('.')) {
|
|
220
|
+
const childPath = joinRelativePath(currentPath, exportKey);
|
|
221
|
+
collectExportPath(childExportValue, exportKey, childPath, childExports, exportToDist);
|
|
314
222
|
} else {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
});
|
|
223
|
+
// Visit export type: import, require, ...
|
|
224
|
+
childExports.add(exportKey);
|
|
225
|
+
collectExportPath(childExportValue, exportKey, currentPath, childExports, exportToDist);
|
|
319
226
|
}
|
|
320
227
|
}
|
|
321
|
-
return paths;
|
|
322
228
|
}
|
|
323
229
|
/**
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* Example:
|
|
327
|
-
*
|
|
328
|
-
* ```json
|
|
329
|
-
* {
|
|
330
|
-
* "exports": {
|
|
331
|
-
* ".": {
|
|
332
|
-
* "require": "./dist/index.cjs",
|
|
333
|
-
* "module": "./dist/index.esm.js",
|
|
334
|
-
* "default": "./dist/index.esm.js"
|
|
335
|
-
* },
|
|
336
|
-
* "./foo": {
|
|
337
|
-
* "require": "./dist/foo.cjs",
|
|
338
|
-
* "module": "./dist/foo.esm.js",
|
|
339
|
-
* "default": "./dist/foo.esm.js"
|
|
340
|
-
* }
|
|
341
|
-
* }
|
|
342
|
-
*
|
|
343
|
-
* ```
|
|
230
|
+
* parseExports - parse package.exports field and other fields like main,module to a map
|
|
344
231
|
*
|
|
345
|
-
*
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
let mainExportCondition;
|
|
377
|
-
if (pkg.main) {
|
|
378
|
-
const mainExportType = isEsmPackage ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
|
|
379
|
-
mainExportCondition = {
|
|
380
|
-
[mainExportType]: pkg.main
|
|
381
|
-
};
|
|
232
|
+
* map from export path to output path and export conditions
|
|
233
|
+
*/ function parseExports(pkg) {
|
|
234
|
+
var _pkg_exports;
|
|
235
|
+
const exportsField = (_pkg_exports = pkg.exports) != null ? _pkg_exports : {};
|
|
236
|
+
var _pkg_bin;
|
|
237
|
+
const bins = (_pkg_bin = pkg.bin) != null ? _pkg_bin : {};
|
|
238
|
+
const exportToDist = new Map();
|
|
239
|
+
const isEsmPkg = isESModulePackage(pkg.type);
|
|
240
|
+
const defaultCondition = isEsmPkg ? 'import' : 'require';
|
|
241
|
+
let currentPath = '.';
|
|
242
|
+
if (typeof exportsField === 'string') {
|
|
243
|
+
const outputConditionPair = [
|
|
244
|
+
exportsField,
|
|
245
|
+
defaultCondition
|
|
246
|
+
];
|
|
247
|
+
exportToDist.set(currentPath, [
|
|
248
|
+
outputConditionPair
|
|
249
|
+
]);
|
|
250
|
+
} else {
|
|
251
|
+
// keys means unknown if they're relative path or export type
|
|
252
|
+
const exportConditionKeys = Object.keys(exportsField);
|
|
253
|
+
for (const exportKey of exportConditionKeys){
|
|
254
|
+
const exportValue = exportsField[exportKey];
|
|
255
|
+
const exportTypes = new Set();
|
|
256
|
+
const isExportPath = exportKey.startsWith('.');
|
|
257
|
+
const childPath = isExportPath ? joinRelativePath(currentPath, exportKey) : currentPath;
|
|
258
|
+
if (!isExportPath) {
|
|
259
|
+
exportTypes.add(exportKey);
|
|
260
|
+
}
|
|
261
|
+
collectExportPath(exportValue, exportKey, childPath, exportTypes, exportToDist);
|
|
262
|
+
}
|
|
382
263
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
264
|
+
if (typeof bins === 'string') {
|
|
265
|
+
const outputConditionPair = [
|
|
266
|
+
bins,
|
|
267
|
+
defaultCondition
|
|
268
|
+
];
|
|
269
|
+
exportToDist.set(BINARY_TAG, [
|
|
270
|
+
outputConditionPair
|
|
271
|
+
]);
|
|
272
|
+
} else {
|
|
273
|
+
for (const binName of Object.keys(bins)){
|
|
274
|
+
const binDistPath = bins[binName];
|
|
275
|
+
const exportType = getExportTypeFromFile(binDistPath, pkg.type);
|
|
276
|
+
const exportPath = path.posix.join(BINARY_TAG, binName);
|
|
277
|
+
const outputConditionPair = [
|
|
278
|
+
binDistPath,
|
|
279
|
+
exportType
|
|
280
|
+
];
|
|
281
|
+
exportToDist.set(exportPath, [
|
|
282
|
+
outputConditionPair
|
|
283
|
+
]);
|
|
284
|
+
}
|
|
403
285
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
286
|
+
// Handle package.json global exports fields
|
|
287
|
+
if (pkg.main || pkg.module || pkg.types) {
|
|
288
|
+
const mainExportPath = pkg.main;
|
|
289
|
+
const moduleExportPath = pkg.module;
|
|
290
|
+
const typesEntryPath = pkg.types;
|
|
291
|
+
const existingExportInfo = exportToDist.get('.');
|
|
292
|
+
exportToDist.set('.', [
|
|
293
|
+
...existingExportInfo || [],
|
|
294
|
+
Boolean(mainExportPath) && [
|
|
295
|
+
mainExportPath,
|
|
296
|
+
getMainFieldExportType(pkg)
|
|
297
|
+
],
|
|
298
|
+
Boolean(moduleExportPath) && [
|
|
299
|
+
moduleExportPath,
|
|
300
|
+
'import'
|
|
301
|
+
],
|
|
302
|
+
Boolean(typesEntryPath) && [
|
|
303
|
+
typesEntryPath,
|
|
304
|
+
'types'
|
|
305
|
+
]
|
|
306
|
+
].filter(Boolean));
|
|
307
|
+
}
|
|
308
|
+
return exportToDist;
|
|
411
309
|
}
|
|
412
310
|
function getExportTypeFromFile(filename, pkgType) {
|
|
413
311
|
const isESModule = isESModulePackage(pkgType);
|
|
@@ -420,7 +318,7 @@ function getExportTypeFromFile(filename, pkgType) {
|
|
|
420
318
|
function lint$1(pkg) {
|
|
421
319
|
const { name, main, exports } = pkg;
|
|
422
320
|
const isESM = isESModulePackage(pkg.type);
|
|
423
|
-
const
|
|
321
|
+
const parsedExports = parseExports(pkg);
|
|
424
322
|
if (!name) {
|
|
425
323
|
logger.warn('Missing package name');
|
|
426
324
|
}
|
|
@@ -456,16 +354,17 @@ function lint$1(pkg) {
|
|
|
456
354
|
if (typeof exports !== 'object') {
|
|
457
355
|
state.invalidExportsFieldType = true;
|
|
458
356
|
} else {
|
|
459
|
-
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
357
|
+
parsedExports.forEach((outputPairs)=>{
|
|
358
|
+
for (const [outputPath, composedExportType] of outputPairs){
|
|
359
|
+
const exportTypes = new Set(composedExportType.split('.'));
|
|
360
|
+
let requirePath = '';
|
|
361
|
+
let importPath = '';
|
|
362
|
+
if (exportTypes.has('require')) {
|
|
363
|
+
requirePath = outputPath;
|
|
364
|
+
}
|
|
365
|
+
if (exportTypes.has('import')) {
|
|
366
|
+
importPath = outputPath;
|
|
367
|
+
}
|
|
469
368
|
const requireExt = requirePath && path__default.default.extname(requirePath);
|
|
470
369
|
const importExt = importPath && path__default.default.extname(importPath);
|
|
471
370
|
if (requireExt === '.mjs' || requireExt === '.js') {
|
|
@@ -494,16 +393,17 @@ function lint$1(pkg) {
|
|
|
494
393
|
if (typeof exports !== 'object') {
|
|
495
394
|
state.invalidExportsFieldType = true;
|
|
496
395
|
} else {
|
|
497
|
-
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
396
|
+
parsedExports.forEach((outputPairs)=>{
|
|
397
|
+
for (const [outputPath, composedExportType] of outputPairs){
|
|
398
|
+
const exportTypes = new Set(composedExportType.split('.'));
|
|
399
|
+
let requirePath = '';
|
|
400
|
+
let importPath = '';
|
|
401
|
+
if (exportTypes.has('require')) {
|
|
402
|
+
requirePath = outputPath;
|
|
403
|
+
}
|
|
404
|
+
if (exportTypes.has('import')) {
|
|
405
|
+
importPath = outputPath;
|
|
406
|
+
}
|
|
507
407
|
const requireExt = requirePath && path__default.default.extname(requirePath);
|
|
508
408
|
const importExt = importPath && path__default.default.extname(importPath);
|
|
509
409
|
if (requireExt === '.mjs') {
|
|
@@ -558,7 +458,7 @@ function lint$1(pkg) {
|
|
|
558
458
|
}
|
|
559
459
|
}
|
|
560
460
|
|
|
561
|
-
var version = "
|
|
461
|
+
var version = "5.0.0-beta.2";
|
|
562
462
|
|
|
563
463
|
function relativify(path) {
|
|
564
464
|
return path.startsWith('.') ? path : `./${path}`;
|
|
@@ -569,41 +469,73 @@ async function writeDefaultTsconfig(tsConfigPath) {
|
|
|
569
469
|
logger.log(`Detected using TypeScript but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
|
|
570
470
|
}
|
|
571
471
|
|
|
572
|
-
//
|
|
573
|
-
|
|
574
|
-
|
|
472
|
+
// shared.ts -> ./shared
|
|
473
|
+
// shared.<export condition>.ts -> ./shared
|
|
474
|
+
// index.ts -> ./index
|
|
475
|
+
// index.development.ts -> ./index.development
|
|
476
|
+
function sourceFilenameToExportPath(filename) {
|
|
477
|
+
const baseName = baseNameWithoutExtension(filename);
|
|
478
|
+
let exportPath = baseName;
|
|
479
|
+
return relativify(exportPath);
|
|
575
480
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
function
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
481
|
+
// ./index -> import|require|default
|
|
482
|
+
// ./index.development -> development
|
|
483
|
+
// ./index.react-server -> react-server
|
|
484
|
+
function getExportTypeFromExportPath(exportPath) {
|
|
485
|
+
// Skip the first two segments: `.` and `index`
|
|
486
|
+
const exportTypes = exportPath.split('.').slice(2);
|
|
487
|
+
return getExportTypeFromExportTypes(exportTypes);
|
|
488
|
+
}
|
|
489
|
+
function getSpecialExportTypeFromExportPath(composedExportType) {
|
|
490
|
+
const exportTypes = composedExportType.split('.');
|
|
491
|
+
for (const exportType of exportTypes){
|
|
492
|
+
if (specialExportConventions.has(exportType)) {
|
|
493
|
+
return exportType;
|
|
494
|
+
}
|
|
586
495
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
496
|
+
return 'default';
|
|
497
|
+
}
|
|
498
|
+
function getExportTypeFromExportTypes(types) {
|
|
499
|
+
let exportType = 'default';
|
|
500
|
+
new Set(types).forEach((value)=>{
|
|
501
|
+
if (specialExportConventions.has(value)) {
|
|
502
|
+
exportType = value;
|
|
503
|
+
} else if (value === 'import' || value === 'require' || value === 'types') {
|
|
504
|
+
exportType = value;
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
return exportType;
|
|
508
|
+
}
|
|
509
|
+
// ./index -> .
|
|
510
|
+
// ./index.development -> .
|
|
511
|
+
// ./index.react-server -> .
|
|
512
|
+
// ./shared -> ./shared
|
|
513
|
+
// ./shared.development -> ./shared
|
|
514
|
+
// $binary -> $binary
|
|
515
|
+
// $binary/index -> $binary
|
|
516
|
+
// $binary/foo -> $binary/foo
|
|
517
|
+
function normalizeExportPath(exportPath) {
|
|
518
|
+
if (exportPath.startsWith(BINARY_TAG)) {
|
|
519
|
+
if (exportPath === `${BINARY_TAG}/index`) {
|
|
520
|
+
exportPath = BINARY_TAG;
|
|
521
|
+
}
|
|
522
|
+
return exportPath;
|
|
598
523
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
}
|
|
524
|
+
const baseName = exportPath.split('.').slice(0, 2).join('.');
|
|
525
|
+
if (baseName === './index') {
|
|
526
|
+
return '.';
|
|
527
|
+
}
|
|
528
|
+
return baseName;
|
|
603
529
|
}
|
|
604
530
|
async function collectSourceEntries(sourceFolderPath) {
|
|
605
531
|
const bins = new Map();
|
|
606
532
|
const exportsEntries = new Map();
|
|
533
|
+
if (!fs__default.default.existsSync(sourceFolderPath)) {
|
|
534
|
+
return {
|
|
535
|
+
bins,
|
|
536
|
+
exportsEntries
|
|
537
|
+
};
|
|
538
|
+
}
|
|
607
539
|
const entryFileDirentList = await fsp__default.default.readdir(sourceFolderPath, {
|
|
608
540
|
withFileTypes: true
|
|
609
541
|
});
|
|
@@ -616,18 +548,35 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
616
548
|
for (const binDirent of binDirentList){
|
|
617
549
|
if (binDirent.isFile()) {
|
|
618
550
|
const binFileAbsolutePath = path__default.default.join(sourceFolderPath, dirent.name, binDirent.name);
|
|
619
|
-
const
|
|
551
|
+
const binExportPath = sourceFilenameToExportPath(binDirent.name);
|
|
620
552
|
if (fs__default.default.existsSync(binFileAbsolutePath)) {
|
|
621
|
-
bins.set(
|
|
553
|
+
bins.set(path.posix.join(BINARY_TAG, binExportPath), binFileAbsolutePath);
|
|
622
554
|
}
|
|
623
555
|
}
|
|
624
556
|
}
|
|
625
557
|
} else {
|
|
626
|
-
// Search folder
|
|
558
|
+
// Search folder/index.<ext> convention entries
|
|
627
559
|
for (const extension of availableExtensions){
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
560
|
+
const indexAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${extension}`);
|
|
561
|
+
// Search folder/index.<special type>.<ext> convention entries
|
|
562
|
+
for (const specialExportType of runtimeExportConventions){
|
|
563
|
+
const indexSpecialAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${specialExportType}.${extension}`);
|
|
564
|
+
if (fs__default.default.existsSync(indexSpecialAbsoluteFile)) {
|
|
565
|
+
// Add special export path
|
|
566
|
+
// { ./<export path>.<special cond>: { <special cond>: 'index.<special cond>.<ext>' } }
|
|
567
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
568
|
+
const specialExportPath = exportPath + '.' + specialExportType;
|
|
569
|
+
const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
|
|
570
|
+
sourceFilesMap[specialExportType] = indexSpecialAbsoluteFile;
|
|
571
|
+
exportsEntries.set(specialExportPath, sourceFilesMap);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
if (fs__default.default.existsSync(indexAbsoluteFile) && !isTestFile(indexAbsoluteFile)) {
|
|
575
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
576
|
+
const sourceFilesMap = exportsEntries.get(exportPath) || {};
|
|
577
|
+
const exportType = getExportTypeFromExportPath(exportPath);
|
|
578
|
+
sourceFilesMap[exportType] = indexAbsoluteFile;
|
|
579
|
+
exportsEntries.set(exportPath, sourceFilesMap);
|
|
631
580
|
break;
|
|
632
581
|
}
|
|
633
582
|
}
|
|
@@ -635,13 +584,17 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
635
584
|
} else if (dirent.isFile()) {
|
|
636
585
|
const isAvailableExtension = availableExtensions.has(path__default.default.extname(dirent.name).slice(1));
|
|
637
586
|
if (isAvailableExtension) {
|
|
638
|
-
const
|
|
639
|
-
const isBinFile =
|
|
587
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
588
|
+
const isBinFile = exportPath === './bin';
|
|
589
|
+
const fullPath = path__default.default.join(sourceFolderPath, dirent.name);
|
|
640
590
|
if (isBinFile) {
|
|
641
|
-
bins.set(
|
|
591
|
+
bins.set(BINARY_TAG, fullPath);
|
|
642
592
|
} else {
|
|
643
593
|
if (hasAvailableExtension(dirent.name) && !isTestFile(dirent.name)) {
|
|
644
|
-
exportsEntries.
|
|
594
|
+
const sourceFilesMap = exportsEntries.get(exportPath) || {};
|
|
595
|
+
const exportType = getExportTypeFromExportPath(exportPath);
|
|
596
|
+
sourceFilesMap[exportType] = fullPath;
|
|
597
|
+
exportsEntries.set(exportPath, sourceFilesMap);
|
|
645
598
|
}
|
|
646
599
|
}
|
|
647
600
|
}
|
|
@@ -652,25 +605,68 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
652
605
|
exportsEntries
|
|
653
606
|
};
|
|
654
607
|
}
|
|
608
|
+
|
|
609
|
+
// Output with posix style in package.json
|
|
610
|
+
function getDistPath(...subPaths) {
|
|
611
|
+
return relativify(path.posix.join(DIST, ...subPaths));
|
|
612
|
+
}
|
|
613
|
+
function stripeBinaryTag(exportName) {
|
|
614
|
+
// Add \ to decode leading $
|
|
615
|
+
return exportName.replace(/\$binary\//, '');
|
|
616
|
+
}
|
|
617
|
+
const normalizeBaseNameToExportName = (name)=>{
|
|
618
|
+
const baseName = stripeBinaryTag(name);
|
|
619
|
+
return /^\.\/index(\.|$)/.test(baseName) ? '.' : relativify(baseName);
|
|
620
|
+
};
|
|
621
|
+
function createExportCondition(exportName, sourceFile, moduleType) {
|
|
622
|
+
const isTsSourceFile = isTypescriptFile(sourceFile);
|
|
623
|
+
let cjsExtension = 'js';
|
|
624
|
+
let esmExtension = 'mjs';
|
|
625
|
+
if (moduleType === 'module') {
|
|
626
|
+
cjsExtension = 'cjs';
|
|
627
|
+
esmExtension = 'js';
|
|
628
|
+
}
|
|
629
|
+
if (exportName === '.') {
|
|
630
|
+
exportName = 'index';
|
|
631
|
+
}
|
|
632
|
+
if (isTsSourceFile) {
|
|
633
|
+
return {
|
|
634
|
+
import: {
|
|
635
|
+
types: getDistPath('es', `${exportName}.${dtsExtensionsMap[esmExtension]}`),
|
|
636
|
+
default: getDistPath('es', `${exportName}.${esmExtension}`)
|
|
637
|
+
},
|
|
638
|
+
require: {
|
|
639
|
+
types: getDistPath('cjs', `${exportName}.${dtsExtensionsMap[cjsExtension]}`),
|
|
640
|
+
default: getDistPath('cjs', `${exportName}.${cjsExtension}`)
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
return {
|
|
645
|
+
import: getDistPath(`${exportName}.mjs`),
|
|
646
|
+
require: getDistPath(`${exportName}.${cjsExtension}`)
|
|
647
|
+
};
|
|
648
|
+
}
|
|
655
649
|
function createExportConditionPair(exportName, sourceFile, moduleType) {
|
|
656
650
|
// <exportName>.<specialCondition>
|
|
657
651
|
let specialCondition;
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
652
|
+
const specialConditionName = getSpecialExportTypeFromExportPath(exportName);
|
|
653
|
+
const normalizedExportPath = normalizeExportPath(exportName);
|
|
654
|
+
if (specialConditionName !== 'default') {
|
|
655
|
+
// e.g.
|
|
656
|
+
// ./index.develop -> index
|
|
657
|
+
// ./foo.react-server -> foo
|
|
658
|
+
const fileBaseName = exportName.split('.').slice(0, 2).join('.').replace('./', '');
|
|
661
659
|
specialCondition = {
|
|
662
|
-
[specialConditionName]: getDistPath('es', `${
|
|
660
|
+
[specialConditionName]: getDistPath('es', `${fileBaseName}-${specialConditionName}.mjs`)
|
|
663
661
|
};
|
|
664
|
-
exportCondName = normalizeBaseNameToExportName(originExportName);
|
|
665
662
|
return [
|
|
666
|
-
|
|
663
|
+
normalizedExportPath,
|
|
667
664
|
specialCondition
|
|
668
665
|
];
|
|
669
666
|
}
|
|
670
|
-
exportCondName = normalizeBaseNameToExportName(exportName);
|
|
671
667
|
const exportCond = createExportCondition(exportName, sourceFile, moduleType);
|
|
672
668
|
return [
|
|
673
|
-
|
|
669
|
+
normalizedExportPath,
|
|
674
670
|
exportCond
|
|
675
671
|
];
|
|
676
672
|
}
|
|
@@ -698,12 +694,17 @@ async function prepare(cwd) {
|
|
|
698
694
|
// Collect bins and exports entries
|
|
699
695
|
const { bins, exportsEntries } = await collectSourceEntries(sourceFolder);
|
|
700
696
|
const tsConfigPath = path__default.default.join(cwd, 'tsconfig.json');
|
|
701
|
-
const
|
|
697
|
+
const exportsSourceFiles = [
|
|
702
698
|
...exportsEntries.values()
|
|
703
|
-
].
|
|
699
|
+
].reduce((acc, sourceFiles)=>{
|
|
700
|
+
Object.values(sourceFiles).forEach((sourceFile)=>acc.add(sourceFile));
|
|
701
|
+
return acc;
|
|
702
|
+
}, new Set());
|
|
703
|
+
const allSourceFiles = [
|
|
704
|
+
...exportsSourceFiles,
|
|
704
705
|
...bins.values()
|
|
705
|
-
]);
|
|
706
|
-
const hasTypeScriptFiles =
|
|
706
|
+
].map((absoluteFilePath)=>absoluteFilePath);
|
|
707
|
+
const hasTypeScriptFiles = allSourceFiles.some((filename)=>isTypescriptFile(filename));
|
|
707
708
|
if (hasTypeScriptFiles) {
|
|
708
709
|
isUsingTs = true;
|
|
709
710
|
if (!fs__default.default.existsSync(tsConfigPath)) {
|
|
@@ -719,13 +720,14 @@ async function prepare(cwd) {
|
|
|
719
720
|
const maxLengthOfBinName = Math.max(...Array.from(bins.keys()).map((binName)=>normalizeBaseNameToExportName(binName).length));
|
|
720
721
|
for (const [binName, binFile] of bins.entries()){
|
|
721
722
|
const spaces = ' '.repeat(Math.max(maxLengthOfBinName - normalizeBaseNameToExportName(binName).length, 0));
|
|
722
|
-
logger.log(` ${normalizeBaseNameToExportName(binName)}${spaces}: ${binFile}`);
|
|
723
|
+
logger.log(` ${normalizeBaseNameToExportName(binName)}${spaces}: ${path__default.default.basename(binFile)}`);
|
|
723
724
|
}
|
|
724
|
-
if (bins.size === 1 && bins.has(
|
|
725
|
+
if (bins.size === 1 && bins.has(BINARY_TAG)) {
|
|
725
726
|
pkgJson.bin = getDistPath('bin', 'index.js');
|
|
726
727
|
} else {
|
|
727
728
|
pkgJson.bin = {};
|
|
728
|
-
for (const [
|
|
729
|
+
for (const [binOriginName] of bins.entries()){
|
|
730
|
+
const binName = stripeBinaryTag(binOriginName);
|
|
729
731
|
pkgJson.bin[binName === '.' ? pkgJson.name : binName] = getDistPath('bin', binName + '.js');
|
|
730
732
|
}
|
|
731
733
|
}
|
|
@@ -733,20 +735,24 @@ async function prepare(cwd) {
|
|
|
733
735
|
if (exportsEntries.size > 0) {
|
|
734
736
|
logger.log('Discovered exports entries:');
|
|
735
737
|
const maxLengthOfExportName = Math.max(...Array.from(exportsEntries.keys()).map((exportName)=>normalizeBaseNameToExportName(exportName).length));
|
|
736
|
-
for (const [exportName,
|
|
738
|
+
for (const [exportName, sourceFilesMap] of exportsEntries.entries()){
|
|
737
739
|
const spaces = ' '.repeat(Math.max(maxLengthOfExportName - normalizeBaseNameToExportName(exportName).length, 0));
|
|
738
|
-
|
|
740
|
+
for (const exportFile of Object.values(sourceFilesMap)){
|
|
741
|
+
logger.log(` ${normalizeBaseNameToExportName(exportName)}${spaces}: ${path__default.default.basename(exportFile)}`);
|
|
742
|
+
}
|
|
739
743
|
}
|
|
740
744
|
const pkgExports = {};
|
|
741
|
-
for (const [exportName,
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
745
|
+
for (const [exportName, sourceFilesMap] of exportsEntries.entries()){
|
|
746
|
+
for (const sourceFile of Object.values(sourceFilesMap)){
|
|
747
|
+
const [key, value] = createExportConditionPair(exportName, sourceFile, pkgJson.type);
|
|
748
|
+
pkgExports[key] = {
|
|
749
|
+
...value,
|
|
750
|
+
...pkgExports[key]
|
|
751
|
+
};
|
|
752
|
+
}
|
|
747
753
|
}
|
|
748
754
|
// Configure node10 module resolution
|
|
749
|
-
if (exportsEntries.has('index')) {
|
|
755
|
+
if (exportsEntries.has('./index')) {
|
|
750
756
|
const isESM = pkgJson.type === 'module';
|
|
751
757
|
const mainExport = pkgExports['.'];
|
|
752
758
|
const mainCondition = isESM ? 'import' : 'require';
|
|
@@ -793,7 +799,8 @@ Options:
|
|
|
793
799
|
--env <env> inlined process env variables, separate by comma. default: NODE_ENV
|
|
794
800
|
--cwd <cwd> specify current working directory
|
|
795
801
|
--sourcemap enable sourcemap generation, default: false
|
|
796
|
-
--dts determine if need to generate types, default:
|
|
802
|
+
--dts determine if need to generate types, default: undefined
|
|
803
|
+
--no-dts do not generate types, default: undefined
|
|
797
804
|
`;
|
|
798
805
|
function help() {
|
|
799
806
|
logger.log(helpMessage);
|
|
@@ -810,6 +817,7 @@ function parseCliArgs(argv) {
|
|
|
810
817
|
args = arg__default.default({
|
|
811
818
|
'--cwd': String,
|
|
812
819
|
'--dts': Boolean,
|
|
820
|
+
'--no-dts': Boolean,
|
|
813
821
|
'--output': String,
|
|
814
822
|
'--format': String,
|
|
815
823
|
'--watch': Boolean,
|
|
@@ -843,7 +851,7 @@ function parseCliArgs(argv) {
|
|
|
843
851
|
minify: args['--minify'],
|
|
844
852
|
sourcemap: !!args['--sourcemap'],
|
|
845
853
|
cwd: args['--cwd'],
|
|
846
|
-
dts: args['--dts'],
|
|
854
|
+
dts: args['--no-dts'] ? false : args['--dts'],
|
|
847
855
|
help: args['--help'],
|
|
848
856
|
version: args['--version'],
|
|
849
857
|
runtime: args['--runtime'],
|
|
@@ -861,7 +869,7 @@ async function run(args) {
|
|
|
861
869
|
const cwd = args.cwd || process.cwd();
|
|
862
870
|
const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
|
|
863
871
|
const bundleConfig = {
|
|
864
|
-
dts,
|
|
872
|
+
dts: typeof dts === 'boolean' ? dts : undefined,
|
|
865
873
|
file,
|
|
866
874
|
format,
|
|
867
875
|
cwd,
|