bunchee 5.2.0-beta.0 → 5.2.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/dist/index.js CHANGED
@@ -3,9 +3,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
3
3
  var fsp = require('fs/promises');
4
4
  var fs = require('fs');
5
5
  var path = require('path');
6
- var perf_hooks = require('perf_hooks');
7
- var module$1 = require('module');
6
+ require('pretty-bytes');
8
7
  var require$$0 = require('tty');
8
+ var module$1 = require('module');
9
+ var rollup = require('rollup');
9
10
  var pluginWasm = require('@rollup/plugin-wasm');
10
11
  var rollupPluginSwc3 = require('rollup-plugin-swc3');
11
12
  var commonjs = require('@rollup/plugin-commonjs');
@@ -16,8 +17,6 @@ var preserveDirectives = require('rollup-preserve-directives');
16
17
  var MagicString = require('magic-string');
17
18
  var CleanCSS = require('clean-css');
18
19
  var pluginutils = require('@rollup/pluginutils');
19
- var prettyBytes = require('pretty-bytes');
20
- var rollup = require('rollup');
21
20
 
22
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
23
22
 
@@ -31,7 +30,6 @@ var replace__default = /*#__PURE__*/_interopDefault(replace);
31
30
  var preserveDirectives__default = /*#__PURE__*/_interopDefault(preserveDirectives);
32
31
  var MagicString__default = /*#__PURE__*/_interopDefault(MagicString);
33
32
  var CleanCSS__default = /*#__PURE__*/_interopDefault(CleanCSS);
34
- var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes);
35
33
 
36
34
  function getDefaultExportFromCjs (x) {
37
35
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -86,6 +84,25 @@ picocolors.exports.createColors = createColors;
86
84
  var picocolorsExports = picocolors.exports;
87
85
  var pc = /*@__PURE__*/getDefaultExportFromCjs(picocolorsExports);
88
86
 
87
+ const defaultColorFn = (text)=>text;
88
+ function color(prefixColor) {
89
+ return pc.isColorSupported ? pc[prefixColor] : defaultColorFn;
90
+ }
91
+ const logger = {
92
+ log (...arg) {
93
+ console.log(...arg);
94
+ },
95
+ warn (...arg) {
96
+ console.warn(color('yellow')('⚠️'), ...arg);
97
+ },
98
+ error (...arg) {
99
+ console.error(color('red')('⨯'), ...arg);
100
+ },
101
+ info (...arg) {
102
+ console.log(color('green')('✓'), ...arg);
103
+ }
104
+ };
105
+
89
106
  const availableExtensions = new Set([
90
107
  'js',
91
108
  'cjs',
@@ -147,25 +164,6 @@ const DEFAULT_TS_CONFIG = {
147
164
  };
148
165
  const BINARY_TAG = '$binary';
149
166
 
150
- const defaultColorFn = (text)=>text;
151
- function color(prefixColor) {
152
- return pc.isColorSupported ? pc[prefixColor] : defaultColorFn;
153
- }
154
- const logger = {
155
- log (...arg) {
156
- console.log(...arg);
157
- },
158
- warn (...arg) {
159
- console.warn(color('yellow')('⚠️'), ...arg);
160
- },
161
- error (...arg) {
162
- console.error(color('red')('⨯'), ...arg);
163
- },
164
- info (...arg) {
165
- console.log(color('green')('✓'), ...arg);
166
- }
167
- };
168
-
169
167
  function exit(err) {
170
168
  logger.error(err);
171
169
  process.exit(1);
@@ -286,742 +284,349 @@ function isBinExportPath(exportPath) {
286
284
  return exportPath === BINARY_TAG || exportPath.startsWith(BINARY_TAG + '/');
287
285
  }
288
286
 
289
- const memoize = (fn, cacheKey, cacheArg)=>{
290
- const cache = cacheArg || new Map();
291
- return (...args)=>{
292
- const key = cacheKey ? typeof cacheKey === 'function' ? cacheKey(...args) : cacheKey : JSON.stringify({
293
- args
294
- });
295
- const existing = cache.get(key);
296
- if (existing !== undefined) {
297
- return existing;
298
- }
299
- const result = fn(...args);
300
- cache.set(key, result);
301
- return result;
302
- };
303
- };
304
- const memoizeByKey = (fn)=>{
305
- const cache = new Map();
306
- return (cacheKey)=>memoize(fn, cacheKey, cache);
307
- };
308
-
309
- let hasLoggedTsWarning = false;
310
- function resolveTypescript(cwd) {
311
- let ts;
312
- const m = new module$1.Module('', undefined);
313
- m.paths = module$1.Module._nodeModulePaths(cwd);
314
- try {
315
- // Bun does not yet support the `Module` class properly.
316
- if (typeof (m == null ? void 0 : m.require) === 'undefined') {
317
- const tsPath = require.resolve('typescript', {
318
- paths: [
319
- cwd
320
- ]
321
- });
322
- ts = require(tsPath);
287
+ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exportToDist) {
288
+ // End of searching, export value is file path.
289
+ // <export key>: <export value> (string)
290
+ if (typeof exportValue === 'string') {
291
+ const composedTypes = new Set(exportTypes);
292
+ const exportType = exportKey.startsWith('.') ? 'default' : exportKey;
293
+ composedTypes.add(exportType);
294
+ const exportInfo = exportToDist.get(mapExportFullPath(currentPath));
295
+ const exportCondition = Array.from(composedTypes).join('.');
296
+ if (!exportInfo) {
297
+ const outputConditionPair = [
298
+ exportValue,
299
+ exportCondition
300
+ ];
301
+ addToExportDistMap(exportToDist, currentPath, [
302
+ outputConditionPair
303
+ ], runtimeExportConventions.has(exportType) ? exportType : undefined);
323
304
  } else {
324
- ts = m.require('typescript');
305
+ exportInfo.push([
306
+ exportValue,
307
+ exportCondition
308
+ ]);
325
309
  }
326
- } catch (e) {
327
- console.error(e);
328
- if (!hasLoggedTsWarning) {
329
- hasLoggedTsWarning = true;
330
- exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency');
310
+ return;
311
+ }
312
+ const exportKeys = Object.keys(exportValue);
313
+ for (const exportKey of exportKeys){
314
+ // Clone the set to avoid modifying the parent set
315
+ const childExports = new Set(exportTypes);
316
+ // Normalize child export value to a map
317
+ const childExportValue = exportValue[exportKey];
318
+ // Visit export path: ./subpath, ./subpath2, ...
319
+ if (exportKey.startsWith('.')) {
320
+ const childPath = joinRelativePath(currentPath, exportKey);
321
+ collectExportPath(childExportValue, exportKey, childPath, childExports, exportToDist);
322
+ } else {
323
+ // Visit export type: import, require, ...
324
+ childExports.add(exportKey);
325
+ collectExportPath(childExportValue, exportKey, currentPath, childExports, exportToDist);
331
326
  }
332
327
  }
333
- return ts;
334
328
  }
335
- function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
336
- let tsCompilerOptions = {};
337
- let tsConfigPath;
338
- tsConfigPath = path.resolve(cwd, tsconfig);
339
- if (fileExists(tsConfigPath)) {
340
- // Use the original ts handler to avoid memory leak
341
- const ts = resolveTypescript(cwd);
342
- const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
343
- const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
344
- tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
329
+ const mapExportFullPath = (exportPath)=>exportPath === '.' ? './index' : exportPath;
330
+ function addToExportDistMap(exportToDist, exportPath, outputConditionPairs, specialExportType) {
331
+ const fullPath = mapExportFullPath(exportPath);
332
+ // + (specialExportType ? '.' + specialExportType : '')
333
+ const existingExportInfo = exportToDist.get(fullPath);
334
+ if (!existingExportInfo) {
335
+ exportToDist.set(fullPath, outputConditionPairs);
345
336
  } else {
346
- return null;
337
+ existingExportInfo.push(...outputConditionPairs);
347
338
  }
348
- return {
349
- tsCompilerOptions,
350
- tsConfigPath
351
- };
352
339
  }
353
- const resolveTsConfig = memoizeByKey(resolveTsConfigHandler)();
354
- async function convertCompilerOptions(cwd, json) {
355
- // Use the original ts handler to avoid memory leak
356
- const ts = resolveTypescript(cwd);
357
- return ts.convertCompilerOptionsFromJson(json, './');
340
+ /**
341
+ * parseExports - parse package.exports field and other fields like main,module to a map
342
+ *
343
+ * map from export path to output path and export conditions
344
+ *
345
+ * exportToDist: {
346
+ * './index': { development: ..., default: ... }
347
+ * './index.react-server': { development: ..., default: ... }
348
+ * }
349
+ */ function parseExports(pkg) {
350
+ var _pkg_exports;
351
+ const exportsField = (_pkg_exports = pkg.exports) != null ? _pkg_exports : {};
352
+ var _pkg_bin;
353
+ const bins = (_pkg_bin = pkg.bin) != null ? _pkg_bin : {};
354
+ const exportToDist = new Map();
355
+ const isEsmPkg = isESModulePackage(pkg.type);
356
+ const defaultCondition = isEsmPkg ? 'import' : 'require';
357
+ let currentPath = '.';
358
+ if (typeof exportsField === 'string') {
359
+ const outputConditionPair = [
360
+ exportsField,
361
+ defaultCondition
362
+ ];
363
+ addToExportDistMap(exportToDist, currentPath, [
364
+ outputConditionPair
365
+ ]);
366
+ } else {
367
+ // keys means unknown if they're relative path or export type
368
+ const exportConditionKeys = Object.keys(exportsField);
369
+ for (const exportKey of exportConditionKeys){
370
+ const exportValue = exportsField[exportKey];
371
+ const exportTypes = new Set();
372
+ const isExportPath = exportKey.startsWith('.');
373
+ const childPath = isExportPath ? joinRelativePath(currentPath, exportKey) : currentPath;
374
+ if (!isExportPath) {
375
+ exportTypes.add(exportKey);
376
+ }
377
+ collectExportPath(exportValue, exportKey, childPath, exportTypes, exportToDist);
378
+ }
379
+ }
380
+ if (typeof bins === 'string') {
381
+ const outputConditionPair = [
382
+ bins,
383
+ defaultCondition
384
+ ];
385
+ addToExportDistMap(exportToDist, BINARY_TAG, [
386
+ outputConditionPair
387
+ ]);
388
+ } else {
389
+ for (const binName of Object.keys(bins)){
390
+ const binDistPath = bins[binName];
391
+ const exportType = getExportTypeFromFile(binDistPath, pkg.type);
392
+ const exportPath = path.posix.join(BINARY_TAG, binName);
393
+ const outputConditionPair = [
394
+ binDistPath,
395
+ exportType
396
+ ];
397
+ addToExportDistMap(exportToDist, exportPath, [
398
+ outputConditionPair
399
+ ]);
400
+ }
401
+ }
402
+ // Handle package.json global exports fields
403
+ if (pkg.main || pkg.module || pkg.types) {
404
+ const mainExportPath = pkg.main;
405
+ const moduleExportPath = pkg.module;
406
+ const typesEntryPath = pkg.types;
407
+ addToExportDistMap(exportToDist, './index', [
408
+ Boolean(mainExportPath) && [
409
+ mainExportPath,
410
+ getMainFieldExportType(pkg)
411
+ ],
412
+ Boolean(moduleExportPath) && [
413
+ moduleExportPath,
414
+ 'module'
415
+ ],
416
+ Boolean(typesEntryPath) && [
417
+ typesEntryPath,
418
+ 'types'
419
+ ]
420
+ ].filter(Boolean));
421
+ }
422
+ return exportToDist;
358
423
  }
359
- async function writeDefaultTsconfig(tsConfigPath) {
360
- await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
361
- logger.log(`Detected using TypeScript but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
424
+ function isEsmExportName(name, ext) {
425
+ return [
426
+ 'import',
427
+ 'module'
428
+ ].includes(name) || ext === 'mjs';
362
429
  }
363
-
364
- const FILENAME_REGEX = /__filename/;
365
- const DIRNAME_REGEX = /__dirname/;
366
- const GLOBAL_REQUIRE_REGEX = /require(\.resolve)?\(/;
367
- const PolyfillComment = '/** rollup-private-do-not-use-esm-shim-polyfill */';
368
- const createESMShim = ({ filename, dirname, globalRequire })=>{
369
- const useNodeUrl = filename || dirname;
370
- const useNodePath = dirname;
371
- const useNodeModule = globalRequire;
372
- return `\
373
- ${PolyfillComment}
374
- ${useNodeUrl ? `import __node_cjsUrl from 'node:url'` : ''};
375
- ${useNodePath ? `import __node_cjsPath from 'node:path';` : ''}
376
- ${useNodeModule ? `import __node_cjsModule from 'node:module';` : ''}
377
- ${useNodeUrl ? 'const __filename = __node_cjsUrl.fileURLToPath(import.meta.url);' : ''}
378
- ${useNodePath ? 'const __dirname = __node_cjsPath.dirname(__filename);' : ''}
379
- ${useNodeModule ? 'const require = __node_cjsModule.createRequire(import.meta.url);' : ''}
380
- `.trim() + '\n';
381
- };
382
- function esmShim() {
383
- return {
384
- name: 'esm-shim',
385
- transform: {
386
- order: 'post',
387
- handler (code, id) {
388
- const ext = path.extname(id);
389
- if (!availableESExtensionsRegex.test(ext) || code.includes(PolyfillComment)) {
390
- return null;
391
- }
392
- let hasFilename = false;
393
- let hasDirname = false;
394
- let hasGlobalRequire = false;
395
- if (FILENAME_REGEX.test(code)) {
396
- hasFilename = true;
397
- }
398
- if (DIRNAME_REGEX.test(code)) {
399
- hasDirname = true;
400
- }
401
- if (GLOBAL_REQUIRE_REGEX.test(code)) {
402
- hasGlobalRequire = true;
403
- }
404
- if (!hasFilename && !hasDirname && !hasGlobalRequire) {
405
- return null;
406
- }
407
- const magicString = new MagicString__default.default(code);
408
- let ast = null;
409
- try {
410
- // rollup 2 built-in parser doesn't have `allowShebang`, we need to use the sliced code here. Hence the `magicString.toString()`
411
- ast = this.parse(magicString.toString(), {
412
- allowReturnOutsideFunction: true
413
- });
414
- } catch (e) {
415
- console.warn(e);
416
- return null;
417
- }
418
- if (ast.type !== 'Program') {
419
- return null;
420
- }
421
- let lastImportNode = null;
422
- for (const node of ast.body){
423
- if (node.type === 'ImportDeclaration') {
424
- lastImportNode = node;
425
- continue;
426
- }
427
- }
428
- let end = 0;
429
- if (lastImportNode) {
430
- end = lastImportNode.end;
431
- } else {
432
- end = ast.body.length > 0 ? ast.body[0].end : 0;
433
- }
434
- magicString.appendRight(end, '\n' + createESMShim({
435
- filename: hasFilename,
436
- dirname: hasDirname,
437
- globalRequire: hasGlobalRequire
438
- }));
439
- return {
440
- code: magicString.toString(),
441
- map: magicString.generateMap({
442
- hires: true
443
- })
444
- };
445
- }
446
- }
447
- };
430
+ function isCjsExportName(pkg, exportCondition, ext) {
431
+ const isESModule = isESModulePackage(pkg.type);
432
+ const isCjsCondition = [
433
+ 'require',
434
+ 'main'
435
+ ].includes(exportCondition);
436
+ const isNotEsmExportName = !isEsmExportName(exportCondition, ext);
437
+ return !isESModule && isNotEsmExportName && (ext !== 'mjs' || isCjsCondition) || ext === 'cjs';
448
438
  }
449
-
450
- const helpers = {
451
- cssImport: {
452
- // have to assign r.type = 'text/css' to make it work in Safari
453
- global: `\
454
- function __insertCSS(code) {
455
- if (!code || typeof document == 'undefined') return
456
- let head = document.head || document.getElementsByTagName('head')[0]
457
- let style = document.createElement('style')
458
- style.type = 'text/css'
459
- head.appendChild(style)
460
- ;style.styleSheet ? (style.styleSheet.cssText = code) : style.appendChild(document.createTextNode(code))
439
+ function getFileExportType(composedTypes) {
440
+ return composedTypes.split('.').pop();
461
441
  }
462
- `,
463
- create (code) {
464
- return `__insertCSS(${JSON.stringify(code)});`;
442
+ function getExportsDistFilesOfCondition(pkg, parsedExportCondition, cwd, dts) {
443
+ const dist = [];
444
+ const exportConditionNames = Object.keys(parsedExportCondition.export);
445
+ const uniqueFiles = new Set();
446
+ for (const exportCondition of exportConditionNames){
447
+ const exportType = getFileExportType(exportCondition);
448
+ // Filter out non-types field when generating types jobs
449
+ if (dts && exportType !== 'types') {
450
+ continue;
465
451
  }
466
- },
467
- cssAssertionImport: {
468
- global: '',
469
- create (code) {
470
- return `\
471
- const sheet = new CSSStyleSheet()
472
- sheet.replaceSync(${JSON.stringify(code)})
473
- export default sheet`;
452
+ // Filter out types field when generating asset jobs
453
+ if (!dts && exportType === 'types') {
454
+ continue;
455
+ }
456
+ const filePath = parsedExportCondition.export[exportCondition];
457
+ const ext = path.extname(filePath).slice(1);
458
+ const relativePath = parsedExportCondition.export[exportCondition];
459
+ const distFile = path.resolve(cwd, relativePath);
460
+ const format = isCjsExportName(pkg, exportCondition, ext) ? 'cjs' : 'esm';
461
+ if (uniqueFiles.has(distFile)) {
462
+ continue;
474
463
  }
464
+ uniqueFiles.add(distFile);
465
+ dist.push({
466
+ format,
467
+ file: distFile,
468
+ exportCondition
469
+ });
475
470
  }
476
- };
477
- const cleanCssInstance = new CleanCSS__default.default({});
478
- function minify(code) {
479
- return cleanCssInstance.minify(code).styles;
471
+ return dist;
480
472
  }
481
- function inlineCss(options) {
482
- const cssIds = new Set();
483
- var _options_exclude;
484
- const filter = pluginutils.createFilter([
485
- '**/*.css'
486
- ], (_options_exclude = options.exclude) != null ? _options_exclude : []);
487
- // Follow up for rollup 4 for better support of assertion support https://github.com/rollup/rollup/issues/4818
488
- return {
489
- name: 'inline-css',
490
- transform: {
491
- order: 'post',
492
- handler (code, id) {
493
- if (!filter(id)) return;
494
- if (options.skip) return '';
495
- const cssCode = minify(code);
496
- cssIds.add(id);
497
- return {
498
- code: helpers.cssImport.create(cssCode),
499
- map: {
500
- mappings: ''
501
- }
502
- };
503
- }
504
- },
505
- renderChunk: {
506
- order: 'pre',
507
- handler (code) {
508
- const dependenciesIds = this.getModuleIds();
509
- let foundCss = false;
510
- for (const depId of dependenciesIds){
511
- if (depId && cssIds.has(depId)) {
512
- foundCss = true;
513
- break;
514
- }
515
- }
516
- if (!foundCss) return;
517
- return {
518
- code: `${helpers.cssImport.global}\n${code}`,
519
- map: {
520
- mappings: ''
521
- }
522
- };
523
- }
524
- }
525
- };
473
+ function getExportFileTypePath(absoluteJsBundlePath) {
474
+ const dirName = path.dirname(absoluteJsBundlePath);
475
+ const baseName = baseNameWithoutExtension(absoluteJsBundlePath);
476
+ const ext = path.extname(absoluteJsBundlePath).slice(1);
477
+ const typeExtension = dtsExtensionsMap[ext];
478
+ return path.join(dirName, baseName + '.' + typeExtension);
526
479
  }
527
-
528
- function rawContent({ exclude }) {
529
- const filter = pluginutils.createFilter([
530
- '**/*.data',
531
- '**/*.txt'
532
- ], exclude);
533
- return {
534
- name: 'string',
535
- transform (code, id) {
536
- if (filter(id)) {
537
- return {
538
- code: `const data = ${JSON.stringify(code)};\nexport default data;`,
539
- map: null
540
- };
541
- }
542
- return null;
543
- }
544
- };
480
+ function getExportTypeFromFile(filename, pkgType) {
481
+ const isESModule = isESModulePackage(pkgType);
482
+ const isCjsExt = filename.endsWith('.cjs');
483
+ const isEsmExt = filename.endsWith('.mjs');
484
+ const exportType = isEsmExt ? 'import' : isCjsExt ? 'require' : isESModule ? 'import' : 'require';
485
+ return exportType;
545
486
  }
546
487
 
547
488
  function relativify(path) {
548
489
  return path.startsWith('.') ? path : `./${path}`;
549
490
  }
550
491
 
551
- // Alias entries to import path
552
- // e.g.
553
- // For a resolved file, if it's one of the entries,
554
- // aliases it as export path, such as <absolute file> -> <pkg>/<export path>
555
- function aliasEntries({ entry, entries, entriesAlias, format, dts, cwd }) {
556
- const entryAliasWithoutSelf = {
557
- ...entriesAlias,
558
- [entry]: null
559
- };
560
- const pathToRelativeDistMap = new Map();
561
- for (const [, exportCondition] of Object.entries(entries)){
562
- const exportDistMaps = exportCondition.export;
563
- if (dts) {
564
- var _Object_entries_find;
565
- // Search types + [format] condition from entries map
566
- // e.g. import.types, require.types
567
- const typeCond = (_Object_entries_find = Object.entries(exportDistMaps).find(([composedKey, cond])=>{
568
- const typesSet = new Set(composedKey.split('.'));
569
- const formatCond = format === 'cjs' ? 'require' : 'import';
570
- const isMatchedCond = typesSet.has(formatCond) || !typesSet.has('import') && !typesSet.has('require');
571
- return typesSet.has('types') && isMatchedCond && cond != null;
572
- })) == null ? void 0 : _Object_entries_find[1];
573
- if (typeCond) {
574
- pathToRelativeDistMap.set(exportCondition.source, typeCond);
492
+ // shared.ts -> ./shared
493
+ // shared.<export condition>.ts -> ./shared
494
+ // index.ts -> ./index
495
+ // index.development.ts -> ./index.development
496
+ function sourceFilenameToExportFullPath(filename) {
497
+ const baseName = baseNameWithoutExtension(filename);
498
+ let exportPath = baseName;
499
+ return relativify(exportPath);
500
+ }
501
+ async function collectEntriesFromParsedExports(cwd, parsedExportsInfo, sourceFile) {
502
+ const entries = {};
503
+ if (sourceFile) {
504
+ const defaultExport = parsedExportsInfo.get('./index')[0];
505
+ entries['./index'] = {
506
+ source: sourceFile,
507
+ name: '.',
508
+ export: {
509
+ default: defaultExport[0]
575
510
  }
576
- }
511
+ };
577
512
  }
578
- return {
579
- name: 'alias',
580
- resolveId: {
581
- async handler (source, importer, options) {
582
- const resolved = await this.resolve(source, importer, options);
583
- if (resolved != null) {
584
- if (dts) {
585
- // For types, generate relative path to the other type files,
586
- // this will be compatible for the node10 ts module resolution.
587
- const resolvedDist = pathToRelativeDistMap.get(resolved.id);
588
- const entryDist = pathToRelativeDistMap.get(entry);
589
- if (resolved.id !== entry && entryDist && resolvedDist) {
590
- const absoluteEntryDist = path__default.default.resolve(cwd, entryDist);
591
- const absoluteResolvedDist = path__default.default.resolve(cwd, resolvedDist);
592
- const filePathBase = path__default.default.relative(path__default.default.dirname(absoluteEntryDist), absoluteResolvedDist);
593
- const relativePath = relativify(filePathBase);
594
- return {
595
- id: relativePath,
596
- external: true
597
- };
598
- }
599
- } else {
600
- const aliasedId = entryAliasWithoutSelf[resolved.id];
601
- if (aliasedId != null) {
602
- return {
603
- id: aliasedId
604
- };
605
- }
606
- }
607
- }
608
- return null;
609
- }
513
+ // Find source files
514
+ const { bins, exportsEntries } = await collectSourceEntriesFromExportPaths(path.join(cwd, SRC), parsedExportsInfo);
515
+ // A mapping between each export path and its related special export conditions,
516
+ // excluding the 'default' export condition.
517
+ // { './index' => Set('development', 'edge-light') }
518
+ const pathSpecialConditionsMap = {};
519
+ for (const [exportPath] of exportsEntries){
520
+ const normalizedExportPath = stripSpecialCondition(exportPath);
521
+ if (!pathSpecialConditionsMap[normalizedExportPath]) {
522
+ pathSpecialConditionsMap[normalizedExportPath] = new Set();
610
523
  }
611
- };
612
- }
613
-
614
- function prependDirectives() {
615
- return {
616
- name: 'prependDirective',
617
- transform: {
618
- order: 'post',
619
- handler (code, id) {
620
- var _moduleInfo_meta;
621
- const moduleInfo = this.getModuleInfo(id);
622
- if (moduleInfo == null ? void 0 : (_moduleInfo_meta = moduleInfo.meta) == null ? void 0 : _moduleInfo_meta.preserveDirectives) {
623
- const firstDirective = moduleInfo.meta.preserveDirectives.directives[0];
624
- if (firstDirective) {
625
- const directive = firstDirective.value;
626
- const directiveCode = `'${directive}';`;
627
- return directiveCode + '\n' + code;
628
- }
629
- }
630
- return null;
631
- }
524
+ const exportType = getExportTypeFromExportPath(exportPath);
525
+ if (exportType !== 'default') {
526
+ pathSpecialConditionsMap[normalizedExportPath].add(exportType);
632
527
  }
633
- };
634
- }
635
-
636
- const prependShebang = (entry)=>({
637
- name: 'prependShebang',
638
- transform: (code, id)=>{
639
- if (id !== entry) return;
640
- const shebang = '#!/usr/bin/env node\n';
641
- if (code.startsWith(shebang)) return;
642
- const magicString = new MagicString__default.default(code);
643
- magicString.prepend(shebang);
644
- return {
645
- code: magicString.toString(),
646
- map: magicString.generateMap({
647
- hires: true
648
- })
649
- };
528
+ }
529
+ // Traverse source files and try to match the entries
530
+ // Find exports from parsed exports info
531
+ // entryExportPath can be: './index', './index.development', './shared.edge-light', etc.
532
+ for (const [entryExportPath, sourceFilesMap] of exportsEntries){
533
+ const normalizedExportPath = stripSpecialCondition(entryExportPath);
534
+ const entryExportPathType = getExportTypeFromExportPath(entryExportPath);
535
+ const outputExports = parsedExportsInfo.get(normalizedExportPath);
536
+ if (!outputExports) {
537
+ continue;
650
538
  }
651
- });
652
-
653
- function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exportToDist) {
654
- // End of searching, export value is file path.
655
- // <export key>: <export value> (string)
656
- if (typeof exportValue === 'string') {
657
- const composedTypes = new Set(exportTypes);
658
- const exportType = exportKey.startsWith('.') ? 'default' : exportKey;
659
- composedTypes.add(exportType);
660
- const exportInfo = exportToDist.get(mapExportFullPath(currentPath));
661
- const exportCondition = Array.from(composedTypes).join('.');
662
- if (!exportInfo) {
663
- const outputConditionPair = [
664
- exportValue,
665
- exportCondition
666
- ];
667
- addToExportDistMap(exportToDist, currentPath, [
668
- outputConditionPair
669
- ], runtimeExportConventions.has(exportType) ? exportType : undefined);
670
- } else {
671
- exportInfo.push([
672
- exportValue,
673
- exportCondition
674
- ]);
539
+ for (const [outputPath, outputComposedExportType] of outputExports){
540
+ // export type can be: default, development, react-server, etc.
541
+ const matchedExportType = getSpecialExportTypeFromComposedExportPath(outputComposedExportType);
542
+ const specialSet = pathSpecialConditionsMap[normalizedExportPath];
543
+ const hasSpecialEntry = specialSet.has(matchedExportType);
544
+ const sourceFile = sourceFilesMap[matchedExportType] || sourceFilesMap.default;
545
+ if (!sourceFile) {
546
+ continue;
547
+ }
548
+ if (!entries[entryExportPath]) {
549
+ entries[entryExportPath] = {
550
+ source: sourceFile,
551
+ name: normalizedExportPath,
552
+ export: {}
553
+ };
554
+ } else if (matchedExportType === entryExportPathType) {
555
+ entries[entryExportPath].source = sourceFile;
556
+ }
557
+ // output exports match
558
+ if (matchedExportType === entryExportPathType || !hasSpecialEntry && matchedExportType !== 'default') {
559
+ const exportMap = entries[entryExportPath].export;
560
+ exportMap[outputComposedExportType] = outputPath;
561
+ }
675
562
  }
676
- return;
677
563
  }
678
- const exportKeys = Object.keys(exportValue);
679
- for (const exportKey of exportKeys){
680
- // Clone the set to avoid modifying the parent set
681
- const childExports = new Set(exportTypes);
682
- // Normalize child export value to a map
683
- const childExportValue = exportValue[exportKey];
684
- // Visit export path: ./subpath, ./subpath2, ...
685
- if (exportKey.startsWith('.')) {
686
- const childPath = joinRelativePath(currentPath, exportKey);
687
- collectExportPath(childExportValue, exportKey, childPath, childExports, exportToDist);
688
- } else {
689
- // Visit export type: import, require, ...
690
- childExports.add(exportKey);
691
- collectExportPath(childExportValue, exportKey, currentPath, childExports, exportToDist);
564
+ // Handling binaries
565
+ for (const [exportPath, sourceFile] of bins){
566
+ const outputExports = parsedExportsInfo.get(exportPath);
567
+ if (!outputExports) {
568
+ continue;
569
+ }
570
+ for (const [outputPath, exportType] of outputExports){
571
+ entries[exportPath] = {
572
+ source: sourceFile,
573
+ name: exportPath,
574
+ export: {
575
+ [exportType]: outputPath
576
+ }
577
+ };
692
578
  }
693
579
  }
580
+ return entries;
694
581
  }
695
- const mapExportFullPath = (exportPath)=>exportPath === '.' ? './index' : exportPath;
696
- function addToExportDistMap(exportToDist, exportPath, outputConditionPairs, specialExportType) {
697
- const fullPath = mapExportFullPath(exportPath);
698
- // + (specialExportType ? '.' + specialExportType : '')
699
- const existingExportInfo = exportToDist.get(fullPath);
700
- if (!existingExportInfo) {
701
- exportToDist.set(fullPath, outputConditionPairs);
702
- } else {
703
- existingExportInfo.push(...outputConditionPairs);
704
- }
582
+ // ./index -> default
583
+ // ./index.development -> development
584
+ // ./index.react-server -> react-server
585
+ function getExportTypeFromExportPath(exportPath) {
586
+ // Skip the first two segments: `.` and `index`
587
+ const exportTypes = exportPath.split('.').slice(2);
588
+ return getExportTypeFromExportTypesArray(exportTypes);
705
589
  }
706
- /**
707
- * parseExports - parse package.exports field and other fields like main,module to a map
708
- *
709
- * map from export path to output path and export conditions
710
- *
711
- * exportToDist: {
712
- * './index': { development: ..., default: ... }
713
- * './index.react-server': { development: ..., default: ... }
714
- * }
715
- */ function parseExports(pkg) {
716
- var _pkg_exports;
717
- const exportsField = (_pkg_exports = pkg.exports) != null ? _pkg_exports : {};
718
- var _pkg_bin;
719
- const bins = (_pkg_bin = pkg.bin) != null ? _pkg_bin : {};
720
- const exportToDist = new Map();
721
- const isEsmPkg = isESModulePackage(pkg.type);
722
- const defaultCondition = isEsmPkg ? 'import' : 'require';
723
- let currentPath = '.';
724
- if (typeof exportsField === 'string') {
725
- const outputConditionPair = [
726
- exportsField,
727
- defaultCondition
728
- ];
729
- addToExportDistMap(exportToDist, currentPath, [
730
- outputConditionPair
731
- ]);
732
- } else {
733
- // keys means unknown if they're relative path or export type
734
- const exportConditionKeys = Object.keys(exportsField);
735
- for (const exportKey of exportConditionKeys){
736
- const exportValue = exportsField[exportKey];
737
- const exportTypes = new Set();
738
- const isExportPath = exportKey.startsWith('.');
739
- const childPath = isExportPath ? joinRelativePath(currentPath, exportKey) : currentPath;
740
- if (!isExportPath) {
741
- exportTypes.add(exportKey);
742
- }
743
- collectExportPath(exportValue, exportKey, childPath, exportTypes, exportToDist);
590
+ function getSpecialExportTypeFromComposedExportPath(composedExportType) {
591
+ const exportTypes = composedExportType.split('.');
592
+ for (const exportType of exportTypes){
593
+ if (specialExportConventions.has(exportType)) {
594
+ return exportType;
744
595
  }
745
596
  }
746
- if (typeof bins === 'string') {
747
- const outputConditionPair = [
748
- bins,
749
- defaultCondition
750
- ];
751
- addToExportDistMap(exportToDist, BINARY_TAG, [
752
- outputConditionPair
753
- ]);
754
- } else {
755
- for (const binName of Object.keys(bins)){
756
- const binDistPath = bins[binName];
757
- const exportType = getExportTypeFromFile(binDistPath, pkg.type);
758
- const exportPath = path.posix.join(BINARY_TAG, binName);
759
- const outputConditionPair = [
760
- binDistPath,
761
- exportType
762
- ];
763
- addToExportDistMap(exportToDist, exportPath, [
764
- outputConditionPair
765
- ]);
597
+ return 'default';
598
+ }
599
+ function getExportTypeFromExportTypesArray(types) {
600
+ let exportType = 'default';
601
+ new Set(types).forEach((value)=>{
602
+ if (specialExportConventions.has(value)) {
603
+ exportType = value;
604
+ } else if (value === 'import' || value === 'require' || value === 'types') {
605
+ exportType = value;
606
+ }
607
+ });
608
+ return exportType;
609
+ }
610
+ // ./index -> .
611
+ // ./index.development -> .
612
+ // ./index.react-server -> .
613
+ // ./shared -> ./shared
614
+ // ./shared.development -> ./shared
615
+ // $binary -> $binary
616
+ // $binary/index -> $binary
617
+ // $binary/foo -> $binary/foo
618
+ function normalizeExportPath(exportPath) {
619
+ if (exportPath.startsWith(BINARY_TAG)) {
620
+ if (exportPath === `${BINARY_TAG}/index`) {
621
+ exportPath = BINARY_TAG;
766
622
  }
623
+ return exportPath;
767
624
  }
768
- // Handle package.json global exports fields
769
- if (pkg.main || pkg.module || pkg.types) {
770
- const mainExportPath = pkg.main;
771
- const moduleExportPath = pkg.module;
772
- const typesEntryPath = pkg.types;
773
- addToExportDistMap(exportToDist, './index', [
774
- Boolean(mainExportPath) && [
775
- mainExportPath,
776
- getMainFieldExportType(pkg)
777
- ],
778
- Boolean(moduleExportPath) && [
779
- moduleExportPath,
780
- 'module'
781
- ],
782
- Boolean(typesEntryPath) && [
783
- typesEntryPath,
784
- 'types'
785
- ]
786
- ].filter(Boolean));
625
+ const baseName = exportPath.split('.').slice(0, 2).join('.');
626
+ if (baseName === './index') {
627
+ return '.';
787
628
  }
788
- return exportToDist;
789
- }
790
- function isEsmExportName(name, ext) {
791
- return [
792
- 'import',
793
- 'module'
794
- ].includes(name) || ext === 'mjs';
795
- }
796
- function isCjsExportName(pkg, exportCondition, ext) {
797
- const isESModule = isESModulePackage(pkg.type);
798
- const isCjsCondition = [
799
- 'require',
800
- 'main'
801
- ].includes(exportCondition);
802
- const isNotEsmExportName = !isEsmExportName(exportCondition, ext);
803
- return !isESModule && isNotEsmExportName && (ext !== 'mjs' || isCjsCondition) || ext === 'cjs';
804
- }
805
- function getFileExportType(composedTypes) {
806
- return composedTypes.split('.').pop();
807
- }
808
- function getExportsDistFilesOfCondition(pkg, parsedExportCondition, cwd, dts) {
809
- const dist = [];
810
- const exportConditionNames = Object.keys(parsedExportCondition.export);
811
- const uniqueFiles = new Set();
812
- for (const exportCondition of exportConditionNames){
813
- const exportType = getFileExportType(exportCondition);
814
- // Filter out non-types field when generating types jobs
815
- if (dts && exportType !== 'types') {
816
- continue;
817
- }
818
- // Filter out types field when generating asset jobs
819
- if (!dts && exportType === 'types') {
820
- continue;
821
- }
822
- const filePath = parsedExportCondition.export[exportCondition];
823
- const ext = path.extname(filePath).slice(1);
824
- const relativePath = parsedExportCondition.export[exportCondition];
825
- const distFile = path.resolve(cwd, relativePath);
826
- const format = isCjsExportName(pkg, exportCondition, ext) ? 'cjs' : 'esm';
827
- if (uniqueFiles.has(distFile)) {
828
- continue;
829
- }
830
- uniqueFiles.add(distFile);
831
- dist.push({
832
- format,
833
- file: distFile,
834
- exportCondition
835
- });
836
- }
837
- return dist;
838
- }
839
- function getExportFileTypePath(absoluteJsBundlePath) {
840
- const dirName = path.dirname(absoluteJsBundlePath);
841
- const baseName = baseNameWithoutExtension(absoluteJsBundlePath);
842
- const ext = path.extname(absoluteJsBundlePath).slice(1);
843
- const typeExtension = dtsExtensionsMap[ext];
844
- return path.join(dirName, baseName + '.' + typeExtension);
845
- }
846
- function getExportTypeFromFile(filename, pkgType) {
847
- const isESModule = isESModulePackage(pkgType);
848
- const isCjsExt = filename.endsWith('.cjs');
849
- const isEsmExt = filename.endsWith('.mjs');
850
- const exportType = isEsmExt ? 'import' : isCjsExt ? 'require' : isESModule ? 'import' : 'require';
851
- return exportType;
852
- }
853
-
854
- /**
855
- * @return {Record<string, string>} env { 'process.env.<key>': '<value>' }
856
- */ function getDefinedInlineVariables(envs, parsedExportCondition) {
857
- if (!envs.includes('NODE_ENV')) {
858
- envs.push('NODE_ENV');
859
- }
860
- const envVars = envs.reduce((acc, key)=>{
861
- const value = process.env[key];
862
- if (typeof value !== 'undefined') {
863
- acc['process.env.' + key] = JSON.stringify(value);
864
- }
865
- return acc;
866
- }, {});
867
- const exportConditionNames = Object.keys(parsedExportCondition.export).reduce((acc, key)=>{
868
- // key could be 'require' or 'import.development' etc.
869
- const exportTypes = key.split('.');
870
- for (const exportType of exportTypes){
871
- acc.add(exportType);
872
- }
873
- return acc;
874
- }, new Set());
875
- // For development and production convention, we override the NODE_ENV value
876
- if (exportConditionNames.has('development')) {
877
- envVars['process.env.NODE_ENV'] = JSON.stringify('development');
878
- } else if (exportConditionNames.has('production')) {
879
- envVars['process.env.NODE_ENV'] = JSON.stringify('production');
880
- }
881
- if (exportConditionNames.has('edge-light')) {
882
- envVars['EdgeRuntime'] = JSON.stringify('edge-runtime');
883
- }
884
- return envVars;
885
- }
886
-
887
- // shared.ts -> ./shared
888
- // shared.<export condition>.ts -> ./shared
889
- // index.ts -> ./index
890
- // index.development.ts -> ./index.development
891
- function sourceFilenameToExportFullPath(filename) {
892
- const baseName = baseNameWithoutExtension(filename);
893
- let exportPath = baseName;
894
- return relativify(exportPath);
895
- }
896
- async function collectEntriesFromParsedExports(cwd, parsedExportsInfo, sourceFile) {
897
- const entries = {};
898
- if (sourceFile) {
899
- const defaultExport = parsedExportsInfo.get('./index')[0];
900
- entries['./index'] = {
901
- source: sourceFile,
902
- name: '.',
903
- export: {
904
- default: defaultExport[0]
905
- }
906
- };
907
- }
908
- // Find source files
909
- const { bins, exportsEntries } = await collectSourceEntriesFromExportPaths(path.join(cwd, SRC), parsedExportsInfo);
910
- // A mapping between each export path and its related special export conditions,
911
- // excluding the 'default' export condition.
912
- // { './index' => Set('development', 'edge-light') }
913
- const pathSpecialConditionsMap = {};
914
- for (const [exportPath] of exportsEntries){
915
- const normalizedExportPath = stripSpecialCondition(exportPath);
916
- if (!pathSpecialConditionsMap[normalizedExportPath]) {
917
- pathSpecialConditionsMap[normalizedExportPath] = new Set();
918
- }
919
- const exportType = getExportTypeFromExportPath(exportPath);
920
- if (exportType !== 'default') {
921
- pathSpecialConditionsMap[normalizedExportPath].add(exportType);
922
- }
923
- }
924
- // Traverse source files and try to match the entries
925
- // Find exports from parsed exports info
926
- // entryExportPath can be: './index', './index.development', './shared.edge-light', etc.
927
- for (const [entryExportPath, sourceFilesMap] of exportsEntries){
928
- const normalizedExportPath = stripSpecialCondition(entryExportPath);
929
- const entryExportPathType = getExportTypeFromExportPath(entryExportPath);
930
- const outputExports = parsedExportsInfo.get(normalizedExportPath);
931
- if (!outputExports) {
932
- continue;
933
- }
934
- for (const [outputPath, outputComposedExportType] of outputExports){
935
- // export type can be: default, development, react-server, etc.
936
- const matchedExportType = getSpecialExportTypeFromComposedExportPath(outputComposedExportType);
937
- const specialSet = pathSpecialConditionsMap[normalizedExportPath];
938
- const hasSpecialEntry = specialSet.has(matchedExportType);
939
- const sourceFile = sourceFilesMap[matchedExportType] || sourceFilesMap.default;
940
- if (!sourceFile) {
941
- continue;
942
- }
943
- if (!entries[entryExportPath]) {
944
- entries[entryExportPath] = {
945
- source: sourceFile,
946
- name: normalizedExportPath,
947
- export: {}
948
- };
949
- } else if (matchedExportType === entryExportPathType) {
950
- entries[entryExportPath].source = sourceFile;
951
- }
952
- // output exports match
953
- if (matchedExportType === entryExportPathType || !hasSpecialEntry && matchedExportType !== 'default') {
954
- const exportMap = entries[entryExportPath].export;
955
- exportMap[outputComposedExportType] = outputPath;
956
- }
957
- }
958
- }
959
- // Handling binaries
960
- for (const [exportPath, sourceFile] of bins){
961
- const outputExports = parsedExportsInfo.get(exportPath);
962
- if (!outputExports) {
963
- continue;
964
- }
965
- for (const [outputPath, exportType] of outputExports){
966
- entries[exportPath] = {
967
- source: sourceFile,
968
- name: exportPath,
969
- export: {
970
- [exportType]: outputPath
971
- }
972
- };
973
- }
974
- }
975
- return entries;
976
- }
977
- // ./index -> default
978
- // ./index.development -> development
979
- // ./index.react-server -> react-server
980
- function getExportTypeFromExportPath(exportPath) {
981
- // Skip the first two segments: `.` and `index`
982
- const exportTypes = exportPath.split('.').slice(2);
983
- return getExportTypeFromExportTypesArray(exportTypes);
984
- }
985
- function getSpecialExportTypeFromComposedExportPath(composedExportType) {
986
- const exportTypes = composedExportType.split('.');
987
- for (const exportType of exportTypes){
988
- if (specialExportConventions.has(exportType)) {
989
- return exportType;
990
- }
991
- }
992
- return 'default';
993
- }
994
- function getExportTypeFromExportTypesArray(types) {
995
- let exportType = 'default';
996
- new Set(types).forEach((value)=>{
997
- if (specialExportConventions.has(value)) {
998
- exportType = value;
999
- } else if (value === 'import' || value === 'require' || value === 'types') {
1000
- exportType = value;
1001
- }
1002
- });
1003
- return exportType;
1004
- }
1005
- // ./index -> .
1006
- // ./index.development -> .
1007
- // ./index.react-server -> .
1008
- // ./shared -> ./shared
1009
- // ./shared.development -> ./shared
1010
- // $binary -> $binary
1011
- // $binary/index -> $binary
1012
- // $binary/foo -> $binary/foo
1013
- function normalizeExportPath(exportPath) {
1014
- if (exportPath.startsWith(BINARY_TAG)) {
1015
- if (exportPath === `${BINARY_TAG}/index`) {
1016
- exportPath = BINARY_TAG;
1017
- }
1018
- return exportPath;
1019
- }
1020
- const baseName = exportPath.split('.').slice(0, 2).join('.');
1021
- if (baseName === './index') {
1022
- return '.';
1023
- }
1024
- return baseName;
629
+ return baseName;
1025
630
  }
1026
631
  // ./index.react-server -> ./index
1027
632
  function stripSpecialCondition(exportPath) {
@@ -1072,80 +677,544 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
1072
677
  }
1073
678
  }
1074
679
  }
1075
- } else {
1076
- // subpath could be a file
1077
- const dirName = path.dirname(subpath);
1078
- const baseName = path.basename(subpath);
1079
- // Read current file's directory
1080
- const dirPath = path__default.default.join(sourceFolderPath, dirName);
1081
- if (!fs__default.default.existsSync(dirPath)) {
1082
- return;
1083
- }
1084
- const dirents = await fsp__default.default.readdir(dirPath, {
1085
- withFileTypes: true
1086
- });
1087
- for (const dirent of dirents){
1088
- // index.development.js -> index.development
1089
- const direntBaseName = baseNameWithoutExtension(dirent.name);
1090
- const ext = path.extname(dirent.name).slice(1);
1091
- if (!dirent.isFile() || direntBaseName !== baseName || !availableExtensions.has(ext)) {
1092
- continue;
680
+ } else {
681
+ // subpath could be a file
682
+ const dirName = path.dirname(subpath);
683
+ const baseName = path.basename(subpath);
684
+ // Read current file's directory
685
+ const dirPath = path__default.default.join(sourceFolderPath, dirName);
686
+ if (!fs__default.default.existsSync(dirPath)) {
687
+ return;
688
+ }
689
+ const dirents = await fsp__default.default.readdir(dirPath, {
690
+ withFileTypes: true
691
+ });
692
+ for (const dirent of dirents){
693
+ // index.development.js -> index.development
694
+ const direntBaseName = baseNameWithoutExtension(dirent.name);
695
+ const ext = path.extname(dirent.name).slice(1);
696
+ if (!dirent.isFile() || direntBaseName !== baseName || !availableExtensions.has(ext)) {
697
+ continue;
698
+ }
699
+ if (isTestFile(dirent.name)) {
700
+ continue;
701
+ }
702
+ const sourceFileAbsolutePath = path__default.default.join(dirPath, dirent.name);
703
+ if (isBinaryPath) {
704
+ bins.set(originalSubpath, sourceFileAbsolutePath);
705
+ } else {
706
+ let sourceFilesMap = exportsEntries.get(originalSubpath) || {};
707
+ const exportType = getExportTypeFromExportPath(originalSubpath);
708
+ sourceFilesMap[exportType] = sourceFileAbsolutePath;
709
+ if (specialExportConventions.has(exportType)) {
710
+ // e.g. ./foo/index.react-server -> ./foo/index
711
+ const fallbackExportPath = sourceFilenameToExportFullPath(originalSubpath);
712
+ const fallbackSourceFilesMap = exportsEntries.get(fallbackExportPath) || {};
713
+ sourceFilesMap = {
714
+ ...fallbackSourceFilesMap,
715
+ ...sourceFilesMap
716
+ };
717
+ }
718
+ exportsEntries.set(originalSubpath, sourceFilesMap);
719
+ }
720
+ }
721
+ }
722
+ }
723
+ /**
724
+ * exportsEntries {
725
+ * "./index" => {
726
+ * "development" => source"
727
+ * "react-server" => "source"
728
+ * },
729
+ * "./index.react-server" => {
730
+ * "development" => source"
731
+ * "react-server" => "source"
732
+ * }
733
+ * }
734
+ */ async function collectSourceEntriesFromExportPaths(sourceFolderPath, parsedExportsInfo) {
735
+ const bins = new Map();
736
+ const exportsEntries = new Map();
737
+ for (const [exportPath, exportInfo] of parsedExportsInfo.entries()){
738
+ const specialConditions = new Set();
739
+ for (const [_, composedExportType] of exportInfo){
740
+ const specialExportType = getSpecialExportTypeFromComposedExportPath(composedExportType);
741
+ if (specialExportType !== 'default') {
742
+ specialConditions.add(specialExportType);
743
+ }
744
+ }
745
+ await collectSourceEntriesByExportPath(sourceFolderPath, exportPath, bins, exportsEntries);
746
+ for (const specialCondition of specialConditions){
747
+ await collectSourceEntriesByExportPath(sourceFolderPath, exportPath + '.' + specialCondition, bins, exportsEntries);
748
+ }
749
+ }
750
+ return {
751
+ bins,
752
+ exportsEntries
753
+ };
754
+ }
755
+
756
+ // Example: @foo/bar -> bar
757
+ const removeScope = (exportPath)=>exportPath.replace(/^@[^/]+\//, '');
758
+ function createOutputState({ entries }) {
759
+ const sizeStats = new Map();
760
+ const uniqFiles = new Set();
761
+ function addSize({ fileName, size, sourceFileName, exportPath }) {
762
+ if (!sizeStats.has(exportPath)) {
763
+ sizeStats.set(exportPath, []);
764
+ }
765
+ const distFilesStats = sizeStats.get(exportPath);
766
+ if (!uniqFiles.has(fileName)) {
767
+ uniqFiles.add(fileName);
768
+ if (distFilesStats) {
769
+ distFilesStats.push([
770
+ fileName,
771
+ sourceFileName,
772
+ size
773
+ ]);
774
+ }
775
+ }
776
+ }
777
+ const reversedMapping = new Map();
778
+ Object.entries(entries).forEach(([resolvedExportName, entry])=>{
779
+ reversedMapping.set(entry.source, resolvedExportName);
780
+ });
781
+ return {
782
+ plugin: (cwd)=>{
783
+ return {
784
+ name: 'collect-sizes',
785
+ writeBundle (options, bundle) {
786
+ const dir = options.dir || path__default.default.dirname(options.file);
787
+ Object.entries(bundle).forEach(([fileName, chunk])=>{
788
+ const filePath = path__default.default.join(dir, fileName);
789
+ if (chunk.type !== 'chunk') {
790
+ return;
791
+ }
792
+ if (!chunk.isEntry) {
793
+ return;
794
+ }
795
+ const size = chunk.code.length;
796
+ const sourceFileName = chunk.facadeModuleId || '';
797
+ const exportPath = removeScope(reversedMapping.get(sourceFileName) || '.');
798
+ addSize({
799
+ fileName: path__default.default.isAbsolute(cwd) ? path__default.default.relative(cwd, filePath) : filePath,
800
+ size,
801
+ sourceFileName,
802
+ exportPath
803
+ });
804
+ });
805
+ }
806
+ };
807
+ },
808
+ getSizeStats () {
809
+ return sizeStats;
810
+ }
811
+ };
812
+ }
813
+
814
+ const memoize = (fn, cacheKey, cacheArg)=>{
815
+ const cache = cacheArg || new Map();
816
+ return (...args)=>{
817
+ const key = cacheKey ? typeof cacheKey === 'function' ? cacheKey(...args) : cacheKey : JSON.stringify({
818
+ args
819
+ });
820
+ const existing = cache.get(key);
821
+ if (existing !== undefined) {
822
+ return existing;
823
+ }
824
+ const result = fn(...args);
825
+ cache.set(key, result);
826
+ return result;
827
+ };
828
+ };
829
+ const memoizeByKey = (fn)=>{
830
+ const cache = new Map();
831
+ return (cacheKey)=>memoize(fn, cacheKey, cache);
832
+ };
833
+
834
+ let hasLoggedTsWarning = false;
835
+ function resolveTypescript(cwd) {
836
+ let ts;
837
+ const m = new module$1.Module('', undefined);
838
+ m.paths = module$1.Module._nodeModulePaths(cwd);
839
+ try {
840
+ // Bun does not yet support the `Module` class properly.
841
+ if (typeof (m == null ? void 0 : m.require) === 'undefined') {
842
+ const tsPath = require.resolve('typescript', {
843
+ paths: [
844
+ cwd
845
+ ]
846
+ });
847
+ ts = require(tsPath);
848
+ } else {
849
+ ts = m.require('typescript');
850
+ }
851
+ } catch (e) {
852
+ console.error(e);
853
+ if (!hasLoggedTsWarning) {
854
+ hasLoggedTsWarning = true;
855
+ exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency');
856
+ }
857
+ }
858
+ return ts;
859
+ }
860
+ function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
861
+ let tsCompilerOptions = {};
862
+ let tsConfigPath;
863
+ tsConfigPath = path.resolve(cwd, tsconfig);
864
+ if (fileExists(tsConfigPath)) {
865
+ // Use the original ts handler to avoid memory leak
866
+ const ts = resolveTypescript(cwd);
867
+ const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
868
+ const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
869
+ tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
870
+ } else {
871
+ return null;
872
+ }
873
+ return {
874
+ tsCompilerOptions,
875
+ tsConfigPath
876
+ };
877
+ }
878
+ const resolveTsConfig = memoizeByKey(resolveTsConfigHandler)();
879
+ async function convertCompilerOptions(cwd, json) {
880
+ // Use the original ts handler to avoid memory leak
881
+ const ts = resolveTypescript(cwd);
882
+ return ts.convertCompilerOptionsFromJson(json, './');
883
+ }
884
+ async function writeDefaultTsconfig(tsConfigPath) {
885
+ await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
886
+ logger.log(`Detected using TypeScript but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
887
+ }
888
+
889
+ const FILENAME_REGEX = /__filename/;
890
+ const DIRNAME_REGEX = /__dirname/;
891
+ const GLOBAL_REQUIRE_REGEX = /require(\.resolve)?\(/;
892
+ const PolyfillComment = '/** rollup-private-do-not-use-esm-shim-polyfill */';
893
+ const createESMShim = ({ filename, dirname, globalRequire })=>{
894
+ const useNodeUrl = filename || dirname;
895
+ const useNodePath = dirname;
896
+ const useNodeModule = globalRequire;
897
+ return `\
898
+ ${PolyfillComment}
899
+ ${useNodeUrl ? `import __node_cjsUrl from 'node:url'` : ''};
900
+ ${useNodePath ? `import __node_cjsPath from 'node:path';` : ''}
901
+ ${useNodeModule ? `import __node_cjsModule from 'node:module';` : ''}
902
+ ${useNodeUrl ? 'const __filename = __node_cjsUrl.fileURLToPath(import.meta.url);' : ''}
903
+ ${useNodePath ? 'const __dirname = __node_cjsPath.dirname(__filename);' : ''}
904
+ ${useNodeModule ? 'const require = __node_cjsModule.createRequire(import.meta.url);' : ''}
905
+ `.trim() + '\n';
906
+ };
907
+ function esmShim() {
908
+ return {
909
+ name: 'esm-shim',
910
+ transform: {
911
+ order: 'post',
912
+ handler (code, id) {
913
+ const ext = path.extname(id);
914
+ if (!availableESExtensionsRegex.test(ext) || code.includes(PolyfillComment)) {
915
+ return null;
916
+ }
917
+ let hasFilename = false;
918
+ let hasDirname = false;
919
+ let hasGlobalRequire = false;
920
+ if (FILENAME_REGEX.test(code)) {
921
+ hasFilename = true;
922
+ }
923
+ if (DIRNAME_REGEX.test(code)) {
924
+ hasDirname = true;
925
+ }
926
+ if (GLOBAL_REQUIRE_REGEX.test(code)) {
927
+ hasGlobalRequire = true;
928
+ }
929
+ if (!hasFilename && !hasDirname && !hasGlobalRequire) {
930
+ return null;
931
+ }
932
+ const magicString = new MagicString__default.default(code);
933
+ let ast = null;
934
+ try {
935
+ // rollup 2 built-in parser doesn't have `allowShebang`, we need to use the sliced code here. Hence the `magicString.toString()`
936
+ ast = this.parse(magicString.toString(), {
937
+ allowReturnOutsideFunction: true
938
+ });
939
+ } catch (e) {
940
+ console.warn(e);
941
+ return null;
942
+ }
943
+ if (ast.type !== 'Program') {
944
+ return null;
945
+ }
946
+ let lastImportNode = null;
947
+ for (const node of ast.body){
948
+ if (node.type === 'ImportDeclaration') {
949
+ lastImportNode = node;
950
+ continue;
951
+ }
952
+ }
953
+ let end = 0;
954
+ if (lastImportNode) {
955
+ end = lastImportNode.end;
956
+ } else {
957
+ end = ast.body.length > 0 ? ast.body[0].end : 0;
958
+ }
959
+ magicString.appendRight(end, '\n' + createESMShim({
960
+ filename: hasFilename,
961
+ dirname: hasDirname,
962
+ globalRequire: hasGlobalRequire
963
+ }));
964
+ return {
965
+ code: magicString.toString(),
966
+ map: magicString.generateMap({
967
+ hires: true
968
+ })
969
+ };
970
+ }
971
+ }
972
+ };
973
+ }
974
+
975
+ const helpers = {
976
+ cssImport: {
977
+ // have to assign r.type = 'text/css' to make it work in Safari
978
+ global: `\
979
+ function __insertCSS(code) {
980
+ if (!code || typeof document == 'undefined') return
981
+ let head = document.head || document.getElementsByTagName('head')[0]
982
+ let style = document.createElement('style')
983
+ style.type = 'text/css'
984
+ head.appendChild(style)
985
+ ;style.styleSheet ? (style.styleSheet.cssText = code) : style.appendChild(document.createTextNode(code))
986
+ }
987
+ `,
988
+ create (code) {
989
+ return `__insertCSS(${JSON.stringify(code)});`;
990
+ }
991
+ },
992
+ cssAssertionImport: {
993
+ global: '',
994
+ create (code) {
995
+ return `\
996
+ const sheet = new CSSStyleSheet()
997
+ sheet.replaceSync(${JSON.stringify(code)})
998
+ export default sheet`;
999
+ }
1000
+ }
1001
+ };
1002
+ const cleanCssInstance = new CleanCSS__default.default({});
1003
+ function minify(code) {
1004
+ return cleanCssInstance.minify(code).styles;
1005
+ }
1006
+ function inlineCss(options) {
1007
+ const cssIds = new Set();
1008
+ var _options_exclude;
1009
+ const filter = pluginutils.createFilter([
1010
+ '**/*.css'
1011
+ ], (_options_exclude = options.exclude) != null ? _options_exclude : []);
1012
+ // Follow up for rollup 4 for better support of assertion support https://github.com/rollup/rollup/issues/4818
1013
+ return {
1014
+ name: 'inline-css',
1015
+ transform: {
1016
+ order: 'post',
1017
+ handler (code, id) {
1018
+ if (!filter(id)) return;
1019
+ if (options.skip) return '';
1020
+ const cssCode = minify(code);
1021
+ cssIds.add(id);
1022
+ return {
1023
+ code: helpers.cssImport.create(cssCode),
1024
+ map: {
1025
+ mappings: ''
1026
+ }
1027
+ };
1028
+ }
1029
+ },
1030
+ renderChunk: {
1031
+ order: 'pre',
1032
+ handler (code) {
1033
+ const dependenciesIds = this.getModuleIds();
1034
+ let foundCss = false;
1035
+ for (const depId of dependenciesIds){
1036
+ if (depId && cssIds.has(depId)) {
1037
+ foundCss = true;
1038
+ break;
1039
+ }
1040
+ }
1041
+ if (!foundCss) return;
1042
+ return {
1043
+ code: `${helpers.cssImport.global}\n${code}`,
1044
+ map: {
1045
+ mappings: ''
1046
+ }
1047
+ };
1048
+ }
1049
+ }
1050
+ };
1051
+ }
1052
+
1053
+ function rawContent({ exclude }) {
1054
+ const filter = pluginutils.createFilter([
1055
+ '**/*.data',
1056
+ '**/*.txt'
1057
+ ], exclude);
1058
+ return {
1059
+ name: 'string',
1060
+ transform (code, id) {
1061
+ if (filter(id)) {
1062
+ return {
1063
+ code: `const data = ${JSON.stringify(code)};\nexport default data;`,
1064
+ map: null
1065
+ };
1066
+ }
1067
+ return null;
1068
+ }
1069
+ };
1070
+ }
1071
+
1072
+ function findJsBundlePathCallback({ format, bundlePath, conditionNames }) {
1073
+ const hasCondition = bundlePath != null;
1074
+ const formatCond = format === 'cjs' ? 'require' : 'import';
1075
+ const isTypesCondName = conditionNames.has('types');
1076
+ const isMatchedFormat = conditionNames.has(formatCond);
1077
+ return isMatchedFormat && !isTypesCondName && hasCondition;
1078
+ }
1079
+ function findTypesFileCallback({ format, bundlePath, conditionNames }) {
1080
+ const hasCondition = bundlePath != null;
1081
+ const formatCond = format ? format === 'cjs' ? 'require' : 'import' : null;
1082
+ const isTypesCondName = conditionNames.has('types');
1083
+ return isTypesCondName && hasCondition && (formatCond ? conditionNames.has(formatCond) : true);
1084
+ }
1085
+ // Alias entry key to dist bundle path
1086
+ function aliasEntries({ entry: sourceFilePath, entries, format, dts, cwd }) {
1087
+ // <imported source file path>: <relative path to source's bundle>
1088
+ const sourceToRelativeBundleMap = new Map();
1089
+ for (const [, exportCondition] of Object.entries(entries)){
1090
+ const exportDistMaps = exportCondition.export;
1091
+ const exportMapEntries = Object.entries(exportDistMaps).map(([composedKey, bundlePath])=>({
1092
+ conditionNames: new Set(composedKey.split('.')),
1093
+ bundlePath,
1094
+ format
1095
+ }));
1096
+ let matchedBundlePath;
1097
+ if (dts) {
1098
+ var _exportMapEntries_find;
1099
+ // Find the type with format condition first
1100
+ matchedBundlePath = (_exportMapEntries_find = exportMapEntries.find(findTypesFileCallback)) == null ? void 0 : _exportMapEntries_find.bundlePath;
1101
+ // If theres no format specific types such as import.types or require.types,
1102
+ // fallback to the general types file.
1103
+ if (!matchedBundlePath) {
1104
+ var _exportMapEntries_find1;
1105
+ matchedBundlePath = (_exportMapEntries_find1 = exportMapEntries.find((item)=>{
1106
+ return findTypesFileCallback({
1107
+ ...item,
1108
+ format: undefined
1109
+ });
1110
+ })) == null ? void 0 : _exportMapEntries_find1.bundlePath;
1093
1111
  }
1094
- if (isTestFile(dirent.name)) {
1095
- continue;
1112
+ } else {
1113
+ var _exportMapEntries_find2;
1114
+ matchedBundlePath = (_exportMapEntries_find2 = exportMapEntries.find(findJsBundlePathCallback)) == null ? void 0 : _exportMapEntries_find2.bundlePath;
1115
+ }
1116
+ if (matchedBundlePath) {
1117
+ if (!sourceToRelativeBundleMap.has(exportCondition.source)) sourceToRelativeBundleMap.set(exportCondition.source, matchedBundlePath);
1118
+ }
1119
+ }
1120
+ return {
1121
+ name: 'alias',
1122
+ resolveId: {
1123
+ async handler (source, importer, options) {
1124
+ const resolved = await this.resolve(source, importer, options);
1125
+ if (resolved != null) {
1126
+ // For types, generate relative path to the other type files,
1127
+ // this will be compatible for the node10 ts module resolution.
1128
+ const srcBundle = sourceToRelativeBundleMap.get(sourceFilePath);
1129
+ // Resolved module bundle path
1130
+ const resolvedModuleBundle = sourceToRelativeBundleMap.get(resolved.id);
1131
+ if (resolved.id !== sourceFilePath && srcBundle && resolvedModuleBundle) {
1132
+ const absoluteBundlePath = path__default.default.resolve(cwd, srcBundle);
1133
+ const absoluteImportBundlePath = path__default.default.resolve(cwd, resolvedModuleBundle);
1134
+ const filePathBase = path__default.default.relative(path__default.default.dirname(absoluteBundlePath), absoluteImportBundlePath);
1135
+ const relativePath = relativify(filePathBase);
1136
+ return {
1137
+ id: relativePath,
1138
+ external: true
1139
+ };
1140
+ }
1141
+ }
1142
+ return null;
1096
1143
  }
1097
- const sourceFileAbsolutePath = path__default.default.join(dirPath, dirent.name);
1098
- if (isBinaryPath) {
1099
- bins.set(originalSubpath, sourceFileAbsolutePath);
1100
- } else {
1101
- let sourceFilesMap = exportsEntries.get(originalSubpath) || {};
1102
- const exportType = getExportTypeFromExportPath(originalSubpath);
1103
- sourceFilesMap[exportType] = sourceFileAbsolutePath;
1104
- if (specialExportConventions.has(exportType)) {
1105
- // e.g. ./foo/index.react-server -> ./foo/index
1106
- const fallbackExportPath = sourceFilenameToExportFullPath(originalSubpath);
1107
- const fallbackSourceFilesMap = exportsEntries.get(fallbackExportPath) || {};
1108
- sourceFilesMap = {
1109
- ...fallbackSourceFilesMap,
1110
- ...sourceFilesMap
1111
- };
1144
+ }
1145
+ };
1146
+ }
1147
+
1148
+ function prependDirectives() {
1149
+ return {
1150
+ name: 'prependDirective',
1151
+ transform: {
1152
+ order: 'post',
1153
+ handler (code, id) {
1154
+ var _moduleInfo_meta;
1155
+ const moduleInfo = this.getModuleInfo(id);
1156
+ if (moduleInfo == null ? void 0 : (_moduleInfo_meta = moduleInfo.meta) == null ? void 0 : _moduleInfo_meta.preserveDirectives) {
1157
+ const firstDirective = moduleInfo.meta.preserveDirectives.directives[0];
1158
+ if (firstDirective) {
1159
+ const directive = firstDirective.value;
1160
+ const directiveCode = `'${directive}';`;
1161
+ return directiveCode + '\n' + code;
1162
+ }
1112
1163
  }
1113
- exportsEntries.set(originalSubpath, sourceFilesMap);
1164
+ return null;
1114
1165
  }
1115
1166
  }
1116
- }
1167
+ };
1117
1168
  }
1169
+
1170
+ const prependShebang = (entry)=>({
1171
+ name: 'prependShebang',
1172
+ transform: (code, id)=>{
1173
+ if (id !== entry) return;
1174
+ const shebang = '#!/usr/bin/env node\n';
1175
+ if (code.startsWith(shebang)) return;
1176
+ const magicString = new MagicString__default.default(code);
1177
+ magicString.prepend(shebang);
1178
+ return {
1179
+ code: magicString.toString(),
1180
+ map: magicString.generateMap({
1181
+ hires: true
1182
+ })
1183
+ };
1184
+ }
1185
+ });
1186
+
1118
1187
  /**
1119
- * exportsEntries {
1120
- * "./index" => {
1121
- * "development" => source"
1122
- * "react-server" => "source"
1123
- * },
1124
- * "./index.react-server" => {
1125
- * "development" => source"
1126
- * "react-server" => "source"
1127
- * }
1128
- * }
1129
- */ async function collectSourceEntriesFromExportPaths(sourceFolderPath, parsedExportsInfo) {
1130
- const bins = new Map();
1131
- const exportsEntries = new Map();
1132
- for (const [exportPath, exportInfo] of parsedExportsInfo.entries()){
1133
- const specialConditions = new Set();
1134
- for (const [_, composedExportType] of exportInfo){
1135
- const specialExportType = getSpecialExportTypeFromComposedExportPath(composedExportType);
1136
- if (specialExportType !== 'default') {
1137
- specialConditions.add(specialExportType);
1138
- }
1188
+ * @return {Record<string, string>} env { 'process.env.<key>': '<value>' }
1189
+ */ function getDefinedInlineVariables(envs, parsedExportCondition) {
1190
+ if (!envs.includes('NODE_ENV')) {
1191
+ envs.push('NODE_ENV');
1192
+ }
1193
+ const envVars = envs.reduce((acc, key)=>{
1194
+ const value = process.env[key];
1195
+ if (typeof value !== 'undefined') {
1196
+ acc['process.env.' + key] = JSON.stringify(value);
1139
1197
  }
1140
- await collectSourceEntriesByExportPath(sourceFolderPath, exportPath, bins, exportsEntries);
1141
- for (const specialCondition of specialConditions){
1142
- await collectSourceEntriesByExportPath(sourceFolderPath, exportPath + '.' + specialCondition, bins, exportsEntries);
1198
+ return acc;
1199
+ }, {});
1200
+ const exportConditionNames = Object.keys(parsedExportCondition.export).reduce((acc, key)=>{
1201
+ // key could be 'require' or 'import.development' etc.
1202
+ const exportTypes = key.split('.');
1203
+ for (const exportType of exportTypes){
1204
+ acc.add(exportType);
1143
1205
  }
1206
+ return acc;
1207
+ }, new Set());
1208
+ // For development and production convention, we override the NODE_ENV value
1209
+ if (exportConditionNames.has('development')) {
1210
+ envVars['process.env.NODE_ENV'] = JSON.stringify('development');
1211
+ } else if (exportConditionNames.has('production')) {
1212
+ envVars['process.env.NODE_ENV'] = JSON.stringify('production');
1144
1213
  }
1145
- return {
1146
- bins,
1147
- exportsEntries
1148
- };
1214
+ if (exportConditionNames.has('edge-light')) {
1215
+ envVars['EdgeRuntime'] = JSON.stringify('edge-runtime');
1216
+ }
1217
+ return envVars;
1149
1218
  }
1150
1219
 
1151
1220
  function getModuleLayer(moduleMeta) {
@@ -1218,22 +1287,6 @@ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, cwd) {
1218
1287
  // Avoid create multiple dts plugins instance and parsing the same tsconfig multi times,
1219
1288
  // This will avoid memory leak and performance issue.
1220
1289
  const memoizeDtsPluginByKey = memoizeByKey(createDtsPlugin);
1221
- /**
1222
- * return {
1223
- * <absolute source path>: <pkg>/<export>
1224
- * }
1225
- */ function getReversedAlias({ entries, name }) {
1226
- const alias = {};
1227
- for (const [entryExportPath, exportCondition] of Object.entries(entries)){
1228
- const normalizedExportPath = normalizeExportPath(entryExportPath);
1229
- // entryExportPath format: ./index, ./shared, etc.
1230
- const specialExportType = getSpecialExportTypeFromComposedExportPath(entryExportPath);
1231
- if (specialExportType === 'default') {
1232
- alias[exportCondition.source] = path.posix.join(name || '', normalizedExportPath);
1233
- }
1234
- }
1235
- return alias;
1236
- }
1237
1290
  async function buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts) {
1238
1291
  var _bundleConfig_file, _bundleConfig_file1;
1239
1292
  const { entries, pkg, cwd, tsOptions: { tsConfigPath, tsCompilerOptions }, pluginContext } = buildContext;
@@ -1287,7 +1340,6 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1287
1340
  const aliasPlugin = aliasEntries({
1288
1341
  entry,
1289
1342
  entries,
1290
- entriesAlias: pluginContext.entriesAlias,
1291
1343
  format: aliasFormat,
1292
1344
  dts,
1293
1345
  cwd
@@ -1576,122 +1628,6 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, bundleE
1576
1628
  return Promise.all(outputConfigs);
1577
1629
  }
1578
1630
 
1579
- // Example: @foo/bar -> bar
1580
- const removeScope = (exportPath)=>exportPath.replace(/^@[^/]+\//, '');
1581
- function createOutputState({ entries }) {
1582
- const sizeStats = new Map();
1583
- const uniqFiles = new Set();
1584
- function addSize({ fileName, size, sourceFileName, exportPath }) {
1585
- if (!sizeStats.has(exportPath)) {
1586
- sizeStats.set(exportPath, []);
1587
- }
1588
- const distFilesStats = sizeStats.get(exportPath);
1589
- if (!uniqFiles.has(fileName)) {
1590
- uniqFiles.add(fileName);
1591
- if (distFilesStats) {
1592
- distFilesStats.push([
1593
- fileName,
1594
- sourceFileName,
1595
- size
1596
- ]);
1597
- }
1598
- }
1599
- }
1600
- const reversedMapping = new Map();
1601
- Object.entries(entries).forEach(([resolvedExportName, entry])=>{
1602
- reversedMapping.set(entry.source, resolvedExportName);
1603
- });
1604
- return {
1605
- plugin: (cwd)=>{
1606
- return {
1607
- name: 'collect-sizes',
1608
- writeBundle (options, bundle) {
1609
- const dir = options.dir || path__default.default.dirname(options.file);
1610
- Object.entries(bundle).forEach(([fileName, chunk])=>{
1611
- const filePath = path__default.default.join(dir, fileName);
1612
- if (chunk.type !== 'chunk') {
1613
- return;
1614
- }
1615
- if (!chunk.isEntry) {
1616
- return;
1617
- }
1618
- const size = chunk.code.length;
1619
- const sourceFileName = chunk.facadeModuleId || '';
1620
- const exportPath = removeScope(reversedMapping.get(sourceFileName) || '.');
1621
- addSize({
1622
- fileName: path__default.default.isAbsolute(cwd) ? path__default.default.relative(cwd, filePath) : filePath,
1623
- size,
1624
- sourceFileName,
1625
- exportPath
1626
- });
1627
- });
1628
- }
1629
- };
1630
- },
1631
- getSizeStats () {
1632
- return sizeStats;
1633
- }
1634
- };
1635
- }
1636
- function isTypeFile(filename) {
1637
- return filename.endsWith('.d.ts') || filename.endsWith('.d.mts') || filename.endsWith('.d.cts');
1638
- }
1639
- function normalizeExportName(exportName) {
1640
- const isBinary = isBinExportPath(exportName);
1641
- let result = exportName;
1642
- if (isBinary) {
1643
- result = (exportName.replace(new RegExp(`^\\${BINARY_TAG}\\/?`), '') || '.') + ' (bin)';
1644
- } else {
1645
- const normalizedExportPath = normalizeExportPath(exportName);
1646
- const specialConditionName = getSpecialExportTypeFromComposedExportPath(exportName);
1647
- result = normalizedExportPath + (specialConditionName !== 'default' ? ` (${specialConditionName})` : '');
1648
- }
1649
- return result;
1650
- }
1651
- function logOutputState(sizeCollector) {
1652
- const stats = sizeCollector.getSizeStats();
1653
- if (stats.size === 0) {
1654
- logger.warn('No build info can be logged');
1655
- return;
1656
- }
1657
- const allFileNameLengths = Array.from(stats.values()).flat(1).map(([filename])=>filename.length);
1658
- const maxFilenameLength = Math.max(...allFileNameLengths);
1659
- const statsArray = [
1660
- ...stats.entries()
1661
- ].sort(([a], [b])=>{
1662
- const comp = normalizeExportPath(a).length - normalizeExportPath(b).length;
1663
- return comp === 0 ? a.localeCompare(b) : comp;
1664
- });
1665
- const maxLengthOfExportName = Math.max(...statsArray.map(([exportName])=>normalizeExportName(exportName).length));
1666
- console.log(pc.underline('Exports'), ' '.repeat(Math.max(maxLengthOfExportName - 'Exports'.length, 0)), pc.underline('File'), ' '.repeat(Math.max(maxFilenameLength - 'File'.length, 0)), pc.underline('Size'));
1667
- statsArray.forEach(([exportName, filesList])=>{
1668
- // sort by file type, first js files then types, js/mjs/cjs are prioritized than .d.ts/.d.mts/.d.cts
1669
- filesList.sort(([a], [b])=>{
1670
- const aIsType = isTypeFile(a);
1671
- const bIsType = isTypeFile(b);
1672
- if (aIsType && bIsType) {
1673
- return 0;
1674
- }
1675
- if (aIsType) {
1676
- return 1;
1677
- }
1678
- if (bIsType) {
1679
- return -1;
1680
- }
1681
- return 0;
1682
- }).forEach((item, index)=>{
1683
- const [filename, , size] = item;
1684
- const normalizedExportName = normalizeExportName(exportName);
1685
- const prefix = index === 0 ? normalizedExportName : ' '.repeat(normalizedExportName.length);
1686
- const filenamePadding = ' '.repeat(Math.max(maxLengthOfExportName, 'Exports'.length) - normalizedExportName.length);
1687
- const isType = isTypeFile(filename);
1688
- const sizePadding = ' '.repeat(Math.max(maxFilenameLength, 'File'.length) - filename.length);
1689
- const prettiedSize = prettyBytes__default.default(size);
1690
- console.log(prefix, filenamePadding, `${pc[isType ? 'dim' : 'bold'](filename)}`, sizePadding, prettiedSize);
1691
- });
1692
- });
1693
- }
1694
-
1695
1631
  async function createAssetRollupJobs(options, buildContext, bundleJobOptions) {
1696
1632
  const { isFromCli, generateTypes } = bundleJobOptions;
1697
1633
  const assetsConfigs = await buildEntryConfig(options, buildContext, {
@@ -1756,6 +1692,7 @@ function hasMultiEntryExport(exportPaths) {
1756
1692
  return exportKeys.length > 0 && exportKeys.every((name)=>name.startsWith('.'));
1757
1693
  }
1758
1694
  async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1695
+ var _options__callbacks_onBuildStart, _options__callbacks, _options__callbacks_onBuildEnd, _options__callbacks1;
1759
1696
  const cwd = path.resolve(process.cwd(), _cwd || '');
1760
1697
  assignDefault(options, 'format', 'esm');
1761
1698
  assignDefault(options, 'minify', false);
@@ -1827,13 +1764,9 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1827
1764
  await writeDefaultTsconfig(tsConfigPath);
1828
1765
  hasTsConfig = true;
1829
1766
  }
1830
- const sizeCollector = createOutputState({
1767
+ const outputState = createOutputState({
1831
1768
  entries
1832
1769
  });
1833
- const entriesAlias = getReversedAlias({
1834
- entries,
1835
- name: pkg.name
1836
- });
1837
1770
  const buildContext = {
1838
1771
  entries,
1839
1772
  pkg,
@@ -1841,68 +1774,18 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1841
1774
  tsOptions: defaultTsOptions,
1842
1775
  useTypeScript: hasTsConfig,
1843
1776
  pluginContext: {
1844
- outputState: sizeCollector,
1845
- moduleDirectiveLayerMap: new Map(),
1846
- entriesAlias
1777
+ outputState,
1778
+ moduleDirectiveLayerMap: new Map()
1847
1779
  }
1848
1780
  };
1781
+ (_options__callbacks = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildStart = _options__callbacks.onBuildStart) == null ? void 0 : _options__callbacks_onBuildStart.call(_options__callbacks, buildContext);
1849
1782
  const generateTypes = hasTsConfig && options.dts !== false;
1850
1783
  const rollupJobsOptions = {
1851
1784
  isFromCli,
1852
1785
  generateTypes
1853
1786
  };
1854
1787
  const assetJobs = await createAssetRollupJobs(options, buildContext, rollupJobsOptions);
1855
- if (assetJobs.length === 0) {
1856
- 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');
1857
- }
1858
- if (options.watch) {
1859
- logWatcherBuildTime(assetJobs);
1860
- } else {
1861
- logOutputState(sizeCollector);
1862
- }
1863
- return;
1864
- }
1865
- function logWatcherBuildTime(result) {
1866
- let watcherCounter = 0;
1867
- let startTime = 0;
1868
- result.map((watcher)=>{
1869
- function start() {
1870
- if (watcherCounter === 0) startTime = perf_hooks.performance.now();
1871
- watcherCounter++;
1872
- }
1873
- function end() {
1874
- watcherCounter--;
1875
- if (watcherCounter === 0) {
1876
- logger.info(`Build in ${(perf_hooks.performance.now() - startTime).toFixed(2)}ms`);
1877
- }
1878
- }
1879
- watcher.on('event', (event)=>{
1880
- switch(event.code){
1881
- case 'ERROR':
1882
- {
1883
- logError(event.error);
1884
- break;
1885
- }
1886
- case 'START':
1887
- {
1888
- start();
1889
- break;
1890
- }
1891
- case 'END':
1892
- {
1893
- end();
1894
- break;
1895
- }
1896
- }
1897
- });
1898
- });
1899
- }
1900
- function logError(error) {
1901
- if (!error) return;
1902
- // logging source code in format
1903
- if (error.frame) {
1904
- process.stderr.write(error.frame + '\n');
1905
- }
1788
+ (_options__callbacks1 = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildEnd = _options__callbacks1.onBuildEnd) == null ? void 0 : _options__callbacks_onBuildEnd.call(_options__callbacks1, assetJobs);
1906
1789
  }
1907
1790
 
1908
1791
  exports.bundle = bundle;