bunchee 5.2.0-beta.0 → 5.2.0

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,866 +284,949 @@ 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
+ // When we dealing with special export conditions, we need to make sure
560
+ // the outputs won't override the default export output paths.
561
+ // e.g. We have './index' -> { default: 'index.js', development: 'index.development.js' };
562
+ // When we generate './index.react-server' -> { 'react-server': 'index.react-server.js' },
563
+ // Normalize the entryExportPath to './index' first and check if it already exists with output paths.
564
+ const normalizedEntryExportPath = stripSpecialCondition(entryExportPath);
565
+ if (// The entry already exists, e.g. normalize './index.react-server' to './index'
566
+ entries[normalizedEntryExportPath] && // Is special export condition
567
+ entryExportPathType !== 'default' && // The extracted special condition is not the current loop one.
568
+ entryExportPathType !== matchedExportType) {
569
+ continue;
570
+ }
571
+ const exportMap = entries[entryExportPath].export;
572
+ exportMap[outputComposedExportType] = outputPath;
573
+ }
675
574
  }
676
- return;
677
575
  }
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);
576
+ // Handling binaries
577
+ for (const [exportPath, sourceFile] of bins){
578
+ const outputExports = parsedExportsInfo.get(exportPath);
579
+ if (!outputExports) {
580
+ continue;
581
+ }
582
+ for (const [outputPath, exportType] of outputExports){
583
+ entries[exportPath] = {
584
+ source: sourceFile,
585
+ name: exportPath,
586
+ export: {
587
+ [exportType]: outputPath
588
+ }
589
+ };
692
590
  }
693
591
  }
592
+ return entries;
694
593
  }
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
- }
594
+ // ./index -> default
595
+ // ./index.development -> development
596
+ // ./index.react-server -> react-server
597
+ function getExportTypeFromExportPath(exportPath) {
598
+ // Skip the first two segments: `.` and `index`
599
+ const exportTypes = exportPath.split('.').slice(2);
600
+ return getExportTypeFromExportTypesArray(exportTypes);
705
601
  }
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);
602
+ function getSpecialExportTypeFromComposedExportPath(composedExportType) {
603
+ const exportTypes = composedExportType.split('.');
604
+ for (const exportType of exportTypes){
605
+ if (specialExportConventions.has(exportType)) {
606
+ return exportType;
744
607
  }
745
608
  }
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
- ]);
609
+ return 'default';
610
+ }
611
+ function getExportTypeFromExportTypesArray(types) {
612
+ let exportType = 'default';
613
+ new Set(types).forEach((value)=>{
614
+ if (specialExportConventions.has(value)) {
615
+ exportType = value;
616
+ } else if (value === 'import' || value === 'require' || value === 'types') {
617
+ exportType = value;
618
+ }
619
+ });
620
+ return exportType;
621
+ }
622
+ // ./index -> .
623
+ // ./index.development -> .
624
+ // ./index.react-server -> .
625
+ // ./shared -> ./shared
626
+ // ./shared.development -> ./shared
627
+ // $binary -> $binary
628
+ // $binary/index -> $binary
629
+ // $binary/foo -> $binary/foo
630
+ function normalizeExportPath(exportPath) {
631
+ if (exportPath.startsWith(BINARY_TAG)) {
632
+ if (exportPath === `${BINARY_TAG}/index`) {
633
+ exportPath = BINARY_TAG;
766
634
  }
635
+ return exportPath;
767
636
  }
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));
637
+ const baseName = exportPath.split('.').slice(0, 2).join('.');
638
+ if (baseName === './index') {
639
+ return '.';
787
640
  }
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';
641
+ return baseName;
804
642
  }
805
- function getFileExportType(composedTypes) {
806
- return composedTypes.split('.').pop();
643
+ // ./index.react-server -> ./index
644
+ function stripSpecialCondition(exportPath) {
645
+ return exportPath.split('.').slice(0, 2).join('.');
807
646
  }
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;
647
+ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpath, bins, exportsEntries) {
648
+ const isBinaryPath = isBinExportPath(originalSubpath);
649
+ const subpath = originalSubpath.replace(BINARY_TAG, 'bin');
650
+ const absoluteDirPath = path__default.default.join(sourceFolderPath, subpath);
651
+ const isDirectory = fs__default.default.existsSync(absoluteDirPath) ? (await fsp__default.default.stat(absoluteDirPath)).isDirectory() : false;
652
+ if (isDirectory) {
653
+ if (isBinaryPath) {
654
+ const binDirentList = await fsp__default.default.readdir(absoluteDirPath, {
655
+ withFileTypes: true
656
+ });
657
+ for (const binDirent of binDirentList){
658
+ if (binDirent.isFile()) {
659
+ const binFileAbsolutePath = path__default.default.join(absoluteDirPath, binDirent.name);
660
+ if (fs__default.default.existsSync(binFileAbsolutePath)) {
661
+ bins.set(normalizeExportPath(originalSubpath), binFileAbsolutePath);
662
+ }
663
+ }
664
+ }
665
+ } else {
666
+ // Search folder/index.<ext> convention entries
667
+ for (const extension of availableExtensions){
668
+ const indexAbsoluteFile = path__default.default.join(absoluteDirPath, `index.${extension}`);
669
+ // Search folder/index.<special type>.<ext> convention entries
670
+ for (const specialExportType of runtimeExportConventions){
671
+ const indexSpecialAbsoluteFile = path__default.default.join(absoluteDirPath, `index.${specialExportType}.${extension}`);
672
+ if (fs__default.default.existsSync(indexSpecialAbsoluteFile)) {
673
+ // Add special export path
674
+ // { ./<export path>.<special cond>: { <special cond>: 'index.<special cond>.<ext>' } }
675
+ const exportPath = relativify(subpath);
676
+ const specialExportPath = exportPath + '.' + specialExportType;
677
+ const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
678
+ sourceFilesMap[specialExportType] = indexSpecialAbsoluteFile;
679
+ exportsEntries.set(specialExportPath, sourceFilesMap);
680
+ }
681
+ }
682
+ if (fs__default.default.existsSync(indexAbsoluteFile) && !isTestFile(indexAbsoluteFile)) {
683
+ const exportPath = relativify(subpath);
684
+ const sourceFilesMap = exportsEntries.get(exportPath) || {};
685
+ const exportType = getExportTypeFromExportPath(exportPath);
686
+ sourceFilesMap[exportType] = indexAbsoluteFile;
687
+ exportsEntries.set(exportPath, sourceFilesMap);
688
+ break;
689
+ }
690
+ }
821
691
  }
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;
692
+ } else {
693
+ // subpath could be a file
694
+ const dirName = path.dirname(subpath);
695
+ const baseName = path.basename(subpath);
696
+ // Read current file's directory
697
+ const dirPath = path__default.default.join(sourceFolderPath, dirName);
698
+ if (!fs__default.default.existsSync(dirPath)) {
699
+ return;
829
700
  }
830
- uniqueFiles.add(distFile);
831
- dist.push({
832
- format,
833
- file: distFile,
834
- exportCondition
701
+ const dirents = await fsp__default.default.readdir(dirPath, {
702
+ withFileTypes: true
835
703
  });
704
+ for (const dirent of dirents){
705
+ // index.development.js -> index.development
706
+ const direntBaseName = baseNameWithoutExtension(dirent.name);
707
+ const ext = path.extname(dirent.name).slice(1);
708
+ if (!dirent.isFile() || direntBaseName !== baseName || !availableExtensions.has(ext)) {
709
+ continue;
710
+ }
711
+ if (isTestFile(dirent.name)) {
712
+ continue;
713
+ }
714
+ const sourceFileAbsolutePath = path__default.default.join(dirPath, dirent.name);
715
+ if (isBinaryPath) {
716
+ bins.set(originalSubpath, sourceFileAbsolutePath);
717
+ } else {
718
+ let sourceFilesMap = exportsEntries.get(originalSubpath) || {};
719
+ const exportType = getExportTypeFromExportPath(originalSubpath);
720
+ sourceFilesMap[exportType] = sourceFileAbsolutePath;
721
+ if (specialExportConventions.has(exportType)) {
722
+ // e.g. ./foo/index.react-server -> ./foo/index
723
+ const fallbackExportPath = sourceFilenameToExportFullPath(originalSubpath);
724
+ const fallbackSourceFilesMap = exportsEntries.get(fallbackExportPath) || {};
725
+ sourceFilesMap = {
726
+ ...fallbackSourceFilesMap,
727
+ ...sourceFilesMap
728
+ };
729
+ }
730
+ exportsEntries.set(originalSubpath, sourceFilesMap);
731
+ }
732
+ }
836
733
  }
837
- return dist;
838
734
  }
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
735
  /**
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);
736
+ * exportsEntries {
737
+ * "./index" => {
738
+ * "development" => source"
739
+ * "react-server" => "source"
740
+ * },
741
+ * "./index.react-server" => {
742
+ * "development" => source"
743
+ * "react-server" => "source"
744
+ * }
745
+ * }
746
+ */ async function collectSourceEntriesFromExportPaths(sourceFolderPath, parsedExportsInfo) {
747
+ const bins = new Map();
748
+ const exportsEntries = new Map();
749
+ for (const [exportPath, exportInfo] of parsedExportsInfo.entries()){
750
+ const specialConditions = new Set();
751
+ for (const [_, composedExportType] of exportInfo){
752
+ const specialExportType = getSpecialExportTypeFromComposedExportPath(composedExportType);
753
+ if (specialExportType !== 'default') {
754
+ specialConditions.add(specialExportType);
755
+ }
864
756
  }
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);
757
+ await collectSourceEntriesByExportPath(sourceFolderPath, exportPath, bins, exportsEntries);
758
+ for (const specialCondition of specialConditions){
759
+ await collectSourceEntriesByExportPath(sourceFolderPath, exportPath + '.' + specialCondition, bins, exportsEntries);
872
760
  }
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
761
  }
884
- return envVars;
762
+ return {
763
+ bins,
764
+ exportsEntries
765
+ };
885
766
  }
886
767
 
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]
768
+ // Example: @foo/bar -> bar
769
+ const removeScope = (exportPath)=>exportPath.replace(/^@[^/]+\//, '');
770
+ function createOutputState({ entries }) {
771
+ const sizeStats = new Map();
772
+ const uniqFiles = new Set();
773
+ function addSize({ fileName, size, sourceFileName, exportPath }) {
774
+ if (!sizeStats.has(exportPath)) {
775
+ sizeStats.set(exportPath, []);
776
+ }
777
+ const distFilesStats = sizeStats.get(exportPath);
778
+ if (!uniqFiles.has(fileName)) {
779
+ uniqFiles.add(fileName);
780
+ if (distFilesStats) {
781
+ distFilesStats.push([
782
+ fileName,
783
+ sourceFileName,
784
+ size
785
+ ]);
905
786
  }
906
- };
787
+ }
907
788
  }
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();
789
+ const reversedMapping = new Map();
790
+ Object.entries(entries).forEach(([resolvedExportName, entry])=>{
791
+ reversedMapping.set(entry.source, resolvedExportName);
792
+ });
793
+ return {
794
+ plugin: (cwd)=>{
795
+ return {
796
+ name: 'collect-sizes',
797
+ writeBundle (options, bundle) {
798
+ const dir = options.dir || path__default.default.dirname(options.file);
799
+ Object.entries(bundle).forEach(([fileName, chunk])=>{
800
+ const filePath = path__default.default.join(dir, fileName);
801
+ if (chunk.type !== 'chunk') {
802
+ return;
803
+ }
804
+ if (!chunk.isEntry) {
805
+ return;
806
+ }
807
+ const size = chunk.code.length;
808
+ const sourceFileName = chunk.facadeModuleId || '';
809
+ const exportPath = removeScope(reversedMapping.get(sourceFileName) || '.');
810
+ addSize({
811
+ fileName: path__default.default.isAbsolute(cwd) ? path__default.default.relative(cwd, filePath) : filePath,
812
+ size,
813
+ sourceFileName,
814
+ exportPath
815
+ });
816
+ });
817
+ }
818
+ };
819
+ },
820
+ getSizeStats () {
821
+ return sizeStats;
918
822
  }
919
- const exportType = getExportTypeFromExportPath(exportPath);
920
- if (exportType !== 'default') {
921
- pathSpecialConditionsMap[normalizedExportPath].add(exportType);
823
+ };
824
+ }
825
+
826
+ const memoize = (fn, cacheKey, cacheArg)=>{
827
+ const cache = cacheArg || new Map();
828
+ return (...args)=>{
829
+ const key = cacheKey ? typeof cacheKey === 'function' ? cacheKey(...args) : cacheKey : JSON.stringify({
830
+ args
831
+ });
832
+ const existing = cache.get(key);
833
+ if (existing !== undefined) {
834
+ return existing;
922
835
  }
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;
836
+ const result = fn(...args);
837
+ cache.set(key, result);
838
+ return result;
839
+ };
840
+ };
841
+ const memoizeByKey = (fn)=>{
842
+ const cache = new Map();
843
+ return (cacheKey)=>memoize(fn, cacheKey, cache);
844
+ };
845
+
846
+ let hasLoggedTsWarning = false;
847
+ function resolveTypescript(cwd) {
848
+ let ts;
849
+ const m = new module$1.Module('', undefined);
850
+ m.paths = module$1.Module._nodeModulePaths(cwd);
851
+ try {
852
+ // Bun does not yet support the `Module` class properly.
853
+ if (typeof (m == null ? void 0 : m.require) === 'undefined') {
854
+ const tsPath = require.resolve('typescript', {
855
+ paths: [
856
+ cwd
857
+ ]
858
+ });
859
+ ts = require(tsPath);
860
+ } else {
861
+ ts = m.require('typescript');
933
862
  }
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: {}
863
+ } catch (e) {
864
+ console.error(e);
865
+ if (!hasLoggedTsWarning) {
866
+ hasLoggedTsWarning = true;
867
+ exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency');
868
+ }
869
+ }
870
+ return ts;
871
+ }
872
+ function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
873
+ let tsCompilerOptions = {};
874
+ let tsConfigPath;
875
+ tsConfigPath = path.resolve(cwd, tsconfig);
876
+ if (fileExists(tsConfigPath)) {
877
+ // Use the original ts handler to avoid memory leak
878
+ const ts = resolveTypescript(cwd);
879
+ const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
880
+ const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
881
+ tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
882
+ } else {
883
+ return null;
884
+ }
885
+ return {
886
+ tsCompilerOptions,
887
+ tsConfigPath
888
+ };
889
+ }
890
+ const resolveTsConfig = memoizeByKey(resolveTsConfigHandler)();
891
+ async function convertCompilerOptions(cwd, json) {
892
+ // Use the original ts handler to avoid memory leak
893
+ const ts = resolveTypescript(cwd);
894
+ return ts.convertCompilerOptionsFromJson(json, './');
895
+ }
896
+ async function writeDefaultTsconfig(tsConfigPath) {
897
+ await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
898
+ logger.log(`Detected using TypeScript but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
899
+ }
900
+
901
+ const FILENAME_REGEX = /__filename/;
902
+ const DIRNAME_REGEX = /__dirname/;
903
+ const GLOBAL_REQUIRE_REGEX = /require(\.resolve)?\(/;
904
+ const PolyfillComment = '/** rollup-private-do-not-use-esm-shim-polyfill */';
905
+ const createESMShim = ({ filename, dirname, globalRequire })=>{
906
+ const useNodeUrl = filename || dirname;
907
+ const useNodePath = dirname;
908
+ const useNodeModule = globalRequire;
909
+ return `\
910
+ ${PolyfillComment}
911
+ ${useNodeUrl ? `import __node_cjsUrl from 'node:url'` : ''};
912
+ ${useNodePath ? `import __node_cjsPath from 'node:path';` : ''}
913
+ ${useNodeModule ? `import __node_cjsModule from 'node:module';` : ''}
914
+ ${useNodeUrl ? 'const __filename = __node_cjsUrl.fileURLToPath(import.meta.url);' : ''}
915
+ ${useNodePath ? 'const __dirname = __node_cjsPath.dirname(__filename);' : ''}
916
+ ${useNodeModule ? 'const require = __node_cjsModule.createRequire(import.meta.url);' : ''}
917
+ `.trim() + '\n';
918
+ };
919
+ function esmShim() {
920
+ return {
921
+ name: 'esm-shim',
922
+ transform: {
923
+ order: 'post',
924
+ handler (code, id) {
925
+ const ext = path.extname(id);
926
+ if (!availableESExtensionsRegex.test(ext) || code.includes(PolyfillComment)) {
927
+ return null;
928
+ }
929
+ let hasFilename = false;
930
+ let hasDirname = false;
931
+ let hasGlobalRequire = false;
932
+ if (FILENAME_REGEX.test(code)) {
933
+ hasFilename = true;
934
+ }
935
+ if (DIRNAME_REGEX.test(code)) {
936
+ hasDirname = true;
937
+ }
938
+ if (GLOBAL_REQUIRE_REGEX.test(code)) {
939
+ hasGlobalRequire = true;
940
+ }
941
+ if (!hasFilename && !hasDirname && !hasGlobalRequire) {
942
+ return null;
943
+ }
944
+ const magicString = new MagicString__default.default(code);
945
+ let ast = null;
946
+ try {
947
+ // rollup 2 built-in parser doesn't have `allowShebang`, we need to use the sliced code here. Hence the `magicString.toString()`
948
+ ast = this.parse(magicString.toString(), {
949
+ allowReturnOutsideFunction: true
950
+ });
951
+ } catch (e) {
952
+ console.warn(e);
953
+ return null;
954
+ }
955
+ if (ast.type !== 'Program') {
956
+ return null;
957
+ }
958
+ let lastImportNode = null;
959
+ for (const node of ast.body){
960
+ if (node.type === 'ImportDeclaration') {
961
+ lastImportNode = node;
962
+ continue;
963
+ }
964
+ }
965
+ let end = 0;
966
+ if (lastImportNode) {
967
+ end = lastImportNode.end;
968
+ } else {
969
+ end = ast.body.length > 0 ? ast.body[0].end : 0;
970
+ }
971
+ magicString.appendRight(end, '\n' + createESMShim({
972
+ filename: hasFilename,
973
+ dirname: hasDirname,
974
+ globalRequire: hasGlobalRequire
975
+ }));
976
+ return {
977
+ code: magicString.toString(),
978
+ map: magicString.generateMap({
979
+ hires: true
980
+ })
948
981
  };
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
982
  }
957
983
  }
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
+ };
984
985
  }
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';
986
+
987
+ const helpers = {
988
+ cssImport: {
989
+ // have to assign r.type = 'text/css' to make it work in Safari
990
+ global: `\
991
+ function __insertCSS(code) {
992
+ if (!code || typeof document == 'undefined') return
993
+ let head = document.head || document.getElementsByTagName('head')[0]
994
+ let style = document.createElement('style')
995
+ style.type = 'text/css'
996
+ head.appendChild(style)
997
+ ;style.styleSheet ? (style.styleSheet.cssText = code) : style.appendChild(document.createTextNode(code))
993
998
  }
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;
999
+ `,
1000
+ create (code) {
1001
+ return `__insertCSS(${JSON.stringify(code)});`;
1001
1002
  }
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;
1003
+ },
1004
+ cssAssertionImport: {
1005
+ global: '',
1006
+ create (code) {
1007
+ return `\
1008
+ const sheet = new CSSStyleSheet()
1009
+ sheet.replaceSync(${JSON.stringify(code)})
1010
+ export default sheet`;
1017
1011
  }
1018
- return exportPath;
1019
- }
1020
- const baseName = exportPath.split('.').slice(0, 2).join('.');
1021
- if (baseName === './index') {
1022
- return '.';
1023
1012
  }
1024
- return baseName;
1025
- }
1026
- // ./index.react-server -> ./index
1027
- function stripSpecialCondition(exportPath) {
1028
- return exportPath.split('.').slice(0, 2).join('.');
1013
+ };
1014
+ const cleanCssInstance = new CleanCSS__default.default({});
1015
+ function minify(code) {
1016
+ return cleanCssInstance.minify(code).styles;
1029
1017
  }
1030
- async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpath, bins, exportsEntries) {
1031
- const isBinaryPath = isBinExportPath(originalSubpath);
1032
- const subpath = originalSubpath.replace(BINARY_TAG, 'bin');
1033
- const absoluteDirPath = path__default.default.join(sourceFolderPath, subpath);
1034
- const isDirectory = fs__default.default.existsSync(absoluteDirPath) ? (await fsp__default.default.stat(absoluteDirPath)).isDirectory() : false;
1035
- if (isDirectory) {
1036
- if (isBinaryPath) {
1037
- const binDirentList = await fsp__default.default.readdir(absoluteDirPath, {
1038
- withFileTypes: true
1039
- });
1040
- for (const binDirent of binDirentList){
1041
- if (binDirent.isFile()) {
1042
- const binFileAbsolutePath = path__default.default.join(absoluteDirPath, binDirent.name);
1043
- if (fs__default.default.existsSync(binFileAbsolutePath)) {
1044
- bins.set(normalizeExportPath(originalSubpath), binFileAbsolutePath);
1018
+ function inlineCss(options) {
1019
+ const cssIds = new Set();
1020
+ var _options_exclude;
1021
+ const filter = pluginutils.createFilter([
1022
+ '**/*.css'
1023
+ ], (_options_exclude = options.exclude) != null ? _options_exclude : []);
1024
+ // Follow up for rollup 4 for better support of assertion support https://github.com/rollup/rollup/issues/4818
1025
+ return {
1026
+ name: 'inline-css',
1027
+ transform: {
1028
+ order: 'post',
1029
+ handler (code, id) {
1030
+ if (!filter(id)) return;
1031
+ if (options.skip) return '';
1032
+ const cssCode = minify(code);
1033
+ cssIds.add(id);
1034
+ return {
1035
+ code: helpers.cssImport.create(cssCode),
1036
+ map: {
1037
+ mappings: ''
1045
1038
  }
1046
- }
1039
+ };
1047
1040
  }
1048
- } else {
1049
- // Search folder/index.<ext> convention entries
1050
- for (const extension of availableExtensions){
1051
- const indexAbsoluteFile = path__default.default.join(absoluteDirPath, `index.${extension}`);
1052
- // Search folder/index.<special type>.<ext> convention entries
1053
- for (const specialExportType of runtimeExportConventions){
1054
- const indexSpecialAbsoluteFile = path__default.default.join(absoluteDirPath, `index.${specialExportType}.${extension}`);
1055
- if (fs__default.default.existsSync(indexSpecialAbsoluteFile)) {
1056
- // Add special export path
1057
- // { ./<export path>.<special cond>: { <special cond>: 'index.<special cond>.<ext>' } }
1058
- const exportPath = relativify(subpath);
1059
- const specialExportPath = exportPath + '.' + specialExportType;
1060
- const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
1061
- sourceFilesMap[specialExportType] = indexSpecialAbsoluteFile;
1062
- exportsEntries.set(specialExportPath, sourceFilesMap);
1041
+ },
1042
+ renderChunk: {
1043
+ order: 'pre',
1044
+ handler (code) {
1045
+ const dependenciesIds = this.getModuleIds();
1046
+ let foundCss = false;
1047
+ for (const depId of dependenciesIds){
1048
+ if (depId && cssIds.has(depId)) {
1049
+ foundCss = true;
1050
+ break;
1063
1051
  }
1064
1052
  }
1065
- if (fs__default.default.existsSync(indexAbsoluteFile) && !isTestFile(indexAbsoluteFile)) {
1066
- const exportPath = relativify(subpath);
1067
- const sourceFilesMap = exportsEntries.get(exportPath) || {};
1068
- const exportType = getExportTypeFromExportPath(exportPath);
1069
- sourceFilesMap[exportType] = indexAbsoluteFile;
1070
- exportsEntries.set(exportPath, sourceFilesMap);
1071
- break;
1072
- }
1053
+ if (!foundCss) return;
1054
+ return {
1055
+ code: `${helpers.cssImport.global}\n${code}`,
1056
+ map: {
1057
+ mappings: ''
1058
+ }
1059
+ };
1060
+ }
1061
+ }
1062
+ };
1063
+ }
1064
+
1065
+ function rawContent({ exclude }) {
1066
+ const filter = pluginutils.createFilter([
1067
+ '**/*.data',
1068
+ '**/*.txt'
1069
+ ], exclude);
1070
+ return {
1071
+ name: 'string',
1072
+ transform (code, id) {
1073
+ if (filter(id)) {
1074
+ return {
1075
+ code: `const data = ${JSON.stringify(code)};\nexport default data;`,
1076
+ map: null
1077
+ };
1073
1078
  }
1079
+ return null;
1074
1080
  }
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;
1081
+ };
1082
+ }
1083
+
1084
+ function findJsBundlePathCallback({ format, bundlePath, conditionNames }) {
1085
+ const hasCondition = bundlePath != null;
1086
+ const formatCond = format === 'cjs' ? 'require' : 'import';
1087
+ const isTypesCondName = conditionNames.has('types');
1088
+ const isMatchedFormat = conditionNames.has(formatCond);
1089
+ return isMatchedFormat && !isTypesCondName && hasCondition;
1090
+ }
1091
+ function findTypesFileCallback({ format, bundlePath, conditionNames }) {
1092
+ const hasCondition = bundlePath != null;
1093
+ const formatCond = format ? format === 'cjs' ? 'require' : 'import' : null;
1094
+ const isTypesCondName = conditionNames.has('types');
1095
+ return isTypesCondName && hasCondition && (formatCond ? conditionNames.has(formatCond) : true);
1096
+ }
1097
+ // Alias entry key to dist bundle path
1098
+ function aliasEntries({ entry: sourceFilePath, entries, format, dts, cwd }) {
1099
+ // <imported source file path>: <relative path to source's bundle>
1100
+ const sourceToRelativeBundleMap = new Map();
1101
+ for (const [, exportCondition] of Object.entries(entries)){
1102
+ const exportDistMaps = exportCondition.export;
1103
+ const exportMapEntries = Object.entries(exportDistMaps).map(([composedKey, bundlePath])=>({
1104
+ conditionNames: new Set(composedKey.split('.')),
1105
+ bundlePath,
1106
+ format
1107
+ }));
1108
+ let matchedBundlePath;
1109
+ if (dts) {
1110
+ var _exportMapEntries_find;
1111
+ // Find the type with format condition first
1112
+ matchedBundlePath = (_exportMapEntries_find = exportMapEntries.find(findTypesFileCallback)) == null ? void 0 : _exportMapEntries_find.bundlePath;
1113
+ // If theres no format specific types such as import.types or require.types,
1114
+ // fallback to the general types file.
1115
+ if (!matchedBundlePath) {
1116
+ var _exportMapEntries_find1;
1117
+ matchedBundlePath = (_exportMapEntries_find1 = exportMapEntries.find((item)=>{
1118
+ return findTypesFileCallback({
1119
+ ...item,
1120
+ format: undefined
1121
+ });
1122
+ })) == null ? void 0 : _exportMapEntries_find1.bundlePath;
1093
1123
  }
1094
- if (isTestFile(dirent.name)) {
1095
- continue;
1124
+ } else {
1125
+ var _exportMapEntries_find2;
1126
+ matchedBundlePath = (_exportMapEntries_find2 = exportMapEntries.find(findJsBundlePathCallback)) == null ? void 0 : _exportMapEntries_find2.bundlePath;
1127
+ }
1128
+ if (matchedBundlePath) {
1129
+ if (!sourceToRelativeBundleMap.has(exportCondition.source)) sourceToRelativeBundleMap.set(exportCondition.source, matchedBundlePath);
1130
+ }
1131
+ }
1132
+ return {
1133
+ name: 'alias',
1134
+ resolveId: {
1135
+ async handler (source, importer, options) {
1136
+ const resolved = await this.resolve(source, importer, options);
1137
+ if (resolved != null) {
1138
+ // For types, generate relative path to the other type files,
1139
+ // this will be compatible for the node10 ts module resolution.
1140
+ const srcBundle = sourceToRelativeBundleMap.get(sourceFilePath);
1141
+ // Resolved module bundle path
1142
+ const resolvedModuleBundle = sourceToRelativeBundleMap.get(resolved.id);
1143
+ if (resolved.id !== sourceFilePath && srcBundle && resolvedModuleBundle) {
1144
+ const absoluteBundlePath = path__default.default.resolve(cwd, srcBundle);
1145
+ const absoluteImportBundlePath = path__default.default.resolve(cwd, resolvedModuleBundle);
1146
+ const filePathBase = path__default.default.relative(path__default.default.dirname(absoluteBundlePath), absoluteImportBundlePath);
1147
+ const relativePath = relativify(filePathBase);
1148
+ return {
1149
+ id: relativePath,
1150
+ external: true
1151
+ };
1152
+ }
1153
+ }
1154
+ return null;
1096
1155
  }
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
- };
1156
+ }
1157
+ };
1158
+ }
1159
+
1160
+ function prependDirectives() {
1161
+ return {
1162
+ name: 'prependDirective',
1163
+ transform: {
1164
+ order: 'post',
1165
+ handler (code, id) {
1166
+ var _moduleInfo_meta;
1167
+ const moduleInfo = this.getModuleInfo(id);
1168
+ if (moduleInfo == null ? void 0 : (_moduleInfo_meta = moduleInfo.meta) == null ? void 0 : _moduleInfo_meta.preserveDirectives) {
1169
+ const firstDirective = moduleInfo.meta.preserveDirectives.directives[0];
1170
+ if (firstDirective) {
1171
+ const directive = firstDirective.value;
1172
+ const directiveCode = `'${directive}';`;
1173
+ return directiveCode + '\n' + code;
1174
+ }
1112
1175
  }
1113
- exportsEntries.set(originalSubpath, sourceFilesMap);
1176
+ return null;
1114
1177
  }
1115
1178
  }
1116
- }
1179
+ };
1117
1180
  }
1181
+
1182
+ const prependShebang = (entry)=>({
1183
+ name: 'prependShebang',
1184
+ transform: (code, id)=>{
1185
+ if (id !== entry) return;
1186
+ const shebang = '#!/usr/bin/env node\n';
1187
+ if (code.startsWith(shebang)) return;
1188
+ const magicString = new MagicString__default.default(code);
1189
+ magicString.prepend(shebang);
1190
+ return {
1191
+ code: magicString.toString(),
1192
+ map: magicString.generateMap({
1193
+ hires: true
1194
+ })
1195
+ };
1196
+ }
1197
+ });
1198
+
1118
1199
  /**
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
- }
1200
+ * @return {Record<string, string>} env { 'process.env.<key>': '<value>' }
1201
+ */ function getDefinedInlineVariables(envs, parsedExportCondition) {
1202
+ if (!envs.includes('NODE_ENV')) {
1203
+ envs.push('NODE_ENV');
1204
+ }
1205
+ const envVars = envs.reduce((acc, key)=>{
1206
+ const value = process.env[key];
1207
+ if (typeof value !== 'undefined') {
1208
+ acc['process.env.' + key] = JSON.stringify(value);
1139
1209
  }
1140
- await collectSourceEntriesByExportPath(sourceFolderPath, exportPath, bins, exportsEntries);
1141
- for (const specialCondition of specialConditions){
1142
- await collectSourceEntriesByExportPath(sourceFolderPath, exportPath + '.' + specialCondition, bins, exportsEntries);
1210
+ return acc;
1211
+ }, {});
1212
+ const exportConditionNames = Object.keys(parsedExportCondition.export).reduce((acc, key)=>{
1213
+ // key could be 'require' or 'import.development' etc.
1214
+ const exportTypes = key.split('.');
1215
+ for (const exportType of exportTypes){
1216
+ acc.add(exportType);
1143
1217
  }
1218
+ return acc;
1219
+ }, new Set());
1220
+ // For development and production convention, we override the NODE_ENV value
1221
+ if (exportConditionNames.has('development')) {
1222
+ envVars['process.env.NODE_ENV'] = JSON.stringify('development');
1223
+ } else if (exportConditionNames.has('production')) {
1224
+ envVars['process.env.NODE_ENV'] = JSON.stringify('production');
1144
1225
  }
1145
- return {
1146
- bins,
1147
- exportsEntries
1148
- };
1226
+ if (exportConditionNames.has('edge-light')) {
1227
+ envVars['EdgeRuntime'] = JSON.stringify('edge-runtime');
1228
+ }
1229
+ return envVars;
1149
1230
  }
1150
1231
 
1151
1232
  function getModuleLayer(moduleMeta) {
@@ -1218,22 +1299,6 @@ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, cwd) {
1218
1299
  // Avoid create multiple dts plugins instance and parsing the same tsconfig multi times,
1219
1300
  // This will avoid memory leak and performance issue.
1220
1301
  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
1302
  async function buildInputConfig(entry, bundleConfig, exportCondition, buildContext, dts) {
1238
1303
  var _bundleConfig_file, _bundleConfig_file1;
1239
1304
  const { entries, pkg, cwd, tsOptions: { tsConfigPath, tsCompilerOptions }, pluginContext } = buildContext;
@@ -1287,7 +1352,6 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1287
1352
  const aliasPlugin = aliasEntries({
1288
1353
  entry,
1289
1354
  entries,
1290
- entriesAlias: pluginContext.entriesAlias,
1291
1355
  format: aliasFormat,
1292
1356
  dts,
1293
1357
  cwd
@@ -1576,122 +1640,6 @@ async function buildConfig(bundleConfig, exportCondition, pluginContext, bundleE
1576
1640
  return Promise.all(outputConfigs);
1577
1641
  }
1578
1642
 
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
1643
  async function createAssetRollupJobs(options, buildContext, bundleJobOptions) {
1696
1644
  const { isFromCli, generateTypes } = bundleJobOptions;
1697
1645
  const assetsConfigs = await buildEntryConfig(options, buildContext, {
@@ -1756,6 +1704,7 @@ function hasMultiEntryExport(exportPaths) {
1756
1704
  return exportKeys.length > 0 && exportKeys.every((name)=>name.startsWith('.'));
1757
1705
  }
1758
1706
  async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1707
+ var _options__callbacks_onBuildStart, _options__callbacks, _options__callbacks_onBuildEnd, _options__callbacks1;
1759
1708
  const cwd = path.resolve(process.cwd(), _cwd || '');
1760
1709
  assignDefault(options, 'format', 'esm');
1761
1710
  assignDefault(options, 'minify', false);
@@ -1827,13 +1776,9 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1827
1776
  await writeDefaultTsconfig(tsConfigPath);
1828
1777
  hasTsConfig = true;
1829
1778
  }
1830
- const sizeCollector = createOutputState({
1779
+ const outputState = createOutputState({
1831
1780
  entries
1832
1781
  });
1833
- const entriesAlias = getReversedAlias({
1834
- entries,
1835
- name: pkg.name
1836
- });
1837
1782
  const buildContext = {
1838
1783
  entries,
1839
1784
  pkg,
@@ -1841,68 +1786,18 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1841
1786
  tsOptions: defaultTsOptions,
1842
1787
  useTypeScript: hasTsConfig,
1843
1788
  pluginContext: {
1844
- outputState: sizeCollector,
1845
- moduleDirectiveLayerMap: new Map(),
1846
- entriesAlias
1789
+ outputState,
1790
+ moduleDirectiveLayerMap: new Map()
1847
1791
  }
1848
1792
  };
1793
+ (_options__callbacks = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildStart = _options__callbacks.onBuildStart) == null ? void 0 : _options__callbacks_onBuildStart.call(_options__callbacks, buildContext);
1849
1794
  const generateTypes = hasTsConfig && options.dts !== false;
1850
1795
  const rollupJobsOptions = {
1851
1796
  isFromCli,
1852
1797
  generateTypes
1853
1798
  };
1854
1799
  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
- }
1800
+ (_options__callbacks1 = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildEnd = _options__callbacks1.onBuildEnd) == null ? void 0 : _options__callbacks_onBuildEnd.call(_options__callbacks1, assetJobs);
1906
1801
  }
1907
1802
 
1908
1803
  exports.bundle = bundle;