bunchee 3.2.0 → 3.3.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/cli.js CHANGED
@@ -1,15 +1,284 @@
1
- #!/usr/bin/env node
2
- var path = require('path');
3
- var arg = require('arg');
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
4
3
  var fs = require('fs/promises');
4
+ var path = require('path');
5
+ var rollup = require('rollup');
6
+ var pluginWasm = require('@rollup/plugin-wasm');
7
+ var rollupPluginSwc3 = require('rollup-plugin-swc3');
8
+ var commonjs = require('@rollup/plugin-commonjs');
9
+ var shebang = require('rollup-plugin-preserve-shebang');
10
+ var json = require('@rollup/plugin-json');
11
+ var pluginNodeResolve = require('@rollup/plugin-node-resolve');
12
+ var replace = require('@rollup/plugin-replace');
13
+ var prettyBytes = require('pretty-bytes');
14
+ var module$1 = require('module');
5
15
 
6
16
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
17
 
8
- var path__default = /*#__PURE__*/_interopDefault(path);
9
- var arg__default = /*#__PURE__*/_interopDefault(arg);
10
18
  var fs__default = /*#__PURE__*/_interopDefault(fs);
19
+ var path__default = /*#__PURE__*/_interopDefault(path);
20
+ var commonjs__default = /*#__PURE__*/_interopDefault(commonjs);
21
+ var shebang__default = /*#__PURE__*/_interopDefault(shebang);
22
+ var json__default = /*#__PURE__*/_interopDefault(json);
23
+ var replace__default = /*#__PURE__*/_interopDefault(replace);
24
+ var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes);
11
25
 
12
- function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
26
+ function chunkSizeCollector() {
27
+ const sizes = new Map();
28
+ function addSize(name, size) {
29
+ sizes.set(name, size);
30
+ }
31
+ return {
32
+ plugin: (cwd)=>{
33
+ return {
34
+ name: 'collect-sizes',
35
+ augmentChunkHash () {
36
+ // Do nothing, but use the hook to keep the plugin instance alive
37
+ },
38
+ renderChunk (code, chunk, options) {
39
+ const dir = options.dir || options.file && path__default.default.dirname(options.file);
40
+ let fileName = chunk.fileName;
41
+ if (dir) {
42
+ const filePath = path__default.default.join(dir, fileName);
43
+ fileName = filePath.startsWith(cwd) ? path__default.default.relative(cwd, filePath) : filePath;
44
+ }
45
+ addSize(fileName, code.length);
46
+ return null;
47
+ }
48
+ };
49
+ },
50
+ getSizeStats () {
51
+ const sizeStats = [];
52
+ sizes.forEach((size, name)=>{
53
+ sizeStats.push([
54
+ name,
55
+ prettyBytes__default.default(size),
56
+ size
57
+ ]);
58
+ });
59
+ return sizeStats;
60
+ }
61
+ };
62
+ }
63
+
64
+ function getTypings(pkg) {
65
+ return pkg.types || pkg.typings;
66
+ }
67
+ function getDistPath(distPath, cwd) {
68
+ return path.resolve(cwd, distPath);
69
+ }
70
+ // Reached the end of the export path
71
+ function isExportLike(field) {
72
+ if (typeof field === 'string') return true;
73
+ return Object.entries(field).every(// Every value is string and key is not start with '.'
74
+ // TODO: check key is ExportType
75
+ ([key, value])=>typeof value === 'string' && !key.startsWith('.'));
76
+ }
77
+ function constructFullExportCondition(value, packageType) {
78
+ const isCommonjs = packageType === 'commonjs';
79
+ let result;
80
+ if (typeof value === 'string') {
81
+ // TODO: determine cjs or esm by "type" field in package.json
82
+ result = {
83
+ [isCommonjs ? 'require' : 'import']: value
84
+ };
85
+ } else {
86
+ // TODO: valid export condition, warn if it's not valid
87
+ const keys = Object.keys(value);
88
+ result = {};
89
+ keys.forEach((key)=>{
90
+ // Filter out nullable value
91
+ if (key in value && value[key]) {
92
+ result[key] = value[key];
93
+ }
94
+ });
95
+ }
96
+ return result;
97
+ }
98
+ function joinRelativePath(...segments) {
99
+ let result = path.join(...segments);
100
+ // If the first segment starts with './', ensure the result does too.
101
+ if (segments[0] === '.' && !result.startsWith('./')) {
102
+ result = './' + result;
103
+ }
104
+ return result;
105
+ }
106
+ function findExport(name, value, paths, packageType) {
107
+ // TODO: handle export condition based on package.type
108
+ if (isExportLike(value)) {
109
+ paths[name] = constructFullExportCondition(value, packageType);
110
+ return;
111
+ }
112
+ Object.keys(value).forEach((subpath)=>{
113
+ const nextName = joinRelativePath(name, subpath);
114
+ const nestedValue = value[subpath];
115
+ findExport(nextName, nestedValue, paths, packageType);
116
+ });
117
+ }
118
+ /**
119
+ *
120
+ * Convert package.exports field to paths mapping
121
+ * Example
122
+ *
123
+ * Input:
124
+ * {
125
+ * ".": {
126
+ * "sub": {
127
+ * "import": "./sub.js",
128
+ * "require": "./sub.cjs",
129
+ * "types": "./sub.d.ts
130
+ * }
131
+ * }
132
+ * }
133
+ *
134
+ * Output:
135
+ * {
136
+ * "./sub": {
137
+ * "import": "./sub.js",
138
+ * "require": "./sub.cjs",
139
+ * "types": "./sub.d.ts,
140
+ * }
141
+ * }
142
+ *
143
+ */ function parseExport(exportsCondition, packageType) {
144
+ const paths = {};
145
+ if (typeof exportsCondition === 'string') {
146
+ paths['.'] = constructFullExportCondition(exportsCondition, packageType);
147
+ } else if (typeof exportsCondition === 'object') {
148
+ Object.keys(exportsCondition).forEach((key)=>{
149
+ const value = exportsCondition[key];
150
+ findExport(key, value, paths, packageType);
151
+ });
152
+ }
153
+ return paths;
154
+ }
155
+ /**
156
+ * Get package exports paths
157
+ *
158
+ * Example:
159
+ *
160
+ * ```json
161
+ * {
162
+ * "exports": {
163
+ * ".": {
164
+ * "require": "./dist/index.cjs",
165
+ * "module": "./dist/index.esm.js",
166
+ * "default": "./dist/index.esm.js"
167
+ * },
168
+ * "./foo": {
169
+ * "require": "./dist/foo.cjs",
170
+ * "module": "./dist/foo.esm.js",
171
+ * "default": "./dist/foo.esm.js"
172
+ * }
173
+ * }
174
+ *
175
+ * ```
176
+ *
177
+ * will be parsed to:
178
+ *
179
+ * ```js
180
+ * {
181
+ * '.': {
182
+ * main: './dist/index.cjs',
183
+ * module: './dist/index.esm.js',
184
+ * export: './dist/index.esm.js'
185
+ * },
186
+ * './foo': {
187
+ * main: './dist/foo.cjs',
188
+ * module: './dist/foo.esm.js',
189
+ * export: './dist/foo.esm.js'
190
+ * }
191
+ *
192
+ *
193
+ * pkg.main and pkg.module will be added to ['.'] if exists
194
+ */ function getExportPaths(pkg) {
195
+ const pathsMap = {};
196
+ const packageType = getPackageType(pkg);
197
+ const { exports: exportsConditions } = pkg;
198
+ if (exportsConditions) {
199
+ const paths = parseExport(exportsConditions, packageType);
200
+ Object.assign(pathsMap, paths);
201
+ }
202
+ // main export '.' from main/module/typings
203
+ const defaultMainExport = constructFullExportCondition({
204
+ [packageType === 'commonjs' ? 'require' : 'import']: pkg.main,
205
+ module: pkg.module,
206
+ types: getTypings(pkg)
207
+ }, packageType);
208
+ // Merge the main export into '.' paths
209
+ const mainExport = Object.assign({}, pathsMap['.'], defaultMainExport);
210
+ // main export is not empty
211
+ if (Object.keys(mainExport).length > 0) {
212
+ pathsMap['.'] = mainExport;
213
+ }
214
+ return pathsMap;
215
+ }
216
+ function getPackageType(pkg) {
217
+ return pkg.type || 'commonjs';
218
+ }
219
+ function constructDefaultExportCondition(value, packageType) {
220
+ const objValue = typeof value === 'string' ? {
221
+ [packageType === 'commonjs' ? 'require' : 'import']: value,
222
+ types: getTypings(value)
223
+ } : value;
224
+ return constructFullExportCondition(objValue, packageType);
225
+ }
226
+ function isEsmExportName(name) {
227
+ return [
228
+ 'import',
229
+ 'module',
230
+ 'react-native',
231
+ 'react-server',
232
+ 'edge-light'
233
+ ].includes(name);
234
+ }
235
+ function isCjsExportName(name) {
236
+ return [
237
+ 'require',
238
+ 'main',
239
+ 'node',
240
+ 'default'
241
+ ].includes(name);
242
+ }
243
+ function getExportConditionDist(pkg, parsedExportCondition, cwd) {
244
+ const dist = [];
245
+ const existed = new Set();
246
+ const exportTypes = Object.keys(parsedExportCondition.export);
247
+ for (const key of exportTypes){
248
+ if (key === 'types') {
249
+ continue;
250
+ }
251
+ const relativePath = parsedExportCondition.export[key];
252
+ const distFile = getDistPath(relativePath, cwd);
253
+ let format = 'esm';
254
+ if (isEsmExportName(key)) {
255
+ format = 'esm';
256
+ } else if (isCjsExportName(key)) {
257
+ format = 'cjs';
258
+ }
259
+ // Deduplicate the same path jobs
260
+ // TODO: detect conflicts paths but with different format
261
+ if (existed.has(distFile)) {
262
+ continue;
263
+ }
264
+ existed.add(distFile);
265
+ dist.push({
266
+ format,
267
+ file: distFile
268
+ });
269
+ }
270
+ if (dist.length === 0) {
271
+ // TODO: Deprecate this warning and behavior in v3
272
+ console.error(`Doesn't fin any exports in ${pkg.name}, using default dist path dist/index.js`);
273
+ dist.push({
274
+ format: 'esm',
275
+ file: getDistPath('dist/index.js', cwd)
276
+ });
277
+ }
278
+ return dist;
279
+ }
280
+
281
+ function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
13
282
  try {
14
283
  var info = gen[key](arg);
15
284
  var value = info.value;
@@ -23,16 +292,16 @@ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
23
292
  Promise.resolve(value).then(_next, _throw);
24
293
  }
25
294
  }
26
- function _async_to_generator$1(fn) {
295
+ function _async_to_generator$3(fn) {
27
296
  return function() {
28
297
  var self = this, args = arguments;
29
298
  return new Promise(function(resolve, reject) {
30
299
  var gen = fn.apply(self, args);
31
300
  function _next(value) {
32
- asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
301
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "next", value);
33
302
  }
34
303
  function _throw(err) {
35
- asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
304
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "throw", err);
36
305
  }
37
306
  _next(undefined);
38
307
  });
@@ -42,21 +311,11 @@ function exit(err) {
42
311
  logger.error(err);
43
312
  process.exit(1);
44
313
  }
45
- const formatDuration = (duration)=>duration >= 1000 ? `${duration / 1000}s` : `${duration}ms`;
46
- function hasPackageJson(cwd) {
47
- return _hasPackageJson.apply(this, arguments);
48
- }
49
- function _hasPackageJson() {
50
- _hasPackageJson = _async_to_generator$1(function*(cwd) {
51
- return yield fileExists(path__default.default.resolve(cwd, 'package.json'));
52
- });
53
- return _hasPackageJson.apply(this, arguments);
54
- }
55
314
  function getPackageMeta(cwd) {
56
315
  return _getPackageMeta.apply(this, arguments);
57
316
  }
58
317
  function _getPackageMeta() {
59
- _getPackageMeta = _async_to_generator$1(function*(cwd) {
318
+ _getPackageMeta = _async_to_generator$3(function*(cwd) {
60
319
  const pkgFilePath = path__default.default.resolve(cwd, 'package.json');
61
320
  let targetPackageJson = {};
62
321
  try {
@@ -83,7 +342,7 @@ function fileExists(filePath) {
83
342
  return _fileExists.apply(this, arguments);
84
343
  }
85
344
  function _fileExists() {
86
- _fileExists = _async_to_generator$1(function*(filePath) {
345
+ _fileExists = _async_to_generator$3(function*(filePath) {
87
346
  try {
88
347
  yield fs__default.default.access(filePath);
89
348
  return true;
@@ -96,8 +355,417 @@ function _fileExists() {
96
355
  });
97
356
  return _fileExists.apply(this, arguments);
98
357
  }
358
+ // . -> pkg name
359
+ // ./lite -> <pkg name>/lite
360
+ function getExportPath(pkg, cwd, exportName) {
361
+ const name = pkg.name || path__default.default.basename(cwd);
362
+ if (exportName === '.' || !exportName) return name;
363
+ return path__default.default.join(name, exportName);
364
+ }
365
+ const isNotNull = (n)=>Boolean(n);
366
+ const SRC = 'src' // resolve from src/ directory
367
+ ;
368
+ function resolveSourceFile(cwd, filename) {
369
+ return path__default.default.resolve(cwd, SRC, filename);
370
+ }
371
+ // Map '.' -> './index.[ext]'
372
+ // Map './lite' -> './lite.[ext]'
373
+ // Return undefined if no match or if it's package.json exports
374
+ function getSourcePathFromExportPath(cwd, exportPath) {
375
+ return _getSourcePathFromExportPath.apply(this, arguments);
376
+ }
377
+ function _getSourcePathFromExportPath() {
378
+ _getSourcePathFromExportPath = _async_to_generator$3(function*(cwd, exportPath) {
379
+ const exts = [
380
+ 'js',
381
+ 'cjs',
382
+ 'mjs',
383
+ 'jsx',
384
+ 'ts',
385
+ 'tsx'
386
+ ];
387
+ for (const ext of exts){
388
+ // ignore package.json
389
+ if (exportPath.endsWith('package.json')) return;
390
+ if (exportPath === '.') exportPath = './index';
391
+ const filename = resolveSourceFile(cwd, `${exportPath}.${ext}`);
392
+ if (yield fileExists(filename)) {
393
+ return filename;
394
+ }
395
+ }
396
+ return;
397
+ });
398
+ return _getSourcePathFromExportPath.apply(this, arguments);
399
+ }
400
+
401
+ function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
402
+ try {
403
+ var info = gen[key](arg);
404
+ var value = info.value;
405
+ } catch (error) {
406
+ reject(error);
407
+ return;
408
+ }
409
+ if (info.done) {
410
+ resolve(value);
411
+ } else {
412
+ Promise.resolve(value).then(_next, _throw);
413
+ }
414
+ }
415
+ function _async_to_generator$2(fn) {
416
+ return function() {
417
+ var self = this, args = arguments;
418
+ return new Promise(function(resolve, reject) {
419
+ var gen = fn.apply(self, args);
420
+ function _next(value) {
421
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
422
+ }
423
+ function _throw(err) {
424
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
425
+ }
426
+ _next(undefined);
427
+ });
428
+ };
429
+ }
430
+ function _extends$1() {
431
+ _extends$1 = Object.assign || function(target) {
432
+ for(var i = 1; i < arguments.length; i++){
433
+ var source = arguments[i];
434
+ for(var key in source){
435
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
436
+ target[key] = source[key];
437
+ }
438
+ }
439
+ }
440
+ return target;
441
+ };
442
+ return _extends$1.apply(this, arguments);
443
+ }
444
+ const minifyOptions = {
445
+ compress: true,
446
+ format: {
447
+ comments: 'some',
448
+ wrapFuncArgs: false,
449
+ preserveAnnotations: true
450
+ },
451
+ mangle: {
452
+ toplevel: true
453
+ }
454
+ };
455
+ // This can also be passed down as stats from top level
456
+ const sizeCollector = chunkSizeCollector();
457
+ function getBuildEnv(envs) {
458
+ if (!envs.includes('NODE_ENV')) {
459
+ envs.push('NODE_ENV');
460
+ }
461
+ const envVars = envs.reduce((acc, key)=>{
462
+ const value = process.env[key];
463
+ if (typeof value !== 'undefined') {
464
+ acc['process.env.' + key] = JSON.stringify(value);
465
+ }
466
+ return acc;
467
+ }, {});
468
+ return envVars;
469
+ }
470
+ function buildInputConfig(entry, pkg, options, cwd, { tsConfigPath , tsCompilerOptions }, dtsOnly) {
471
+ var _options_external;
472
+ const externals = options.noExternal ? [] : [
473
+ pkg.peerDependencies,
474
+ pkg.dependencies,
475
+ pkg.peerDependenciesMeta
476
+ ].filter((n)=>Boolean(n)).map((o)=>Object.keys(o)).reduce((a, b)=>a.concat(b), []).concat(((_options_external = options.external) != null ? _options_external : []).concat(pkg.name ? [
477
+ pkg.name
478
+ ] : []));
479
+ const { useTypescript , runtime , target: jscTarget , minify } = options;
480
+ const hasSpecifiedTsTarget = Boolean((tsCompilerOptions == null ? void 0 : tsCompilerOptions.target) && tsConfigPath);
481
+ const sizePlugin = sizeCollector.plugin(cwd);
482
+ const commonPlugins = [
483
+ shebang__default.default(),
484
+ sizePlugin
485
+ ];
486
+ const plugins = (dtsOnly ? [
487
+ ...commonPlugins,
488
+ useTypescript && require('rollup-plugin-dts').default({
489
+ compilerOptions: _extends$1({}, tsCompilerOptions, {
490
+ declaration: true,
491
+ noEmit: false,
492
+ noEmitOnError: true,
493
+ emitDeclarationOnly: true,
494
+ checkJs: false,
495
+ declarationMap: false,
496
+ skipLibCheck: true,
497
+ preserveSymlinks: false,
498
+ target: 'esnext',
499
+ module: 'esnext',
500
+ incremental: false,
501
+ jsx: tsCompilerOptions.jsx || 'react'
502
+ })
503
+ })
504
+ ] : [
505
+ ...commonPlugins,
506
+ replace__default.default({
507
+ values: getBuildEnv(options.env || []),
508
+ preventAssignment: true
509
+ }),
510
+ pluginNodeResolve.nodeResolve({
511
+ preferBuiltins: runtime === 'node',
512
+ extensions: [
513
+ '.mjs',
514
+ '.cjs',
515
+ '.js',
516
+ '.json',
517
+ '.node',
518
+ '.jsx'
519
+ ]
520
+ }),
521
+ commonjs__default.default({
522
+ include: /node_modules\//
523
+ }),
524
+ json__default.default(),
525
+ pluginWasm.wasm(),
526
+ rollupPluginSwc3.swc({
527
+ include: /\.(m|c)?[jt]sx?$/,
528
+ exclude: 'node_modules',
529
+ tsconfig: tsConfigPath,
530
+ jsc: _extends$1({}, !hasSpecifiedTsTarget && {
531
+ target: jscTarget
532
+ }, {
533
+ loose: true,
534
+ externalHelpers: false,
535
+ parser: {
536
+ syntax: useTypescript ? 'typescript' : 'ecmascript',
537
+ [useTypescript ? 'tsx' : 'jsx']: true,
538
+ privateMethod: true,
539
+ classPrivateProperty: true,
540
+ exportDefaultFrom: true
541
+ }
542
+ }, minify && {
543
+ minify: _extends$1({}, minifyOptions, {
544
+ sourceMap: options.sourcemap
545
+ })
546
+ }),
547
+ sourceMaps: options.sourcemap,
548
+ inlineSourcesContent: false
549
+ })
550
+ ]).filter(isNotNull);
551
+ return {
552
+ input: entry,
553
+ external (id) {
554
+ return externals.some((name)=>id === name || id.startsWith(name + '/'));
555
+ },
556
+ plugins,
557
+ treeshake: {
558
+ propertyReadSideEffects: false
559
+ },
560
+ onwarn (warning, warn) {
561
+ const code = warning.code || '';
562
+ // Some may not have types, like CLI binary
563
+ if (dtsOnly && code === 'EMPTY_BUNDLE') return;
564
+ if ([
565
+ 'MIXED_EXPORTS',
566
+ 'PREFER_NAMED_EXPORTS',
567
+ 'UNRESOLVED_IMPORT',
568
+ 'THIS_IS_UNDEFINED'
569
+ ].includes(code)) return;
570
+ // If the circular dependency warning is from node_modules, ignore it
571
+ if (code === 'CIRCULAR_DEPENDENCY' && /Circular dependency: node_modules/.test(warning.message)) {
572
+ return;
573
+ }
574
+ warn(warning);
575
+ }
576
+ };
577
+ }
578
+ function hasEsmExport(exportPaths, tsCompilerOptions) {
579
+ let hasEsm = false;
580
+ for(const key in exportPaths){
581
+ const exportInfo = exportPaths[key];
582
+ const exportNames = Object.keys(exportInfo);
583
+ if (exportNames.some((name)=>isEsmExportName(name))) {
584
+ hasEsm = true;
585
+ break;
586
+ }
587
+ }
588
+ return Boolean(hasEsm || (tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop));
589
+ }
590
+ function buildOutputConfigs(pkg, exportPaths, options, exportCondition, cwd, { tsCompilerOptions }, dtsOnly) {
591
+ const { format } = options;
592
+ // Add esm mark and interop helper if esm export is detected
593
+ const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions);
594
+ const typings = getTypings(pkg);
595
+ const file = options.file && path.resolve(cwd, options.file);
596
+ const dtsDir = typings ? path.dirname(path.resolve(cwd, typings)) : path.resolve(cwd, 'dist');
597
+ // file base name without extension
598
+ const name = file ? file.replace(new RegExp(`${path.extname(file)}$`), '') : undefined;
599
+ // TODO: simplify dts file name detection
600
+ const dtsFile = exportCondition.export['types'] ? path.resolve(cwd, exportCondition.export['types']) : 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);
601
+ // If there's dts file, use `output.file`
602
+ const dtsPathConfig = dtsFile ? {
603
+ file: dtsFile
604
+ } : {
605
+ dir: dtsDir
606
+ };
607
+ return _extends$1({
608
+ name: pkg.name || name
609
+ }, dtsOnly ? dtsPathConfig : {
610
+ file: file
611
+ }, {
612
+ format,
613
+ exports: 'named',
614
+ esModule: useEsModuleMark || 'if-default-prop',
615
+ interop: 'auto',
616
+ freeze: false,
617
+ strict: false,
618
+ sourcemap: options.sourcemap
619
+ });
620
+ }
621
+ // build configs for each entry from package exports
622
+ function buildEntryConfig(pkg, entryPath, exportPaths, bundleConfig, cwd, tsOptions, dtsOnly) {
623
+ return _buildEntryConfig.apply(this, arguments);
624
+ }
625
+ function _buildEntryConfig() {
626
+ _buildEntryConfig = _async_to_generator$2(function*(pkg, entryPath, exportPaths, bundleConfig, cwd, tsOptions, dtsOnly) {
627
+ const configs = Object.keys(exportPaths).map(/*#__PURE__*/ _async_to_generator$2(function*(entryExport) {
628
+ // TODO: improve the source detection
629
+ const source = (yield getSourcePathFromExportPath(cwd, entryExport)) || entryPath;
630
+ if (!source) return undefined;
631
+ const exportCondition = {
632
+ source,
633
+ name: entryExport,
634
+ export: exportPaths[entryExport]
635
+ };
636
+ const entry = resolveSourceFile(cwd, source);
637
+ const rollupConfig = buildConfig(entry, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, dtsOnly);
638
+ return rollupConfig;
639
+ }));
640
+ return (yield Promise.all(configs)).filter((n)=>Boolean(n));
641
+ });
642
+ return _buildEntryConfig.apply(this, arguments);
643
+ }
644
+ function buildConfig(entry, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, dtsOnly) {
645
+ const { file } = bundleConfig;
646
+ const useTypescript = Boolean(tsOptions.tsConfigPath);
647
+ const options = _extends$1({}, bundleConfig, {
648
+ useTypescript
649
+ });
650
+ const inputOptions = buildInputConfig(entry, pkg, options, cwd, tsOptions, dtsOnly);
651
+ const outputExports = getExportConditionDist(pkg, exportCondition, cwd);
652
+ let outputConfigs = [];
653
+ // Generate dts job - single config
654
+ if (dtsOnly) {
655
+ outputConfigs = [
656
+ buildOutputConfigs(pkg, exportPaths, _extends$1({}, bundleConfig, {
657
+ format: 'es',
658
+ useTypescript
659
+ }), exportCondition, cwd, tsOptions, dtsOnly)
660
+ ];
661
+ } else {
662
+ // multi outputs with specified format
663
+ outputConfigs = outputExports.map((exportDist)=>{
664
+ return buildOutputConfigs(pkg, exportPaths, _extends$1({}, bundleConfig, {
665
+ file: exportDist.file,
666
+ format: exportDist.format,
667
+ useTypescript
668
+ }), exportCondition, cwd, tsOptions, dtsOnly);
669
+ });
670
+ // CLI output option is always prioritized
671
+ if (file) {
672
+ var _outputExports_;
673
+ const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format;
674
+ outputConfigs = [
675
+ buildOutputConfigs(pkg, exportPaths, _extends$1({}, bundleConfig, {
676
+ file,
677
+ format: bundleConfig.format || fallbackFormat,
678
+ useTypescript
679
+ }), exportCondition, cwd, tsOptions, dtsOnly)
680
+ ];
681
+ }
682
+ }
683
+ return {
684
+ input: inputOptions,
685
+ output: outputConfigs,
686
+ exportName: exportCondition.name || '.'
687
+ };
688
+ }
689
+
690
+ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
691
+ try {
692
+ var info = gen[key](arg);
693
+ var value = info.value;
694
+ } catch (error) {
695
+ reject(error);
696
+ return;
697
+ }
698
+ if (info.done) {
699
+ resolve(value);
700
+ } else {
701
+ Promise.resolve(value).then(_next, _throw);
702
+ }
703
+ }
704
+ function _async_to_generator$1(fn) {
705
+ return function() {
706
+ var self = this, args = arguments;
707
+ return new Promise(function(resolve, reject) {
708
+ var gen = fn.apply(self, args);
709
+ function _next(value) {
710
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
711
+ }
712
+ function _throw(err) {
713
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
714
+ }
715
+ _next(undefined);
716
+ });
717
+ };
718
+ }
719
+ let hasLoggedTsWarning = false;
720
+ function resolveTypescript(cwd) {
721
+ let ts;
722
+ const m = new module$1.Module('', undefined);
723
+ m.paths = module$1.Module._nodeModulePaths(cwd);
724
+ try {
725
+ ts = m.require('typescript');
726
+ } catch (_) {
727
+ console.error(_);
728
+ if (!hasLoggedTsWarning) {
729
+ hasLoggedTsWarning = true;
730
+ exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency');
731
+ }
732
+ }
733
+ return ts;
734
+ }
735
+ function resolveTsConfig(cwd) {
736
+ return _resolveTsConfig.apply(this, arguments);
737
+ }
738
+ function _resolveTsConfig() {
739
+ _resolveTsConfig = _async_to_generator$1(function*(cwd) {
740
+ let tsCompilerOptions = {};
741
+ let tsConfigPath;
742
+ const ts = resolveTypescript(cwd);
743
+ tsConfigPath = path.resolve(cwd, 'tsconfig.json');
744
+ if (yield fileExists(tsConfigPath)) {
745
+ const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
746
+ const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
747
+ tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
748
+ } else {
749
+ tsConfigPath = undefined;
750
+ return null;
751
+ }
752
+ return {
753
+ tsCompilerOptions,
754
+ tsConfigPath
755
+ };
756
+ });
757
+ return _resolveTsConfig.apply(this, arguments);
758
+ }
99
759
 
100
- var version = "3.2.0";
760
+ function logSizeStats() {
761
+ const stats = sizeCollector.getSizeStats();
762
+ const maxLength = Math.max(...stats.map(([filename])=>filename.length));
763
+ stats.forEach(([filename, prettiedSize])=>{
764
+ const padding = ' '.repeat(maxLength - filename.length);
765
+ const action = filename.endsWith('.d.ts') ? 'Typed' : 'Built';
766
+ logger.log(` ✓ ${action} ${filename}${padding} - ${prettiedSize}`);
767
+ });
768
+ }
101
769
 
102
770
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
103
771
  try {
@@ -128,167 +796,159 @@ function _async_to_generator(fn) {
128
796
  });
129
797
  };
130
798
  }
131
- const helpMessage = `
132
- Usage: bunchee [options]
133
-
134
- Options:
135
- -v, --version output the version number
136
- -w, --watch watch src files changes
137
- -m, --minify compress output. default: false
138
- -o, --output <file> specify output filename
139
- -f, --format <format> type of output (esm, amd, cjs, iife, umd, system), default: esm
140
- -h, --help output usage information
141
- --external <mod> specify an external dependency, separate by comma
142
- --no-external do not bundle external dependencies
143
- --target <target> js features target: swc target es versions. default: es2016
144
- --runtime <runtime> build runtime (nodejs, browser). default: browser
145
- --env <env> inlined process env variables, separate by comma. default: NODE_ENV
146
- --cwd <cwd> specify current working directory
147
- --sourcemap enable sourcemap generation, default: false
148
- --dts determine if need to generate types, default: false
149
- `;
150
- function help() {
151
- logger.log(helpMessage);
152
- }
153
- function lintPackage(cwd) {
154
- return _lintPackage.apply(this, arguments);
155
- }
156
- function _lintPackage() {
157
- _lintPackage = _async_to_generator(function*(cwd) {
158
- // Not package.json detected, skip package linting
159
- if (!(yield hasPackageJson(cwd))) {
160
- return;
161
- }
162
- const { publint } = yield import('publint');
163
- const { printMessage } = yield import('publint/utils');
164
- const messages = yield publint({
165
- pkgDir: cwd,
166
- level: 'error'
167
- });
168
- const pkg = yield getPackageMeta(cwd);
169
- for (const message of messages){
170
- console.log(printMessage(message, pkg));
799
+ function _extends() {
800
+ _extends = Object.assign || function(target) {
801
+ for(var i = 1; i < arguments.length; i++){
802
+ var source = arguments[i];
803
+ for(var key in source){
804
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
805
+ target[key] = source[key];
806
+ }
807
+ }
171
808
  }
172
- });
173
- return _lintPackage.apply(this, arguments);
174
- }
175
- function parseCliArgs(argv) {
176
- let args;
177
- args = arg__default.default({
178
- '--cwd': String,
179
- '--dts': Boolean,
180
- '--output': String,
181
- '--format': String,
182
- '--watch': Boolean,
183
- '--minify': Boolean,
184
- '--help': Boolean,
185
- '--version': Boolean,
186
- '--runtime': String,
187
- '--target': String,
188
- '--sourcemap': Boolean,
189
- '--env': String,
190
- '--external': String,
191
- '--no-external': Boolean,
192
- '-h': '--help',
193
- '-v': '--version',
194
- '-w': '--watch',
195
- '-o': '--output',
196
- '-f': '--format',
197
- '-m': '--minify'
198
- }, {
199
- permissive: true,
200
- argv
201
- });
202
- const source = args._[0];
203
- const parsedArgs = {
204
- source,
205
- format: args['--format'],
206
- file: args['--output'],
207
- watch: args['--watch'],
208
- minify: args['--minify'],
209
- sourcemap: !!args['--sourcemap'],
210
- cwd: args['--cwd'],
211
- dts: args['--dts'],
212
- help: args['--help'],
213
- version: args['--version'],
214
- runtime: args['--runtime'],
215
- target: args['--target'],
216
- external: !!args['--no-external'] ? null : args['--external'],
217
- env: args['--env']
809
+ return target;
218
810
  };
219
- return parsedArgs;
220
- }
221
- function run(args) {
222
- return _run.apply(this, arguments);
223
- }
224
- function _run() {
225
- _run = _async_to_generator(function*(args) {
226
- var _args_external;
227
- const { source , format , watch , minify , sourcemap , target , runtime , dts , env } = args;
228
- const cwd = args.cwd || process.cwd();
229
- const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
230
- const bundleConfig = {
231
- dts,
232
- file,
233
- format,
234
- cwd,
235
- target,
236
- runtime,
237
- external: ((_args_external = args.external) == null ? void 0 : _args_external.split(',')) || [],
238
- watch: !!watch,
239
- minify: !!minify,
240
- sourcemap: sourcemap === false ? false : true,
241
- env: (env == null ? void 0 : env.split(',')) || []
811
+ return _extends.apply(this, arguments);
812
+ }
813
+ function _object_without_properties_loose(source, excluded) {
814
+ if (source == null) return {};
815
+ var target = {};
816
+ var sourceKeys = Object.keys(source);
817
+ var key, i;
818
+ for(i = 0; i < sourceKeys.length; i++){
819
+ key = sourceKeys[i];
820
+ if (excluded.indexOf(key) >= 0) continue;
821
+ target[key] = source[key];
822
+ }
823
+ return target;
824
+ }
825
+ function assignDefault(options, name, defaultValue) {
826
+ if (!(name in options) || options[name] == null) {
827
+ options[name] = defaultValue;
828
+ }
829
+ }
830
+ function hasMultiEntryExport(exportPaths) {
831
+ const exportKeys = Object.keys(exportPaths).filter((key)=>key !== './package.json');
832
+ return exportKeys.length > 0 && exportKeys.every((name)=>name.startsWith('.'));
833
+ }
834
+ function bundle(entryPath) {
835
+ return _bundle.apply(this, arguments);
836
+ }
837
+ function _bundle() {
838
+ _bundle = _async_to_generator(function*(entryPath, _param = {}) {
839
+ var { cwd: _cwd } = _param, options = _object_without_properties_loose(_param, [
840
+ "cwd"
841
+ ]);
842
+ const cwd = path.resolve(process.cwd(), _cwd || '');
843
+ assignDefault(options, 'format', 'es');
844
+ assignDefault(options, 'minify', false);
845
+ assignDefault(options, 'target', 'es2015');
846
+ const pkg = yield getPackageMeta(cwd);
847
+ const packageType = getPackageType(pkg);
848
+ const exportPaths = getExportPaths(pkg);
849
+ const exportKeys = Object.keys(exportPaths).filter((key)=>key !== './package.json');
850
+ // const exportPathsLength = Object.keys(exportPaths).length
851
+ const isMultiEntries = hasMultiEntryExport(exportPaths) // exportPathsLength > 1
852
+ ;
853
+ const tsConfig = yield resolveTsConfig(cwd);
854
+ const hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
855
+ const defaultTsOptions = {
856
+ tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
857
+ tsCompilerOptions: (tsConfig == null ? void 0 : tsConfig.tsCompilerOptions) || {}
242
858
  };
243
- if (args.version) {
244
- return logger.log(version);
859
+ // Handle single entry file
860
+ if (!isMultiEntries) {
861
+ // Use specified string file path if possible, then fallback to the default behavior entry picking logic
862
+ // e.g. "exports": "./dist/index.js" -> use "./index.<ext>" as entry
863
+ entryPath = entryPath || (yield getSourcePathFromExportPath(cwd, '.')) || '';
245
864
  }
246
- if (args.help) {
247
- return help();
865
+ if (exportKeys.length === 0 && entryPath) {
866
+ exportPaths['.'] = constructDefaultExportCondition(entryPath, packageType);
248
867
  }
249
- const entry = source ? path__default.default.resolve(cwd, source) : '';
250
- const bundle = require('./index').bundle;
251
- let timeStart = Date.now();
252
- let timeEnd;
253
- try {
254
- yield bundle(entry, bundleConfig);
255
- timeEnd = Date.now();
256
- } catch (err) {
257
- if (err.name === 'NOT_EXISTED') {
258
- help();
259
- return exit(err);
868
+ const bundleOrWatch = (rollupConfig)=>{
869
+ const { input , exportName } = rollupConfig;
870
+ const exportPath = getExportPath(pkg, cwd, exportName);
871
+ // Log original entry file relative path
872
+ const source = typeof input.input === 'string' ? path.relative(cwd, input.input) : exportPath;
873
+ const buildMetadata = {
874
+ source
875
+ };
876
+ if (options.watch) {
877
+ return Promise.resolve(runWatch(rollupConfig, buildMetadata));
260
878
  }
261
- throw err;
879
+ return runBundle(rollupConfig);
880
+ };
881
+ const hasSpecifiedEntryFile = entryPath ? (yield fileExists(entryPath)) && (yield fs__default.default.stat(entryPath)).isFile() : false;
882
+ if (!hasSpecifiedEntryFile && !isMultiEntries) {
883
+ const err = new Error(`Entry file \`${entryPath}\` is not existed`);
884
+ err.name = 'NOT_EXISTED';
885
+ return Promise.reject(err);
262
886
  }
263
- const duration = timeEnd - timeStart;
264
- // watching mode
265
- if (watch) {
266
- logger.log(`🔍 Watching assets in ${cwd}...`);
267
- return;
887
+ // has `types` field in package.json or has `types` exports in any export condition for multi-entries
888
+ const hasTypings = Object.values(exportPaths).some((condition)=>condition.hasOwnProperty('types'));
889
+ // Enable types generation if it's types field specified in package.json
890
+ if (hasTypings) {
891
+ options.dts = hasTypings;
268
892
  }
269
- // build mode
270
- logger.log(`✨ Finished in ${formatDuration(duration)}`);
271
- yield lintPackage(cwd);
893
+ let result;
894
+ const buildConfigs = yield buildEntryConfig(pkg, entryPath, exportPaths, options, cwd, defaultTsOptions, false);
895
+ const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
896
+ const typesJobs = hasTsConfig && options.dts ? (yield buildEntryConfig(pkg, entryPath, exportPaths, options, cwd, defaultTsOptions, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
897
+ result = yield Promise.all(assetsJobs.concat(typesJobs));
898
+ logSizeStats();
899
+ return result;
272
900
  });
273
- return _run.apply(this, arguments);
274
- }
275
- function main() {
276
- return _main.apply(this, arguments);
901
+ return _bundle.apply(this, arguments);
277
902
  }
278
- function _main() {
279
- _main = _async_to_generator(function*() {
280
- let params, error;
281
- try {
282
- params = parseCliArgs(process.argv.slice(2));
283
- } catch (err) {
284
- error = err;
285
- }
286
- if (error || !params) {
287
- if (!error) help();
288
- return exit(error);
903
+ function runWatch({ input , output }, metadata) {
904
+ const watchOptions = [
905
+ _extends({}, input, {
906
+ output: output,
907
+ watch: {
908
+ exclude: [
909
+ 'node_modules/**'
910
+ ]
911
+ }
912
+ })
913
+ ];
914
+ const watcher = rollup.watch(watchOptions);
915
+ watcher.on('event', (event)=>{
916
+ switch(event.code){
917
+ case 'ERROR':
918
+ {
919
+ return onError(event.error);
920
+ }
921
+ case 'START':
922
+ {
923
+ logger.log(`Start building ${metadata.source} ...`);
924
+ break;
925
+ }
926
+ case 'END':
927
+ {
928
+ break;
929
+ }
930
+ default:
931
+ return;
289
932
  }
290
- yield run(params);
291
933
  });
292
- return _main.apply(this, arguments);
934
+ return watcher;
935
+ }
936
+ function runBundle({ input , output }) {
937
+ return rollup.rollup(input).then((bundle)=>{
938
+ const writeJobs = output.map((options)=>bundle.write(options));
939
+ return Promise.all(writeJobs);
940
+ }, onError);
293
941
  }
294
- main().catch(exit);
942
+ function onError(error) {
943
+ if (!error) return;
944
+ // logging source code in format
945
+ if (error.frame) {
946
+ process.stderr.write(error.frame + '\n');
947
+ }
948
+ // filter out the rollup plugin error information such as loc/frame/code...
949
+ const err = new Error(error.message);
950
+ err.stack = error.stack;
951
+ throw err;
952
+ }
953
+
954
+ exports.bundle = bundle;