bunchee 3.0.1 → 3.1.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/README.md CHANGED
@@ -124,7 +124,7 @@ Replace `ENV1`, `ENV2`, and `ENV3` with the names of the environment variables y
124
124
 
125
125
  ### Entry Files Convention
126
126
 
127
- While `exports` filed is becoming the standard of exporting in node.js, bunchee also supports to build multiple exports all in one command.
127
+ While `exports` field is becoming the standard of exporting in node.js, bunchee also supports to build multiple exports all in one command.
128
128
 
129
129
  What you need to do is just add an entry file with the name (`[name].[ext]`) that matches the exported name from exports field in package.json. For instance:
130
130
 
package/dist/cli.js CHANGED
@@ -37,6 +37,15 @@ function exit(err) {
37
37
  process.exit(1);
38
38
  }
39
39
  const formatDuration = (duration)=>duration >= 1000 ? `${duration / 1000}s` : `${duration}ms`;
40
+ function hasPackageJson(cwd) {
41
+ return _hasPackageJson.apply(this, arguments);
42
+ }
43
+ function _hasPackageJson() {
44
+ _hasPackageJson = _async_to_generator$1(function*(cwd) {
45
+ return yield fileExists(path.resolve(cwd, 'package.json'));
46
+ });
47
+ return _hasPackageJson.apply(this, arguments);
48
+ }
40
49
  function getPackageMeta(cwd) {
41
50
  return _getPackageMeta.apply(this, arguments);
42
51
  }
@@ -64,8 +73,25 @@ const logger = {
64
73
  console.error('\x1b[31m' + arg + '\x1b[0m');
65
74
  }
66
75
  };
76
+ function fileExists(filePath) {
77
+ return _fileExists.apply(this, arguments);
78
+ }
79
+ function _fileExists() {
80
+ _fileExists = _async_to_generator$1(function*(filePath) {
81
+ try {
82
+ yield fs.access(filePath);
83
+ return true;
84
+ } catch (err) {
85
+ if (err.code === 'ENOENT') {
86
+ return false;
87
+ }
88
+ throw err;
89
+ }
90
+ });
91
+ return _fileExists.apply(this, arguments);
92
+ }
67
93
 
68
- var version = "3.0.1";
94
+ var version = "3.1.0";
69
95
 
70
96
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
71
97
  try {
@@ -123,6 +149,10 @@ function lintPackage(cwd) {
123
149
  }
124
150
  function _lintPackage() {
125
151
  _lintPackage = _async_to_generator(function*(cwd) {
152
+ // Not package.json detected, skip package linting
153
+ if (!(yield hasPackageJson(cwd))) {
154
+ return;
155
+ }
126
156
  const { publint } = yield import('publint');
127
157
  const { printMessage } = yield import('publint/utils');
128
158
  const messages = yield publint({
package/dist/index.d.ts CHANGED
@@ -23,6 +23,6 @@ type BundleConfig = {
23
23
  };
24
24
  type ExportCondition = string | Record<ExportType, string>;
25
25
 
26
- declare function bundle(entryPath: string, { cwd, ...options }?: BundleConfig): Promise<any>;
26
+ declare function bundle(entryPath: string, { cwd: _cwd, ...options }?: BundleConfig): Promise<any>;
27
27
 
28
28
  export { BundleConfig, bundle };
package/dist/index.js CHANGED
@@ -3,25 +3,57 @@ Object.defineProperty(exports, '__esModule', { value: true });
3
3
  var fs = require('fs/promises');
4
4
  var path = require('path');
5
5
  var rollup = require('rollup');
6
- var fs$1 = require('fs');
7
- var module$1 = require('module');
8
6
  var rollupPluginSwc3 = require('rollup-plugin-swc3');
9
7
  var commonjs = require('@rollup/plugin-commonjs');
10
8
  var shebang = require('rollup-plugin-preserve-shebang');
11
9
  var json = require('@rollup/plugin-json');
12
10
  var pluginNodeResolve = require('@rollup/plugin-node-resolve');
13
11
  var replace = require('@rollup/plugin-replace');
12
+ var prettyBytes = require('pretty-bytes');
13
+ var module$1 = require('module');
14
14
 
15
- const rootDir = process.cwd();
16
- var config = {
17
- rootDir
18
- };
15
+ function chunkSizeCollector() {
16
+ const sizes = new Map();
17
+ function addSize(name, size) {
18
+ sizes.set(name, size);
19
+ }
20
+ return {
21
+ plugin: (cwd)=>{
22
+ return {
23
+ name: 'collect-sizes',
24
+ augmentChunkHash () {
25
+ // Do nothing, but use the hook to keep the plugin instance alive
26
+ },
27
+ renderChunk (code, chunk, options) {
28
+ const dir = options.dir || options.file && path.dirname(options.file);
29
+ let fileName = chunk.fileName;
30
+ if (dir) {
31
+ fileName = path.relative(cwd, path.join(dir, fileName));
32
+ }
33
+ addSize(fileName, code.length);
34
+ return null;
35
+ }
36
+ };
37
+ },
38
+ getSizeStats () {
39
+ const sizeStats = [];
40
+ sizes.forEach((size, name)=>{
41
+ sizeStats.push([
42
+ name,
43
+ prettyBytes(size),
44
+ size
45
+ ]);
46
+ });
47
+ return sizeStats;
48
+ }
49
+ };
50
+ }
19
51
 
20
52
  function getTypings(pkg) {
21
53
  return pkg.types || pkg.typings;
22
54
  }
23
- function getDistPath(distPath) {
24
- return path.resolve(config.rootDir, distPath);
55
+ function getDistPath(distPath, cwd) {
56
+ return path.resolve(cwd, distPath);
25
57
  }
26
58
  function findExport(field) {
27
59
  if (!field) return;
@@ -68,67 +100,64 @@ function getExportPaths(pkg) {
68
100
  pathsMap['.'] = mainExport;
69
101
  return pathsMap;
70
102
  }
71
- function getExportDist(pkg) {
103
+ function getExportDist(pkg, cwd) {
72
104
  const paths = getExportPaths(pkg)['.'];
73
105
  const dist = [];
74
106
  if (paths.main) {
75
107
  dist.push({
76
108
  format: 'cjs',
77
- file: getDistPath(paths.main)
109
+ file: getDistPath(paths.main, cwd)
78
110
  });
79
111
  }
80
112
  if (paths.module) {
81
113
  dist.push({
82
114
  format: 'esm',
83
- file: getDistPath(paths.module)
115
+ file: getDistPath(paths.module, cwd)
84
116
  });
85
117
  }
86
118
  if (paths.export) {
87
119
  dist.push({
88
120
  format: 'esm',
89
- file: getDistPath(paths.export)
121
+ file: getDistPath(paths.export, cwd)
90
122
  });
91
123
  }
92
124
  // default fallback to output `dist/index.js` in default esm format
93
125
  if (dist.length === 0) {
94
126
  dist.push({
95
127
  format: 'esm',
96
- file: getDistPath('dist/index.js')
128
+ file: getDistPath('dist/index.js', cwd)
97
129
  });
98
130
  }
99
131
  return dist;
100
132
  }
101
- function getExportConditionDist(pkg, exportCondition) {
102
- // const pkgExports = pkg.exports || {}
133
+ function getExportConditionDist(pkg, exportCondition, cwd) {
103
134
  const dist = [];
104
135
  // "exports": "..."
105
136
  if (typeof exportCondition === 'string') {
106
137
  dist.push({
107
138
  format: pkg.type === 'module' ? 'esm' : 'cjs',
108
- file: getDistPath(exportCondition)
139
+ file: getDistPath(exportCondition, cwd)
109
140
  });
110
141
  } else {
111
142
  // "./<subexport>": { }
112
- const subExports = exportCondition // pkgExports[subExport]
113
- ;
143
+ const subExports = exportCondition;
114
144
  // Ignore json exports, like "./package.json"
115
- // if (subExport.endsWith('.json')) return dist
116
145
  if (typeof subExports === 'string') {
117
146
  dist.push({
118
147
  format: 'esm',
119
- file: getDistPath(subExports)
148
+ file: getDistPath(subExports, cwd)
120
149
  });
121
150
  } else {
122
151
  if (subExports.require) {
123
152
  dist.push({
124
153
  format: 'cjs',
125
- file: getDistPath(subExports.require)
154
+ file: getDistPath(subExports.require, cwd)
126
155
  });
127
156
  }
128
157
  if (subExports.import) {
129
158
  dist.push({
130
159
  format: 'esm',
131
- file: getDistPath(subExports.import)
160
+ file: getDistPath(subExports.import, cwd)
132
161
  });
133
162
  }
134
163
  }
@@ -136,7 +165,7 @@ function getExportConditionDist(pkg, exportCondition) {
136
165
  return dist;
137
166
  }
138
167
 
139
- function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
168
+ function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
140
169
  try {
141
170
  var info = gen[key](arg);
142
171
  var value = info.value;
@@ -150,16 +179,16 @@ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
150
179
  Promise.resolve(value).then(_next, _throw);
151
180
  }
152
181
  }
153
- function _async_to_generator$1(fn) {
182
+ function _async_to_generator$3(fn) {
154
183
  return function() {
155
184
  var self = this, args = arguments;
156
185
  return new Promise(function(resolve, reject) {
157
186
  var gen = fn.apply(self, args);
158
187
  function _next(value) {
159
- asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
188
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "next", value);
160
189
  }
161
190
  function _throw(err) {
162
- asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
191
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "throw", err);
163
192
  }
164
193
  _next(undefined);
165
194
  });
@@ -169,12 +198,11 @@ function exit(err) {
169
198
  logger.error(err);
170
199
  process.exit(1);
171
200
  }
172
- const formatDuration = (duration)=>duration >= 1000 ? `${duration / 1000}s` : `${duration}ms`;
173
201
  function getPackageMeta(cwd) {
174
202
  return _getPackageMeta.apply(this, arguments);
175
203
  }
176
204
  function _getPackageMeta() {
177
- _getPackageMeta = _async_to_generator$1(function*(cwd) {
205
+ _getPackageMeta = _async_to_generator$3(function*(cwd) {
178
206
  const pkgFilePath = path.resolve(cwd, 'package.json');
179
207
  let targetPackageJson = {};
180
208
  try {
@@ -197,15 +225,11 @@ const logger = {
197
225
  console.error('\x1b[31m' + arg + '\x1b[0m');
198
226
  }
199
227
  };
200
- function isTypescript(filename) {
201
- const ext = path.extname(filename);
202
- return ext === '.ts' || ext === '.tsx';
203
- }
204
228
  function fileExists(filePath) {
205
229
  return _fileExists.apply(this, arguments);
206
230
  }
207
231
  function _fileExists() {
208
- _fileExists = _async_to_generator$1(function*(filePath) {
232
+ _fileExists = _async_to_generator$3(function*(filePath) {
209
233
  try {
210
234
  yield fs.access(filePath);
211
235
  return true;
@@ -218,8 +242,78 @@ function _fileExists() {
218
242
  });
219
243
  return _fileExists.apply(this, arguments);
220
244
  }
245
+ // . -> pkg name
246
+ // ./lite -> <pkg name>/lite
247
+ function getExportPath(pkg, cwd, exportName) {
248
+ const name = pkg.name || path.basename(cwd);
249
+ if (exportName === '.' || !exportName) return name;
250
+ return path.join(name, exportName);
251
+ }
221
252
  const isNotNull = (n)=>Boolean(n);
253
+ const SRC = 'src' // resolve from src/ directory
254
+ ;
255
+ function resolveSourceFile(cwd, filename) {
256
+ return path.resolve(cwd, SRC, filename);
257
+ }
258
+ // Map '.' -> './index.[ext]'
259
+ // Map './lite' -> './lite.[ext]'
260
+ // Return undefined if no match or if it's package.json exports
261
+ function getSourcePathFromExportPath(cwd, exportPath) {
262
+ return _getSourcePathFromExportPath.apply(this, arguments);
263
+ }
264
+ function _getSourcePathFromExportPath() {
265
+ _getSourcePathFromExportPath = _async_to_generator$3(function*(cwd, exportPath) {
266
+ const exts = [
267
+ 'js',
268
+ 'cjs',
269
+ 'mjs',
270
+ 'jsx',
271
+ 'ts',
272
+ 'tsx'
273
+ ];
274
+ for (const ext of exts){
275
+ // ignore package.json
276
+ if (exportPath.endsWith('package.json')) return;
277
+ if (exportPath === '.') exportPath = './index';
278
+ const filename = resolveSourceFile(cwd, `${exportPath}.${ext}`);
279
+ if (yield fileExists(filename)) {
280
+ return filename;
281
+ }
282
+ }
283
+ return;
284
+ });
285
+ return _getSourcePathFromExportPath.apply(this, arguments);
286
+ }
222
287
 
288
+ function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
289
+ try {
290
+ var info = gen[key](arg);
291
+ var value = info.value;
292
+ } catch (error) {
293
+ reject(error);
294
+ return;
295
+ }
296
+ if (info.done) {
297
+ resolve(value);
298
+ } else {
299
+ Promise.resolve(value).then(_next, _throw);
300
+ }
301
+ }
302
+ function _async_to_generator$2(fn) {
303
+ return function() {
304
+ var self = this, args = arguments;
305
+ return new Promise(function(resolve, reject) {
306
+ var gen = fn.apply(self, args);
307
+ function _next(value) {
308
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
309
+ }
310
+ function _throw(err) {
311
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
312
+ }
313
+ _next(undefined);
314
+ });
315
+ };
316
+ }
223
317
  function _extends$1() {
224
318
  _extends$1 = Object.assign || function(target) {
225
319
  for(var i = 1; i < arguments.length; i++){
@@ -245,22 +339,8 @@ const minifyOptions = {
245
339
  toplevel: true
246
340
  }
247
341
  };
248
- let hasLoggedTsWarning = false;
249
- function resolveTypescript(cwd) {
250
- let ts;
251
- const m = new module$1.Module('', undefined);
252
- m.paths = module$1.Module._nodeModulePaths(cwd);
253
- try {
254
- ts = m.require('typescript');
255
- } catch (_) {
256
- console.error(_);
257
- if (!hasLoggedTsWarning) {
258
- hasLoggedTsWarning = true;
259
- exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency');
260
- }
261
- }
262
- return ts;
263
- }
342
+ // This can also be passed down as stats from top level
343
+ const sizeCollector = chunkSizeCollector();
264
344
  function getBuildEnv(envs) {
265
345
  if (!envs.includes('NODE_ENV')) {
266
346
  envs.push('NODE_ENV');
@@ -274,7 +354,7 @@ function getBuildEnv(envs) {
274
354
  }, {});
275
355
  return envVars;
276
356
  }
277
- function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOptions , dtsOnly }) {
357
+ function buildInputConfig(entry, pkg, options, cwd, { tsConfigPath , tsCompilerOptions }, dtsOnly) {
278
358
  var _options_external;
279
359
  const externals = options.noExternal ? [] : [
280
360
  pkg.peerDependencies,
@@ -285,8 +365,13 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
285
365
  ] : []));
286
366
  const { useTypescript , runtime , target: jscTarget , minify } = options;
287
367
  const hasSpecifiedTsTarget = Boolean((tsCompilerOptions == null ? void 0 : tsCompilerOptions.target) && tsConfigPath);
288
- const plugins = (dtsOnly ? [
368
+ const sizePlugin = sizeCollector.plugin(cwd);
369
+ const commonPlugins = [
289
370
  shebang(),
371
+ sizePlugin
372
+ ];
373
+ const plugins = (dtsOnly ? [
374
+ ...commonPlugins,
290
375
  useTypescript && require('rollup-plugin-dts').default({
291
376
  compilerOptions: _extends$1({}, tsCompilerOptions, {
292
377
  declaration: true,
@@ -304,6 +389,7 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
304
389
  })
305
390
  })
306
391
  ] : [
392
+ ...commonPlugins,
307
393
  replace({
308
394
  values: getBuildEnv(options.env || []),
309
395
  preventAssignment: true
@@ -322,7 +408,6 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
322
408
  include: /node_modules\//
323
409
  }),
324
410
  json(),
325
- shebang(),
326
411
  rollupPluginSwc3.swc({
327
412
  include: /\.(m|c)?[jt]sx?$/,
328
413
  exclude: 'node_modules',
@@ -375,20 +460,19 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
375
460
  }
376
461
  };
377
462
  }
378
- function buildOutputConfigs(options, pkg, { tsCompilerOptions , dtsOnly }) {
463
+ function buildOutputConfigs(pkg, options, cwd, { tsCompilerOptions }, dtsOnly) {
379
464
  const { format , exportCondition } = options;
380
465
  const exportPaths = getExportPaths(pkg);
381
466
  // respect if tsconfig.json has `esModuleInterop` config;
382
467
  // add ESModule mark if cjs and ESModule are both generated;
383
- // TODO: support `import` in exportCondition
384
468
  const mainExport = exportPaths['.'];
385
469
  const useEsModuleMark = Boolean(tsCompilerOptions.esModuleInterop || mainExport.main && mainExport.module);
386
470
  const typings = getTypings(pkg);
387
- const file = options.file && path.resolve(config.rootDir, options.file);
388
- const dtsDir = typings ? path.dirname(path.resolve(config.rootDir, typings)) : path.resolve(config.rootDir, 'dist');
471
+ const file = options.file && path.resolve(cwd, options.file);
472
+ const dtsDir = typings ? path.dirname(path.resolve(cwd, typings)) : path.resolve(cwd, 'dist');
389
473
  // file base name without extension
390
474
  const name = file ? file.replace(new RegExp(`${path.extname(file)}$`), '') : undefined;
391
- const dtsFile = file ? name + '.d.ts' : (exportCondition == null ? void 0 : exportCondition.name) ? path.resolve(dtsDir, (exportCondition.name === '.' ? 'index' : exportCondition.name) + '.d.ts') : typings && path.resolve(config.rootDir, typings);
475
+ const dtsFile = file ? name + '.d.ts' : (exportCondition == null ? void 0 : exportCondition.name) ? path.resolve(dtsDir, (exportCondition.name === '.' ? 'index' : exportCondition.name) + '.d.ts') : typings && path.resolve(cwd, typings);
392
476
  // If there's dts file, use `output.file`
393
477
  const dtsPathConfig = dtsFile ? {
394
478
  file: dtsFile
@@ -408,72 +492,156 @@ function buildOutputConfigs(options, pkg, { tsCompilerOptions , dtsOnly }) {
408
492
  sourcemap: options.sourcemap
409
493
  });
410
494
  }
411
- function buildConfig(entry, pkg, bundleConfig, dtsOnly) {
495
+ // build configs for each entry from package exports
496
+ function buildEntryConfig(pkg, bundleConfig, cwd, tsOptions, dtsOnly) {
497
+ return _buildEntryConfig.apply(this, arguments);
498
+ }
499
+ function _buildEntryConfig() {
500
+ _buildEntryConfig = _async_to_generator$2(function*(pkg, bundleConfig, cwd, tsOptions, dtsOnly) {
501
+ const packageExports = pkg.exports || {};
502
+ const configs = Object.keys(packageExports).map(/*#__PURE__*/ _async_to_generator$2(function*(entryExport) {
503
+ const source = yield getSourcePathFromExportPath(cwd, entryExport);
504
+ if (!source) return undefined;
505
+ if (dtsOnly && !(tsOptions == null ? void 0 : tsOptions.tsConfigPath)) return;
506
+ bundleConfig.exportCondition = {
507
+ source,
508
+ name: entryExport,
509
+ export: packageExports[entryExport]
510
+ };
511
+ const entry = resolveSourceFile(cwd, source);
512
+ const rollupConfig = buildConfig(entry, pkg, bundleConfig, cwd, tsOptions, dtsOnly);
513
+ return rollupConfig;
514
+ }));
515
+ return (yield Promise.all(configs)).filter((n)=>Boolean(n));
516
+ });
517
+ return _buildEntryConfig.apply(this, arguments);
518
+ }
519
+ function buildConfig(entry, pkg, bundleConfig, cwd, tsOptions, dtsOnly) {
412
520
  var _options_exportCondition;
413
521
  const { file } = bundleConfig;
414
- const useTypescript = isTypescript(entry);
522
+ const useTypescript = Boolean(tsOptions.tsConfigPath);
415
523
  const options = _extends$1({}, bundleConfig, {
416
524
  useTypescript
417
525
  });
418
- let tsCompilerOptions = {};
419
- let tsConfigPath;
420
- if (useTypescript) {
421
- const ts = resolveTypescript(config.rootDir);
422
- tsConfigPath = path.resolve(config.rootDir, 'tsconfig.json');
423
- if (fs$1.existsSync(tsConfigPath)) {
424
- const basePath = tsConfigPath ? path.dirname(tsConfigPath) : config.rootDir;
425
- const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
426
- tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
427
- } else {
428
- tsConfigPath = undefined;
429
- exit('tsconfig.json is missing in your project directory');
430
- }
431
- }
432
- const typescriptOptions = {
433
- dtsOnly,
434
- tsConfigPath,
435
- tsCompilerOptions
436
- };
437
- const inputOptions = buildInputConfig(entry, pkg, options, typescriptOptions);
438
- const outputExports = options.exportCondition ? getExportConditionDist(pkg, options.exportCondition.export) : getExportDist(pkg);
526
+ const inputOptions = buildInputConfig(entry, pkg, options, cwd, tsOptions, dtsOnly);
527
+ const outputExports = options.exportCondition ? getExportConditionDist(pkg, options.exportCondition.export, cwd) : getExportDist(pkg, cwd);
439
528
  let outputConfigs = [];
440
529
  // Generate dts job - single config
441
530
  if (dtsOnly) {
442
531
  outputConfigs = [
443
- buildOutputConfigs(_extends$1({}, bundleConfig, {
532
+ buildOutputConfigs(pkg, _extends$1({}, bundleConfig, {
444
533
  format: 'es',
445
534
  useTypescript
446
- }), pkg, typescriptOptions)
535
+ }), cwd, tsOptions, dtsOnly)
447
536
  ];
448
537
  } else {
449
538
  // multi outputs with specified format
450
539
  outputConfigs = outputExports.map((exportDist)=>{
451
- return buildOutputConfigs(_extends$1({}, bundleConfig, {
540
+ return buildOutputConfigs(pkg, _extends$1({}, bundleConfig, {
452
541
  file: exportDist.file,
453
542
  format: exportDist.format,
454
543
  useTypescript
455
- }), pkg, typescriptOptions);
544
+ }), cwd, tsOptions, dtsOnly);
456
545
  });
457
546
  // CLI output option is always prioritized
458
547
  if (file) {
459
548
  var _outputExports_;
460
549
  const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format;
461
550
  outputConfigs = [
462
- buildOutputConfigs(_extends$1({}, bundleConfig, {
551
+ buildOutputConfigs(pkg, _extends$1({}, bundleConfig, {
463
552
  file,
464
553
  format: bundleConfig.format || fallbackFormat,
465
554
  useTypescript
466
- }), pkg, typescriptOptions)
555
+ }), cwd, tsOptions, dtsOnly)
467
556
  ];
468
557
  }
469
558
  }
470
559
  return {
471
560
  input: inputOptions,
472
561
  output: outputConfigs,
473
- exportName: ((_options_exportCondition = options.exportCondition) == null ? void 0 : _options_exportCondition.name) || '.',
474
- dtsOnly
562
+ exportName: ((_options_exportCondition = options.exportCondition) == null ? void 0 : _options_exportCondition.name) || '.'
563
+ };
564
+ }
565
+
566
+ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
567
+ try {
568
+ var info = gen[key](arg);
569
+ var value = info.value;
570
+ } catch (error) {
571
+ reject(error);
572
+ return;
573
+ }
574
+ if (info.done) {
575
+ resolve(value);
576
+ } else {
577
+ Promise.resolve(value).then(_next, _throw);
578
+ }
579
+ }
580
+ function _async_to_generator$1(fn) {
581
+ return function() {
582
+ var self = this, args = arguments;
583
+ return new Promise(function(resolve, reject) {
584
+ var gen = fn.apply(self, args);
585
+ function _next(value) {
586
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
587
+ }
588
+ function _throw(err) {
589
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
590
+ }
591
+ _next(undefined);
592
+ });
475
593
  };
476
594
  }
595
+ let hasLoggedTsWarning = false;
596
+ function resolveTypescript(cwd) {
597
+ let ts;
598
+ const m = new module$1.Module('', undefined);
599
+ m.paths = module$1.Module._nodeModulePaths(cwd);
600
+ try {
601
+ ts = m.require('typescript');
602
+ } catch (_) {
603
+ console.error(_);
604
+ if (!hasLoggedTsWarning) {
605
+ hasLoggedTsWarning = true;
606
+ exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency');
607
+ }
608
+ }
609
+ return ts;
610
+ }
611
+ function resolveTsConfig(cwd) {
612
+ return _resolveTsConfig.apply(this, arguments);
613
+ }
614
+ function _resolveTsConfig() {
615
+ _resolveTsConfig = _async_to_generator$1(function*(cwd) {
616
+ let tsCompilerOptions = {};
617
+ let tsConfigPath;
618
+ const ts = resolveTypescript(cwd);
619
+ tsConfigPath = path.resolve(cwd, 'tsconfig.json');
620
+ if (yield fileExists(tsConfigPath)) {
621
+ const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
622
+ const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
623
+ tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
624
+ } else {
625
+ tsConfigPath = undefined;
626
+ return null;
627
+ }
628
+ return {
629
+ tsCompilerOptions,
630
+ tsConfigPath
631
+ };
632
+ });
633
+ return _resolveTsConfig.apply(this, arguments);
634
+ }
635
+
636
+ function logSizeStats() {
637
+ const stats = sizeCollector.getSizeStats();
638
+ const maxLength = Math.max(...stats.map(([filename])=>filename.length));
639
+ stats.forEach(([filename, prettiedSize])=>{
640
+ const padding = ' '.repeat(maxLength - filename.length);
641
+ const action = filename.endsWith('.d.ts') ? 'Typed' : 'Built';
642
+ logger.log(` ✓ ${action} ${filename}${padding} - ${prettiedSize}`);
643
+ });
644
+ }
477
645
 
478
646
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
479
647
  try {
@@ -530,48 +698,11 @@ function _object_without_properties_loose(source, excluded) {
530
698
  }
531
699
  return target;
532
700
  }
533
- const SRC = 'src' // resolve from src/ directory
534
- ;
535
- function logBuild(exportPath, dtsOnly, duration) {
536
- logger.log(` ✓ ${dtsOnly ? 'Typed' : 'Built'} ${exportPath} ${formatDuration(duration)}`);
537
- }
538
701
  function assignDefault(options, name, defaultValue) {
539
702
  if (!(name in options) || options[name] == null) {
540
703
  options[name] = defaultValue;
541
704
  }
542
705
  }
543
- function resolveSourceFile(cwd, filename) {
544
- return path.resolve(cwd, SRC, filename);
545
- }
546
- function getSourcePathFromExportPath(cwd, exportPath) {
547
- return _getSourcePathFromExportPath.apply(this, arguments);
548
- }
549
- function _getSourcePathFromExportPath() {
550
- _getSourcePathFromExportPath = // Map '.' -> './index.[ext]'
551
- // Map './lite' -> './lite.[ext]'
552
- // Return undefined if no match or if it's package.json exports
553
- _async_to_generator(function*(cwd, exportPath) {
554
- const exts = [
555
- 'js',
556
- 'cjs',
557
- 'mjs',
558
- 'jsx',
559
- 'ts',
560
- 'tsx'
561
- ];
562
- for (const ext of exts){
563
- // ignore package.json
564
- if (exportPath.endsWith('package.json')) return;
565
- if (exportPath === '.') exportPath = './index';
566
- const filename = resolveSourceFile(cwd, `${exportPath}.${ext}`);
567
- if (yield fileExists(filename)) {
568
- return filename;
569
- }
570
- }
571
- return;
572
- });
573
- return _getSourcePathFromExportPath.apply(this, arguments);
574
- }
575
706
  function hasMultiEntryExport(pkg) {
576
707
  const packageExportsField = pkg.exports || {};
577
708
  if (typeof packageExportsField === 'string') return false;
@@ -583,56 +714,40 @@ function bundle(entryPath) {
583
714
  }
584
715
  function _bundle() {
585
716
  _bundle = _async_to_generator(function*(entryPath, _param = {}) {
586
- var { cwd } = _param, options = _object_without_properties_loose(_param, [
717
+ var { cwd: _cwd } = _param, options = _object_without_properties_loose(_param, [
587
718
  "cwd"
588
719
  ]);
589
- config.rootDir = path.resolve(process.cwd(), cwd || '');
720
+ const cwd = path.resolve(process.cwd(), _cwd || '');
590
721
  assignDefault(options, 'format', 'es');
591
722
  assignDefault(options, 'minify', false);
592
723
  assignDefault(options, 'target', 'es2015');
593
- const pkg = yield getPackageMeta(config.rootDir);
724
+ const pkg = yield getPackageMeta(cwd);
594
725
  const packageExportsField = pkg.exports || {};
595
726
  const isMultiEntries = hasMultiEntryExport(pkg);
727
+ const tsConfig = yield resolveTsConfig(cwd);
728
+ const hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
729
+ const defaultTsOptions = {
730
+ tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
731
+ tsCompilerOptions: (tsConfig == null ? void 0 : tsConfig.tsCompilerOptions) || {}
732
+ };
596
733
  // Handle single entry file
597
734
  if (!isMultiEntries) {
598
735
  // Use specified string file path if possible, then fallback to the default behavior entry picking logic
599
736
  // e.g. "exports": "./dist/index.js" -> use "./index.<ext>" as entry
600
- entryPath = entryPath || (yield getSourcePathFromExportPath(config.rootDir, '.')) || '';
601
- }
602
- function buildEntryConfig(packageExports, dtsOnly) {
603
- return _buildEntryConfig.apply(this, arguments);
604
- }
605
- function _buildEntryConfig() {
606
- _buildEntryConfig = _async_to_generator(function*(packageExports, dtsOnly) {
607
- const configs = Object.keys(packageExports).map(/*#__PURE__*/ _async_to_generator(function*(entryExport) {
608
- const source = yield getSourcePathFromExportPath(config.rootDir, entryExport);
609
- if (!source) return undefined;
610
- if (dtsOnly && !isTypescript(source)) return;
611
- options.exportCondition = {
612
- source,
613
- name: entryExport,
614
- export: packageExports[entryExport]
615
- };
616
- const entry = resolveSourceFile(cwd, source);
617
- const rollupConfig = buildConfig(entry, pkg, options, dtsOnly);
618
- return rollupConfig;
619
- }));
620
- return (yield Promise.all(configs)).filter((n)=>Boolean(n));
621
- });
622
- return _buildEntryConfig.apply(this, arguments);
737
+ entryPath = entryPath || (yield getSourcePathFromExportPath(cwd, '.')) || '';
623
738
  }
624
739
  const bundleOrWatch = (rollupConfig)=>{
625
740
  const { input , exportName } = rollupConfig;
626
- const exportPath = getExportPath(pkg, exportName);
741
+ const exportPath = getExportPath(pkg, cwd, exportName);
627
742
  // Log original entry file relative path
628
- const source = typeof input.input === 'string' ? path.relative(config.rootDir, input.input) : exportPath;
743
+ const source = typeof input.input === 'string' ? path.relative(cwd, input.input) : exportPath;
629
744
  const buildMetadata = {
630
745
  source
631
746
  };
632
747
  if (options.watch) {
633
748
  return Promise.resolve(runWatch(rollupConfig, buildMetadata));
634
749
  }
635
- return runBundle(rollupConfig, buildMetadata);
750
+ return runBundle(rollupConfig);
636
751
  };
637
752
  const hasSpecifiedEntryFile = entryPath ? (yield fileExists(entryPath)) && (yield fs.stat(entryPath)).isFile() : false;
638
753
  if (!hasSpecifiedEntryFile && !isMultiEntries) {
@@ -646,30 +761,26 @@ function _bundle() {
646
761
  if (hasTypings) {
647
762
  options.dts = hasTypings;
648
763
  }
764
+ let result;
649
765
  if (isMultiEntries) {
650
- const pkgExports = packageExportsField;
651
- const buildConfigs = yield buildEntryConfig(pkgExports, false);
766
+ const buildConfigs = yield buildEntryConfig(pkg, options, cwd, defaultTsOptions, false);
652
767
  const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
653
- const typesJobs = options.dts ? (yield buildEntryConfig(pkgExports, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
654
- return yield Promise.all(assetsJobs.concat(typesJobs));
655
- }
656
- // Generate types
657
- if (isTypescript(entryPath) && options.dts) {
658
- yield bundleOrWatch(buildConfig(entryPath, pkg, options, true));
768
+ const typesJobs = options.dts ? (yield buildEntryConfig(pkg, options, cwd, defaultTsOptions, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
769
+ result = yield Promise.all(assetsJobs.concat(typesJobs));
770
+ } else {
771
+ // Generate types
772
+ if (hasTsConfig && options.dts) {
773
+ yield bundleOrWatch(buildConfig(entryPath, pkg, options, cwd, defaultTsOptions, true));
774
+ }
775
+ const rollupConfig = buildConfig(entryPath, pkg, options, cwd, defaultTsOptions, false);
776
+ result = yield bundleOrWatch(rollupConfig);
659
777
  }
660
- const rollupConfig = buildConfig(entryPath, pkg, options, false);
661
- return bundleOrWatch(rollupConfig);
778
+ logSizeStats();
779
+ return result;
662
780
  });
663
781
  return _bundle.apply(this, arguments);
664
782
  }
665
- // . -> pkg name
666
- // ./lite -> <pkg name>/lite
667
- function getExportPath(pkg, exportName) {
668
- const name = pkg.name || path.basename(config.rootDir);
669
- if (exportName === '.' || !exportName) return name;
670
- return path.join(name, exportName);
671
- }
672
- function runWatch({ input , output , dtsOnly }, metadata) {
783
+ function runWatch({ input , output }, metadata) {
673
784
  const watchOptions = [
674
785
  _extends({}, input, {
675
786
  output: output,
@@ -681,7 +792,6 @@ function runWatch({ input , output , dtsOnly }, metadata) {
681
792
  })
682
793
  ];
683
794
  const watcher = rollup.watch(watchOptions);
684
- let startTime = Date.now();
685
795
  watcher.on('event', (event)=>{
686
796
  switch(event.code){
687
797
  case 'ERROR':
@@ -690,14 +800,11 @@ function runWatch({ input , output , dtsOnly }, metadata) {
690
800
  }
691
801
  case 'START':
692
802
  {
693
- startTime = Date.now();
694
803
  logger.log(`Start building ${metadata.source} ...`);
695
804
  break;
696
805
  }
697
806
  case 'END':
698
807
  {
699
- const duration = Date.now() - startTime;
700
- logBuild(metadata.source, dtsOnly, duration);
701
808
  break;
702
809
  }
703
810
  default:
@@ -706,15 +813,11 @@ function runWatch({ input , output , dtsOnly }, metadata) {
706
813
  });
707
814
  return watcher;
708
815
  }
709
- function runBundle({ input , output , dtsOnly }, jobOptions) {
710
- const startTime = Date.now();
816
+ function runBundle({ input , output }) {
711
817
  return rollup.rollup(input).then((bundle)=>{
712
818
  const writeJobs = output.map((options)=>bundle.write(options));
713
819
  return Promise.all(writeJobs);
714
- }, onError).then(()=>{
715
- const duration = Date.now() - startTime;
716
- logBuild(jobOptions.source, dtsOnly, duration);
717
- });
820
+ }, onError);
718
821
  }
719
822
  function onError(error) {
720
823
  if (!error) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "3.0.1",
3
+ "version": "3.1.0",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": {
6
6
  "bunchee": "./dist/cli.js"
@@ -31,6 +31,10 @@
31
31
  "dist",
32
32
  "*.md"
33
33
  ],
34
+ "prettier": {
35
+ "semi": false,
36
+ "singleQuote": true
37
+ },
34
38
  "engines": {
35
39
  "node": ">= 16"
36
40
  },
@@ -48,6 +52,7 @@
48
52
  "@swc/core": "1.3.46",
49
53
  "@swc/helpers": "0.5.0",
50
54
  "arg": "5.0.2",
55
+ "pretty-bytes": "5.6.0",
51
56
  "publint": "0.1.11",
52
57
  "rollup": "3.20.2",
53
58
  "rollup-plugin-dts": "5.3.0",