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/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,142 @@ 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
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const fullExportCondition = constructFullExportCondition(exportCondition, packageType);
|
|
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
|
+
exportTypes.add(exportKey.startsWith('./') ? 'default' : exportKey);
|
|
193
|
+
const exportInfo = exportToDist.get(currentPath);
|
|
194
|
+
const exportCondition = Array.from(exportTypes).join('.');
|
|
195
|
+
if (!exportInfo) {
|
|
196
|
+
const outputConditionPair = [
|
|
197
|
+
exportValue,
|
|
198
|
+
exportCondition
|
|
199
|
+
];
|
|
200
|
+
exportToDist.set(currentPath, [
|
|
201
|
+
outputConditionPair
|
|
202
|
+
]);
|
|
227
203
|
} 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
|
-
}
|
|
204
|
+
exportInfo.push([
|
|
205
|
+
exportValue,
|
|
206
|
+
exportCondition
|
|
207
|
+
]);
|
|
243
208
|
}
|
|
244
209
|
return;
|
|
245
210
|
}
|
|
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);
|
|
211
|
+
const exportKeys = Object.keys(exportValue);
|
|
212
|
+
for (const exportKey of exportKeys){
|
|
213
|
+
// Clone the set to avoid modifying the parent set
|
|
214
|
+
const childExports = new Set(exportTypes);
|
|
215
|
+
// Normalize child export value to a map
|
|
216
|
+
const childExportValue = exportValue[exportKey];
|
|
217
|
+
// Visit export path: ./subpath, ./subpath2, ...
|
|
218
|
+
if (exportKey.startsWith('.')) {
|
|
219
|
+
const childPath = joinRelativePath(currentPath, exportKey);
|
|
220
|
+
collectExportPath(childExportValue, exportKey, childPath, childExports, exportToDist);
|
|
314
221
|
} else {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
});
|
|
222
|
+
// Visit export type: import, require, ...
|
|
223
|
+
childExports.add(exportKey);
|
|
224
|
+
collectExportPath(childExportValue, exportKey, currentPath, childExports, exportToDist);
|
|
319
225
|
}
|
|
320
226
|
}
|
|
321
|
-
return paths;
|
|
322
227
|
}
|
|
323
228
|
/**
|
|
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
|
-
* ```
|
|
229
|
+
* parseExports - parse package.exports field and other fields like main,module to a map
|
|
344
230
|
*
|
|
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
|
-
// main export '.' from main/module/typings
|
|
376
|
-
let mainExportCondition;
|
|
377
|
-
if (pkg.main) {
|
|
378
|
-
const mainExportType = isEsmPackage ? hasCjsExtension(pkg.main) ? 'require' : 'import' : 'require';
|
|
379
|
-
mainExportCondition = {
|
|
380
|
-
[mainExportType]: pkg.main
|
|
381
|
-
};
|
|
231
|
+
* map from export path to output path and export conditions
|
|
232
|
+
*/ function parseExports(pkg) {
|
|
233
|
+
var _pkg_exports;
|
|
234
|
+
const exportsField = (_pkg_exports = pkg.exports) != null ? _pkg_exports : {};
|
|
235
|
+
var _pkg_bin;
|
|
236
|
+
const bins = (_pkg_bin = pkg.bin) != null ? _pkg_bin : {};
|
|
237
|
+
const exportToDist = new Map();
|
|
238
|
+
const isEsmPkg = isESModulePackage(pkg.type);
|
|
239
|
+
const defaultCondition = isEsmPkg ? 'import' : 'require';
|
|
240
|
+
let currentPath = '.';
|
|
241
|
+
if (typeof exportsField === 'string') {
|
|
242
|
+
const outputConditionPair = [
|
|
243
|
+
exportsField,
|
|
244
|
+
defaultCondition
|
|
245
|
+
];
|
|
246
|
+
exportToDist.set(currentPath, [
|
|
247
|
+
outputConditionPair
|
|
248
|
+
]);
|
|
249
|
+
} else {
|
|
250
|
+
// keys means unknown if they're relative path or export type
|
|
251
|
+
const exportConditionKeys = Object.keys(exportsField);
|
|
252
|
+
for (const exportKey of exportConditionKeys){
|
|
253
|
+
const exportValue = exportsField[exportKey];
|
|
254
|
+
const exportTypes = new Set();
|
|
255
|
+
const isExportPath = exportKey.startsWith('.');
|
|
256
|
+
const childPath = isExportPath ? joinRelativePath(currentPath, exportKey) : currentPath;
|
|
257
|
+
collectExportPath(exportValue, exportKey, childPath, exportTypes, exportToDist);
|
|
258
|
+
}
|
|
382
259
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
260
|
+
if (typeof bins === 'string') {
|
|
261
|
+
const outputConditionPair = [
|
|
262
|
+
bins,
|
|
263
|
+
defaultCondition
|
|
264
|
+
];
|
|
265
|
+
exportToDist.set(BINARY_TAG, [
|
|
266
|
+
outputConditionPair
|
|
267
|
+
]);
|
|
268
|
+
} else {
|
|
269
|
+
for (const binName of Object.keys(bins)){
|
|
270
|
+
const binDistPath = bins[binName];
|
|
271
|
+
const exportType = getExportTypeFromFile(binDistPath, pkg.type);
|
|
272
|
+
const exportPath = path.posix.join(BINARY_TAG, binName);
|
|
273
|
+
const outputConditionPair = [
|
|
274
|
+
binDistPath,
|
|
275
|
+
exportType
|
|
276
|
+
];
|
|
277
|
+
exportToDist.set(exportPath, [
|
|
278
|
+
outputConditionPair
|
|
279
|
+
]);
|
|
280
|
+
}
|
|
403
281
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
282
|
+
if (pkg.main || pkg.module) {
|
|
283
|
+
const mainExportPath = pkg.main;
|
|
284
|
+
const moduleExportPath = pkg.module;
|
|
285
|
+
const typesEntryPath = pkg.types;
|
|
286
|
+
const existingExportInfo = exportToDist.get('.');
|
|
287
|
+
exportToDist.set('.', [
|
|
288
|
+
...existingExportInfo || [],
|
|
289
|
+
[
|
|
290
|
+
mainExportPath,
|
|
291
|
+
getMainFieldExportType(pkg)
|
|
292
|
+
],
|
|
293
|
+
Boolean(moduleExportPath) && [
|
|
294
|
+
moduleExportPath,
|
|
295
|
+
'import'
|
|
296
|
+
],
|
|
297
|
+
Boolean(typesEntryPath) && [
|
|
298
|
+
typesEntryPath,
|
|
299
|
+
'types'
|
|
300
|
+
]
|
|
301
|
+
].filter(Boolean));
|
|
302
|
+
}
|
|
303
|
+
return exportToDist;
|
|
411
304
|
}
|
|
412
305
|
function getExportTypeFromFile(filename, pkgType) {
|
|
413
306
|
const isESModule = isESModulePackage(pkgType);
|
|
@@ -420,7 +313,7 @@ function getExportTypeFromFile(filename, pkgType) {
|
|
|
420
313
|
function lint$1(pkg) {
|
|
421
314
|
const { name, main, exports } = pkg;
|
|
422
315
|
const isESM = isESModulePackage(pkg.type);
|
|
423
|
-
const
|
|
316
|
+
const parsedExports = parseExports(pkg);
|
|
424
317
|
if (!name) {
|
|
425
318
|
logger.warn('Missing package name');
|
|
426
319
|
}
|
|
@@ -456,16 +349,17 @@ function lint$1(pkg) {
|
|
|
456
349
|
if (typeof exports !== 'object') {
|
|
457
350
|
state.invalidExportsFieldType = true;
|
|
458
351
|
} else {
|
|
459
|
-
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
352
|
+
parsedExports.forEach((outputPairs)=>{
|
|
353
|
+
for (const [outputPath, composedExportType] of outputPairs){
|
|
354
|
+
const exportTypes = new Set(composedExportType.split('.'));
|
|
355
|
+
let requirePath = '';
|
|
356
|
+
let importPath = '';
|
|
357
|
+
if (exportTypes.has('require')) {
|
|
358
|
+
requirePath = outputPath;
|
|
359
|
+
}
|
|
360
|
+
if (exportTypes.has('import')) {
|
|
361
|
+
importPath = outputPath;
|
|
362
|
+
}
|
|
469
363
|
const requireExt = requirePath && path__default.default.extname(requirePath);
|
|
470
364
|
const importExt = importPath && path__default.default.extname(importPath);
|
|
471
365
|
if (requireExt === '.mjs' || requireExt === '.js') {
|
|
@@ -494,16 +388,17 @@ function lint$1(pkg) {
|
|
|
494
388
|
if (typeof exports !== 'object') {
|
|
495
389
|
state.invalidExportsFieldType = true;
|
|
496
390
|
} else {
|
|
497
|
-
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
391
|
+
parsedExports.forEach((outputPairs)=>{
|
|
392
|
+
for (const [outputPath, composedExportType] of outputPairs){
|
|
393
|
+
const exportTypes = new Set(composedExportType.split('.'));
|
|
394
|
+
let requirePath = '';
|
|
395
|
+
let importPath = '';
|
|
396
|
+
if (exportTypes.has('require')) {
|
|
397
|
+
requirePath = outputPath;
|
|
398
|
+
}
|
|
399
|
+
if (exportTypes.has('import')) {
|
|
400
|
+
importPath = outputPath;
|
|
401
|
+
}
|
|
507
402
|
const requireExt = requirePath && path__default.default.extname(requirePath);
|
|
508
403
|
const importExt = importPath && path__default.default.extname(importPath);
|
|
509
404
|
if (requireExt === '.mjs') {
|
|
@@ -558,7 +453,7 @@ function lint$1(pkg) {
|
|
|
558
453
|
}
|
|
559
454
|
}
|
|
560
455
|
|
|
561
|
-
var version = "
|
|
456
|
+
var version = "5.0.0-beta.1";
|
|
562
457
|
|
|
563
458
|
function relativify(path) {
|
|
564
459
|
return path.startsWith('.') ? path : `./${path}`;
|
|
@@ -569,41 +464,73 @@ async function writeDefaultTsconfig(tsConfigPath) {
|
|
|
569
464
|
logger.log(`Detected using TypeScript but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
|
|
570
465
|
}
|
|
571
466
|
|
|
572
|
-
//
|
|
573
|
-
|
|
574
|
-
|
|
467
|
+
// shared.ts -> ./shared
|
|
468
|
+
// shared.<export condition>.ts -> ./shared
|
|
469
|
+
// index.ts -> ./index
|
|
470
|
+
// index.development.ts -> ./index.development
|
|
471
|
+
function sourceFilenameToExportPath(filename) {
|
|
472
|
+
const baseName = baseNameWithoutExtension(filename);
|
|
473
|
+
let exportPath = baseName;
|
|
474
|
+
return relativify(exportPath);
|
|
575
475
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
function
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
476
|
+
// ./index -> import|require|default
|
|
477
|
+
// ./index.development -> development
|
|
478
|
+
// ./index.react-server -> react-server
|
|
479
|
+
function getExportTypeFromExportPath(exportPath) {
|
|
480
|
+
// Skip the first two segments: `.` and `index`
|
|
481
|
+
const exportTypes = exportPath.split('.').slice(2);
|
|
482
|
+
return getExportTypeFromExportTypes(exportTypes);
|
|
483
|
+
}
|
|
484
|
+
function getSpecialExportTypeFromExportPath(composedExportType) {
|
|
485
|
+
const exportTypes = composedExportType.split('.');
|
|
486
|
+
for (const exportType of exportTypes){
|
|
487
|
+
if (specialExportConventions.has(exportType)) {
|
|
488
|
+
return exportType;
|
|
489
|
+
}
|
|
586
490
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
491
|
+
return 'default';
|
|
492
|
+
}
|
|
493
|
+
function getExportTypeFromExportTypes(types) {
|
|
494
|
+
let exportType = 'default';
|
|
495
|
+
new Set(types).forEach((value)=>{
|
|
496
|
+
if (specialExportConventions.has(value)) {
|
|
497
|
+
exportType = value;
|
|
498
|
+
} else if (value === 'import' || value === 'require') {
|
|
499
|
+
exportType = value;
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
return exportType;
|
|
503
|
+
}
|
|
504
|
+
// ./index -> .
|
|
505
|
+
// ./index.development -> .
|
|
506
|
+
// ./index.react-server -> .
|
|
507
|
+
// ./shared -> ./shared
|
|
508
|
+
// ./shared.development -> ./shared
|
|
509
|
+
// $binary -> $binary
|
|
510
|
+
// $binary/index -> $binary
|
|
511
|
+
// $binary/foo -> $binary/foo
|
|
512
|
+
function normalizeExportPath(exportPath) {
|
|
513
|
+
if (exportPath.startsWith(BINARY_TAG)) {
|
|
514
|
+
if (exportPath === `${BINARY_TAG}/index`) {
|
|
515
|
+
exportPath = BINARY_TAG;
|
|
516
|
+
}
|
|
517
|
+
return exportPath;
|
|
598
518
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
}
|
|
519
|
+
const baseName = exportPath.split('.').slice(0, 2).join('.');
|
|
520
|
+
if (baseName === './index') {
|
|
521
|
+
return '.';
|
|
522
|
+
}
|
|
523
|
+
return baseName;
|
|
603
524
|
}
|
|
604
525
|
async function collectSourceEntries(sourceFolderPath) {
|
|
605
526
|
const bins = new Map();
|
|
606
527
|
const exportsEntries = new Map();
|
|
528
|
+
if (!fs__default.default.existsSync(sourceFolderPath)) {
|
|
529
|
+
return {
|
|
530
|
+
bins,
|
|
531
|
+
exportsEntries
|
|
532
|
+
};
|
|
533
|
+
}
|
|
607
534
|
const entryFileDirentList = await fsp__default.default.readdir(sourceFolderPath, {
|
|
608
535
|
withFileTypes: true
|
|
609
536
|
});
|
|
@@ -616,18 +543,35 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
616
543
|
for (const binDirent of binDirentList){
|
|
617
544
|
if (binDirent.isFile()) {
|
|
618
545
|
const binFileAbsolutePath = path__default.default.join(sourceFolderPath, dirent.name, binDirent.name);
|
|
619
|
-
const
|
|
546
|
+
const binExportPath = sourceFilenameToExportPath(binDirent.name);
|
|
620
547
|
if (fs__default.default.existsSync(binFileAbsolutePath)) {
|
|
621
|
-
bins.set(
|
|
548
|
+
bins.set(path.posix.join(BINARY_TAG, binExportPath), binFileAbsolutePath);
|
|
622
549
|
}
|
|
623
550
|
}
|
|
624
551
|
}
|
|
625
552
|
} else {
|
|
626
|
-
// Search folder
|
|
553
|
+
// Search folder/index.<ext> convention entries
|
|
627
554
|
for (const extension of availableExtensions){
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
555
|
+
const indexAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${extension}`);
|
|
556
|
+
// Search folder/index.<special type>.<ext> convention entries
|
|
557
|
+
for (const specialExportType of runtimeExportConventions){
|
|
558
|
+
const indexSpecialAbsoluteFile = path__default.default.join(dirent.path, dirent.name, `index.${specialExportType}.${extension}`);
|
|
559
|
+
if (fs__default.default.existsSync(indexSpecialAbsoluteFile)) {
|
|
560
|
+
// Add special export path
|
|
561
|
+
// { ./<export path>.<special cond>: { <special cond>: 'index.<special cond>.<ext>' } }
|
|
562
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
563
|
+
const specialExportPath = exportPath + '.' + specialExportType;
|
|
564
|
+
const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
|
|
565
|
+
sourceFilesMap[specialExportType] = indexSpecialAbsoluteFile;
|
|
566
|
+
exportsEntries.set(specialExportPath, sourceFilesMap);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
if (fs__default.default.existsSync(indexAbsoluteFile) && !isTestFile(indexAbsoluteFile)) {
|
|
570
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
571
|
+
const sourceFilesMap = exportsEntries.get(exportPath) || {};
|
|
572
|
+
const exportType = getExportTypeFromExportPath(exportPath);
|
|
573
|
+
sourceFilesMap[exportType] = indexAbsoluteFile;
|
|
574
|
+
exportsEntries.set(exportPath, sourceFilesMap);
|
|
631
575
|
break;
|
|
632
576
|
}
|
|
633
577
|
}
|
|
@@ -635,13 +579,17 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
635
579
|
} else if (dirent.isFile()) {
|
|
636
580
|
const isAvailableExtension = availableExtensions.has(path__default.default.extname(dirent.name).slice(1));
|
|
637
581
|
if (isAvailableExtension) {
|
|
638
|
-
const
|
|
639
|
-
const isBinFile =
|
|
582
|
+
const exportPath = sourceFilenameToExportPath(dirent.name);
|
|
583
|
+
const isBinFile = exportPath === './bin';
|
|
584
|
+
const fullPath = path__default.default.join(sourceFolderPath, dirent.name);
|
|
640
585
|
if (isBinFile) {
|
|
641
|
-
bins.set(
|
|
586
|
+
bins.set(BINARY_TAG, fullPath);
|
|
642
587
|
} else {
|
|
643
588
|
if (hasAvailableExtension(dirent.name) && !isTestFile(dirent.name)) {
|
|
644
|
-
exportsEntries.
|
|
589
|
+
const sourceFilesMap = exportsEntries.get(exportPath) || {};
|
|
590
|
+
const exportType = getExportTypeFromExportPath(exportPath);
|
|
591
|
+
sourceFilesMap[exportType] = fullPath;
|
|
592
|
+
exportsEntries.set(exportPath, sourceFilesMap);
|
|
645
593
|
}
|
|
646
594
|
}
|
|
647
595
|
}
|
|
@@ -652,25 +600,68 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
652
600
|
exportsEntries
|
|
653
601
|
};
|
|
654
602
|
}
|
|
603
|
+
|
|
604
|
+
// Output with posix style in package.json
|
|
605
|
+
function getDistPath(...subPaths) {
|
|
606
|
+
return relativify(path.posix.join(DIST, ...subPaths));
|
|
607
|
+
}
|
|
608
|
+
function stripeBinaryTag(exportName) {
|
|
609
|
+
// Add \ to decode leading $
|
|
610
|
+
return exportName.replace(/\$binary\//, '');
|
|
611
|
+
}
|
|
612
|
+
const normalizeBaseNameToExportName = (name)=>{
|
|
613
|
+
const baseName = stripeBinaryTag(name);
|
|
614
|
+
return /^\.\/index(\.|$)/.test(baseName) ? '.' : relativify(baseName);
|
|
615
|
+
};
|
|
616
|
+
function createExportCondition(exportName, sourceFile, moduleType) {
|
|
617
|
+
const isTsSourceFile = isTypescriptFile(sourceFile);
|
|
618
|
+
let cjsExtension = 'js';
|
|
619
|
+
let esmExtension = 'mjs';
|
|
620
|
+
if (moduleType === 'module') {
|
|
621
|
+
cjsExtension = 'cjs';
|
|
622
|
+
esmExtension = 'js';
|
|
623
|
+
}
|
|
624
|
+
if (exportName === '.') {
|
|
625
|
+
exportName = 'index';
|
|
626
|
+
}
|
|
627
|
+
if (isTsSourceFile) {
|
|
628
|
+
return {
|
|
629
|
+
import: {
|
|
630
|
+
types: getDistPath('es', `${exportName}.${dtsExtensionsMap[esmExtension]}`),
|
|
631
|
+
default: getDistPath('es', `${exportName}.${esmExtension}`)
|
|
632
|
+
},
|
|
633
|
+
require: {
|
|
634
|
+
types: getDistPath('cjs', `${exportName}.${dtsExtensionsMap[cjsExtension]}`),
|
|
635
|
+
default: getDistPath('cjs', `${exportName}.${cjsExtension}`)
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
return {
|
|
640
|
+
import: getDistPath(`${exportName}.mjs`),
|
|
641
|
+
require: getDistPath(`${exportName}.${cjsExtension}`)
|
|
642
|
+
};
|
|
643
|
+
}
|
|
655
644
|
function createExportConditionPair(exportName, sourceFile, moduleType) {
|
|
656
645
|
// <exportName>.<specialCondition>
|
|
657
646
|
let specialCondition;
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
647
|
+
const specialConditionName = getSpecialExportTypeFromExportPath(exportName);
|
|
648
|
+
const normalizedExportPath = normalizeExportPath(exportName);
|
|
649
|
+
if (specialConditionName !== 'default') {
|
|
650
|
+
// e.g.
|
|
651
|
+
// ./index.develop -> index
|
|
652
|
+
// ./foo.react-server -> foo
|
|
653
|
+
const fileBaseName = exportName.split('.').slice(0, 2).join('.').replace('./', '');
|
|
661
654
|
specialCondition = {
|
|
662
|
-
[specialConditionName]: getDistPath('es', `${
|
|
655
|
+
[specialConditionName]: getDistPath('es', `${fileBaseName}-${specialConditionName}.mjs`)
|
|
663
656
|
};
|
|
664
|
-
exportCondName = normalizeBaseNameToExportName(originExportName);
|
|
665
657
|
return [
|
|
666
|
-
|
|
658
|
+
normalizedExportPath,
|
|
667
659
|
specialCondition
|
|
668
660
|
];
|
|
669
661
|
}
|
|
670
|
-
exportCondName = normalizeBaseNameToExportName(exportName);
|
|
671
662
|
const exportCond = createExportCondition(exportName, sourceFile, moduleType);
|
|
672
663
|
return [
|
|
673
|
-
|
|
664
|
+
normalizedExportPath,
|
|
674
665
|
exportCond
|
|
675
666
|
];
|
|
676
667
|
}
|
|
@@ -698,12 +689,17 @@ async function prepare(cwd) {
|
|
|
698
689
|
// Collect bins and exports entries
|
|
699
690
|
const { bins, exportsEntries } = await collectSourceEntries(sourceFolder);
|
|
700
691
|
const tsConfigPath = path__default.default.join(cwd, 'tsconfig.json');
|
|
701
|
-
const
|
|
692
|
+
const exportsSourceFiles = [
|
|
702
693
|
...exportsEntries.values()
|
|
703
|
-
].
|
|
694
|
+
].reduce((acc, sourceFiles)=>{
|
|
695
|
+
Object.values(sourceFiles).forEach((sourceFile)=>acc.add(sourceFile));
|
|
696
|
+
return acc;
|
|
697
|
+
}, new Set());
|
|
698
|
+
const allSourceFiles = [
|
|
699
|
+
...exportsSourceFiles,
|
|
704
700
|
...bins.values()
|
|
705
|
-
]);
|
|
706
|
-
const hasTypeScriptFiles =
|
|
701
|
+
].map((absoluteFilePath)=>absoluteFilePath);
|
|
702
|
+
const hasTypeScriptFiles = allSourceFiles.some((filename)=>isTypescriptFile(filename));
|
|
707
703
|
if (hasTypeScriptFiles) {
|
|
708
704
|
isUsingTs = true;
|
|
709
705
|
if (!fs__default.default.existsSync(tsConfigPath)) {
|
|
@@ -719,13 +715,14 @@ async function prepare(cwd) {
|
|
|
719
715
|
const maxLengthOfBinName = Math.max(...Array.from(bins.keys()).map((binName)=>normalizeBaseNameToExportName(binName).length));
|
|
720
716
|
for (const [binName, binFile] of bins.entries()){
|
|
721
717
|
const spaces = ' '.repeat(Math.max(maxLengthOfBinName - normalizeBaseNameToExportName(binName).length, 0));
|
|
722
|
-
logger.log(` ${normalizeBaseNameToExportName(binName)}${spaces}: ${binFile}`);
|
|
718
|
+
logger.log(` ${normalizeBaseNameToExportName(binName)}${spaces}: ${path__default.default.basename(binFile)}`);
|
|
723
719
|
}
|
|
724
|
-
if (bins.size === 1 && bins.has(
|
|
720
|
+
if (bins.size === 1 && bins.has(BINARY_TAG)) {
|
|
725
721
|
pkgJson.bin = getDistPath('bin', 'index.js');
|
|
726
722
|
} else {
|
|
727
723
|
pkgJson.bin = {};
|
|
728
|
-
for (const [
|
|
724
|
+
for (const [binOriginName] of bins.entries()){
|
|
725
|
+
const binName = stripeBinaryTag(binOriginName);
|
|
729
726
|
pkgJson.bin[binName === '.' ? pkgJson.name : binName] = getDistPath('bin', binName + '.js');
|
|
730
727
|
}
|
|
731
728
|
}
|
|
@@ -733,20 +730,24 @@ async function prepare(cwd) {
|
|
|
733
730
|
if (exportsEntries.size > 0) {
|
|
734
731
|
logger.log('Discovered exports entries:');
|
|
735
732
|
const maxLengthOfExportName = Math.max(...Array.from(exportsEntries.keys()).map((exportName)=>normalizeBaseNameToExportName(exportName).length));
|
|
736
|
-
for (const [exportName,
|
|
733
|
+
for (const [exportName, sourceFilesMap] of exportsEntries.entries()){
|
|
737
734
|
const spaces = ' '.repeat(Math.max(maxLengthOfExportName - normalizeBaseNameToExportName(exportName).length, 0));
|
|
738
|
-
|
|
735
|
+
for (const exportFile of Object.values(sourceFilesMap)){
|
|
736
|
+
logger.log(` ${normalizeBaseNameToExportName(exportName)}${spaces}: ${path__default.default.basename(exportFile)}`);
|
|
737
|
+
}
|
|
739
738
|
}
|
|
740
739
|
const pkgExports = {};
|
|
741
|
-
for (const [exportName,
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
740
|
+
for (const [exportName, sourceFilesMap] of exportsEntries.entries()){
|
|
741
|
+
for (const sourceFile of Object.values(sourceFilesMap)){
|
|
742
|
+
const [key, value] = createExportConditionPair(exportName, sourceFile, pkgJson.type);
|
|
743
|
+
pkgExports[key] = {
|
|
744
|
+
...value,
|
|
745
|
+
...pkgExports[key]
|
|
746
|
+
};
|
|
747
|
+
}
|
|
747
748
|
}
|
|
748
749
|
// Configure node10 module resolution
|
|
749
|
-
if (exportsEntries.has('index')) {
|
|
750
|
+
if (exportsEntries.has('./index')) {
|
|
750
751
|
const isESM = pkgJson.type === 'module';
|
|
751
752
|
const mainExport = pkgExports['.'];
|
|
752
753
|
const mainCondition = isESM ? 'import' : 'require';
|
|
@@ -793,7 +794,8 @@ Options:
|
|
|
793
794
|
--env <env> inlined process env variables, separate by comma. default: NODE_ENV
|
|
794
795
|
--cwd <cwd> specify current working directory
|
|
795
796
|
--sourcemap enable sourcemap generation, default: false
|
|
796
|
-
--dts determine if need to generate types, default:
|
|
797
|
+
--dts determine if need to generate types, default: undefined
|
|
798
|
+
--no-dts do not generate types, default: undefined
|
|
797
799
|
`;
|
|
798
800
|
function help() {
|
|
799
801
|
logger.log(helpMessage);
|
|
@@ -810,6 +812,7 @@ function parseCliArgs(argv) {
|
|
|
810
812
|
args = arg__default.default({
|
|
811
813
|
'--cwd': String,
|
|
812
814
|
'--dts': Boolean,
|
|
815
|
+
'--no-dts': Boolean,
|
|
813
816
|
'--output': String,
|
|
814
817
|
'--format': String,
|
|
815
818
|
'--watch': Boolean,
|
|
@@ -843,7 +846,7 @@ function parseCliArgs(argv) {
|
|
|
843
846
|
minify: args['--minify'],
|
|
844
847
|
sourcemap: !!args['--sourcemap'],
|
|
845
848
|
cwd: args['--cwd'],
|
|
846
|
-
dts: args['--dts'],
|
|
849
|
+
dts: args['--no-dts'] ? false : args['--dts'],
|
|
847
850
|
help: args['--help'],
|
|
848
851
|
version: args['--version'],
|
|
849
852
|
runtime: args['--runtime'],
|
|
@@ -861,7 +864,7 @@ async function run(args) {
|
|
|
861
864
|
const cwd = args.cwd || process.cwd();
|
|
862
865
|
const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
|
|
863
866
|
const bundleConfig = {
|
|
864
|
-
dts,
|
|
867
|
+
dts: typeof dts === 'boolean' ? dts : undefined,
|
|
865
868
|
file,
|
|
866
869
|
format,
|
|
867
870
|
cwd,
|