bunchee 3.0.1 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,9 +39,9 @@ You can use the `exports` field to support different conditions and leverage the
39
39
  ```json
40
40
  {
41
41
  "exports": {
42
- "require": "dist/index.cjs",
42
+ "module": "dist/index.esm.js",
43
43
  "import": "dist/index.mjs",
44
- "module": "dist/index.esm.js"
44
+ "require": "dist/index.cjs"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "bunchee"
@@ -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
@@ -3,6 +3,12 @@ var path = require('path');
3
3
  var arg = require('arg');
4
4
  var fs = require('fs/promises');
5
5
 
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var path__default = /*#__PURE__*/_interopDefault(path);
9
+ var arg__default = /*#__PURE__*/_interopDefault(arg);
10
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
11
+
6
12
  function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
7
13
  try {
8
14
  var info = gen[key](arg);
@@ -37,15 +43,24 @@ function exit(err) {
37
43
  process.exit(1);
38
44
  }
39
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
+ }
40
55
  function getPackageMeta(cwd) {
41
56
  return _getPackageMeta.apply(this, arguments);
42
57
  }
43
58
  function _getPackageMeta() {
44
59
  _getPackageMeta = _async_to_generator$1(function*(cwd) {
45
- const pkgFilePath = path.resolve(cwd, 'package.json');
60
+ const pkgFilePath = path__default.default.resolve(cwd, 'package.json');
46
61
  let targetPackageJson = {};
47
62
  try {
48
- targetPackageJson = JSON.parse((yield fs.readFile(pkgFilePath, {
63
+ targetPackageJson = JSON.parse((yield fs__default.default.readFile(pkgFilePath, {
49
64
  encoding: 'utf-8'
50
65
  })));
51
66
  } catch (_) {}
@@ -64,8 +79,25 @@ const logger = {
64
79
  console.error('\x1b[31m' + arg + '\x1b[0m');
65
80
  }
66
81
  };
82
+ function fileExists(filePath) {
83
+ return _fileExists.apply(this, arguments);
84
+ }
85
+ function _fileExists() {
86
+ _fileExists = _async_to_generator$1(function*(filePath) {
87
+ try {
88
+ yield fs__default.default.access(filePath);
89
+ return true;
90
+ } catch (err) {
91
+ if (err.code === 'ENOENT') {
92
+ return false;
93
+ }
94
+ throw err;
95
+ }
96
+ });
97
+ return _fileExists.apply(this, arguments);
98
+ }
67
99
 
68
- var version = "3.0.1";
100
+ var version = "3.1.1";
69
101
 
70
102
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
71
103
  try {
@@ -123,6 +155,10 @@ function lintPackage(cwd) {
123
155
  }
124
156
  function _lintPackage() {
125
157
  _lintPackage = _async_to_generator(function*(cwd) {
158
+ // Not package.json detected, skip package linting
159
+ if (!(yield hasPackageJson(cwd))) {
160
+ return;
161
+ }
126
162
  const { publint } = yield import('publint');
127
163
  const { printMessage } = yield import('publint/utils');
128
164
  const messages = yield publint({
@@ -138,7 +174,7 @@ function _lintPackage() {
138
174
  }
139
175
  function parseCliArgs(argv) {
140
176
  let args;
141
- args = arg({
177
+ args = arg__default.default({
142
178
  '--cwd': String,
143
179
  '--dts': Boolean,
144
180
  '--output': String,
@@ -190,7 +226,7 @@ function _run() {
190
226
  var _args_external;
191
227
  const { source , format , watch , minify , sourcemap , target , runtime , dts , env } = args;
192
228
  const cwd = args.cwd || process.cwd();
193
- const file = args.file ? path.resolve(cwd, args.file) : undefined;
229
+ const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
194
230
  const bundleConfig = {
195
231
  dts,
196
232
  file,
@@ -210,7 +246,7 @@ function _run() {
210
246
  if (args.help) {
211
247
  return help();
212
248
  }
213
- const entry = source ? path.resolve(cwd, source) : '';
249
+ const entry = source ? path__default.default.resolve(cwd, source) : '';
214
250
  const bundle = require('./index').bundle;
215
251
  let timeStart = Date.now();
216
252
  let timeEnd;
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,67 @@ 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 _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
+
17
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
18
+ var path__default = /*#__PURE__*/_interopDefault(path);
19
+ var commonjs__default = /*#__PURE__*/_interopDefault(commonjs);
20
+ var shebang__default = /*#__PURE__*/_interopDefault(shebang);
21
+ var json__default = /*#__PURE__*/_interopDefault(json);
22
+ var replace__default = /*#__PURE__*/_interopDefault(replace);
23
+ var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes);
24
+
25
+ function chunkSizeCollector() {
26
+ const sizes = new Map();
27
+ function addSize(name, size) {
28
+ sizes.set(name, size);
29
+ }
30
+ return {
31
+ plugin: (cwd)=>{
32
+ return {
33
+ name: 'collect-sizes',
34
+ augmentChunkHash () {
35
+ // Do nothing, but use the hook to keep the plugin instance alive
36
+ },
37
+ renderChunk (code, chunk, options) {
38
+ const dir = options.dir || options.file && path__default.default.dirname(options.file);
39
+ let fileName = chunk.fileName;
40
+ if (dir) {
41
+ fileName = path__default.default.relative(cwd, path__default.default.join(dir, fileName));
42
+ }
43
+ addSize(fileName, code.length);
44
+ return null;
45
+ }
46
+ };
47
+ },
48
+ getSizeStats () {
49
+ const sizeStats = [];
50
+ sizes.forEach((size, name)=>{
51
+ sizeStats.push([
52
+ name,
53
+ prettyBytes__default.default(size),
54
+ size
55
+ ]);
56
+ });
57
+ return sizeStats;
58
+ }
59
+ };
60
+ }
19
61
 
20
62
  function getTypings(pkg) {
21
63
  return pkg.types || pkg.typings;
22
64
  }
23
- function getDistPath(distPath) {
24
- return path.resolve(config.rootDir, distPath);
65
+ function getDistPath(distPath, cwd) {
66
+ return path.resolve(cwd, distPath);
25
67
  }
26
68
  function findExport(field) {
27
69
  if (!field) return;
@@ -40,7 +82,46 @@ function parseExport(exportsCondition) {
40
82
  }
41
83
  return paths;
42
84
  }
43
- function getExportPaths(pkg) {
85
+ /**
86
+ * Get package exports paths
87
+ *
88
+ * Example:
89
+ *
90
+ * ```json
91
+ * {
92
+ * "exports": {
93
+ * ".": {
94
+ * "require": "./dist/index.cjs",
95
+ * "module": "./dist/index.esm.js",
96
+ * "default": "./dist/index.esm.js"
97
+ * },
98
+ * "./foo": {
99
+ * "require": "./dist/foo.cjs",
100
+ * "module": "./dist/foo.esm.js",
101
+ * "default": "./dist/foo.esm.js"
102
+ * }
103
+ * }
104
+ *
105
+ * ```
106
+ *
107
+ * will be parsed to:
108
+ *
109
+ * ```js
110
+ * {
111
+ * '.': {
112
+ * main: './dist/index.cjs',
113
+ * module: './dist/index.esm.js',
114
+ * export: './dist/index.esm.js'
115
+ * },
116
+ * './foo': {
117
+ * main: './dist/foo.cjs',
118
+ * module: './dist/foo.esm.js',
119
+ * export: './dist/foo.esm.js'
120
+ * }
121
+ *
122
+ *
123
+ * pkg.main and pkg.module will be added to ['.'] if exists
124
+ */ function getExportPaths(pkg) {
44
125
  const pathsMap = {};
45
126
  const mainExport = {};
46
127
  if (pkg.main) {
@@ -68,67 +149,64 @@ function getExportPaths(pkg) {
68
149
  pathsMap['.'] = mainExport;
69
150
  return pathsMap;
70
151
  }
71
- function getExportDist(pkg) {
152
+ function getExportDist(pkg, cwd) {
72
153
  const paths = getExportPaths(pkg)['.'];
73
154
  const dist = [];
74
155
  if (paths.main) {
75
156
  dist.push({
76
157
  format: 'cjs',
77
- file: getDistPath(paths.main)
158
+ file: getDistPath(paths.main, cwd)
78
159
  });
79
160
  }
80
161
  if (paths.module) {
81
162
  dist.push({
82
163
  format: 'esm',
83
- file: getDistPath(paths.module)
164
+ file: getDistPath(paths.module, cwd)
84
165
  });
85
166
  }
86
167
  if (paths.export) {
87
168
  dist.push({
88
169
  format: 'esm',
89
- file: getDistPath(paths.export)
170
+ file: getDistPath(paths.export, cwd)
90
171
  });
91
172
  }
92
173
  // default fallback to output `dist/index.js` in default esm format
93
174
  if (dist.length === 0) {
94
175
  dist.push({
95
176
  format: 'esm',
96
- file: getDistPath('dist/index.js')
177
+ file: getDistPath('dist/index.js', cwd)
97
178
  });
98
179
  }
99
180
  return dist;
100
181
  }
101
- function getExportConditionDist(pkg, exportCondition) {
102
- // const pkgExports = pkg.exports || {}
182
+ function getExportConditionDist(pkg, exportCondition, cwd) {
103
183
  const dist = [];
104
184
  // "exports": "..."
105
185
  if (typeof exportCondition === 'string') {
106
186
  dist.push({
107
187
  format: pkg.type === 'module' ? 'esm' : 'cjs',
108
- file: getDistPath(exportCondition)
188
+ file: getDistPath(exportCondition, cwd)
109
189
  });
110
190
  } else {
111
191
  // "./<subexport>": { }
112
- const subExports = exportCondition // pkgExports[subExport]
113
- ;
192
+ const subExports = exportCondition;
114
193
  // Ignore json exports, like "./package.json"
115
- // if (subExport.endsWith('.json')) return dist
116
194
  if (typeof subExports === 'string') {
117
195
  dist.push({
118
196
  format: 'esm',
119
- file: getDistPath(subExports)
197
+ file: getDistPath(subExports, cwd)
120
198
  });
121
199
  } else {
122
200
  if (subExports.require) {
123
201
  dist.push({
124
202
  format: 'cjs',
125
- file: getDistPath(subExports.require)
203
+ file: getDistPath(subExports.require, cwd)
126
204
  });
127
205
  }
128
206
  if (subExports.import) {
129
207
  dist.push({
130
208
  format: 'esm',
131
- file: getDistPath(subExports.import)
209
+ file: getDistPath(subExports.import, cwd)
132
210
  });
133
211
  }
134
212
  }
@@ -136,7 +214,7 @@ function getExportConditionDist(pkg, exportCondition) {
136
214
  return dist;
137
215
  }
138
216
 
139
- function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
217
+ function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
140
218
  try {
141
219
  var info = gen[key](arg);
142
220
  var value = info.value;
@@ -150,16 +228,16 @@ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
150
228
  Promise.resolve(value).then(_next, _throw);
151
229
  }
152
230
  }
153
- function _async_to_generator$1(fn) {
231
+ function _async_to_generator$3(fn) {
154
232
  return function() {
155
233
  var self = this, args = arguments;
156
234
  return new Promise(function(resolve, reject) {
157
235
  var gen = fn.apply(self, args);
158
236
  function _next(value) {
159
- asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
237
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "next", value);
160
238
  }
161
239
  function _throw(err) {
162
- asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
240
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "throw", err);
163
241
  }
164
242
  _next(undefined);
165
243
  });
@@ -169,16 +247,15 @@ function exit(err) {
169
247
  logger.error(err);
170
248
  process.exit(1);
171
249
  }
172
- const formatDuration = (duration)=>duration >= 1000 ? `${duration / 1000}s` : `${duration}ms`;
173
250
  function getPackageMeta(cwd) {
174
251
  return _getPackageMeta.apply(this, arguments);
175
252
  }
176
253
  function _getPackageMeta() {
177
- _getPackageMeta = _async_to_generator$1(function*(cwd) {
178
- const pkgFilePath = path.resolve(cwd, 'package.json');
254
+ _getPackageMeta = _async_to_generator$3(function*(cwd) {
255
+ const pkgFilePath = path__default.default.resolve(cwd, 'package.json');
179
256
  let targetPackageJson = {};
180
257
  try {
181
- targetPackageJson = JSON.parse((yield fs.readFile(pkgFilePath, {
258
+ targetPackageJson = JSON.parse((yield fs__default.default.readFile(pkgFilePath, {
182
259
  encoding: 'utf-8'
183
260
  })));
184
261
  } catch (_) {}
@@ -197,17 +274,13 @@ const logger = {
197
274
  console.error('\x1b[31m' + arg + '\x1b[0m');
198
275
  }
199
276
  };
200
- function isTypescript(filename) {
201
- const ext = path.extname(filename);
202
- return ext === '.ts' || ext === '.tsx';
203
- }
204
277
  function fileExists(filePath) {
205
278
  return _fileExists.apply(this, arguments);
206
279
  }
207
280
  function _fileExists() {
208
- _fileExists = _async_to_generator$1(function*(filePath) {
281
+ _fileExists = _async_to_generator$3(function*(filePath) {
209
282
  try {
210
- yield fs.access(filePath);
283
+ yield fs__default.default.access(filePath);
211
284
  return true;
212
285
  } catch (err) {
213
286
  if (err.code === 'ENOENT') {
@@ -218,8 +291,78 @@ function _fileExists() {
218
291
  });
219
292
  return _fileExists.apply(this, arguments);
220
293
  }
294
+ // . -> pkg name
295
+ // ./lite -> <pkg name>/lite
296
+ function getExportPath(pkg, cwd, exportName) {
297
+ const name = pkg.name || path__default.default.basename(cwd);
298
+ if (exportName === '.' || !exportName) return name;
299
+ return path__default.default.join(name, exportName);
300
+ }
221
301
  const isNotNull = (n)=>Boolean(n);
302
+ const SRC = 'src' // resolve from src/ directory
303
+ ;
304
+ function resolveSourceFile(cwd, filename) {
305
+ return path__default.default.resolve(cwd, SRC, filename);
306
+ }
307
+ // Map '.' -> './index.[ext]'
308
+ // Map './lite' -> './lite.[ext]'
309
+ // Return undefined if no match or if it's package.json exports
310
+ function getSourcePathFromExportPath(cwd, exportPath) {
311
+ return _getSourcePathFromExportPath.apply(this, arguments);
312
+ }
313
+ function _getSourcePathFromExportPath() {
314
+ _getSourcePathFromExportPath = _async_to_generator$3(function*(cwd, exportPath) {
315
+ const exts = [
316
+ 'js',
317
+ 'cjs',
318
+ 'mjs',
319
+ 'jsx',
320
+ 'ts',
321
+ 'tsx'
322
+ ];
323
+ for (const ext of exts){
324
+ // ignore package.json
325
+ if (exportPath.endsWith('package.json')) return;
326
+ if (exportPath === '.') exportPath = './index';
327
+ const filename = resolveSourceFile(cwd, `${exportPath}.${ext}`);
328
+ if (yield fileExists(filename)) {
329
+ return filename;
330
+ }
331
+ }
332
+ return;
333
+ });
334
+ return _getSourcePathFromExportPath.apply(this, arguments);
335
+ }
222
336
 
337
+ function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
338
+ try {
339
+ var info = gen[key](arg);
340
+ var value = info.value;
341
+ } catch (error) {
342
+ reject(error);
343
+ return;
344
+ }
345
+ if (info.done) {
346
+ resolve(value);
347
+ } else {
348
+ Promise.resolve(value).then(_next, _throw);
349
+ }
350
+ }
351
+ function _async_to_generator$2(fn) {
352
+ return function() {
353
+ var self = this, args = arguments;
354
+ return new Promise(function(resolve, reject) {
355
+ var gen = fn.apply(self, args);
356
+ function _next(value) {
357
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
358
+ }
359
+ function _throw(err) {
360
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
361
+ }
362
+ _next(undefined);
363
+ });
364
+ };
365
+ }
223
366
  function _extends$1() {
224
367
  _extends$1 = Object.assign || function(target) {
225
368
  for(var i = 1; i < arguments.length; i++){
@@ -245,22 +388,8 @@ const minifyOptions = {
245
388
  toplevel: true
246
389
  }
247
390
  };
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
- }
391
+ // This can also be passed down as stats from top level
392
+ const sizeCollector = chunkSizeCollector();
264
393
  function getBuildEnv(envs) {
265
394
  if (!envs.includes('NODE_ENV')) {
266
395
  envs.push('NODE_ENV');
@@ -274,7 +403,7 @@ function getBuildEnv(envs) {
274
403
  }, {});
275
404
  return envVars;
276
405
  }
277
- function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOptions , dtsOnly }) {
406
+ function buildInputConfig(entry, pkg, options, cwd, { tsConfigPath , tsCompilerOptions }, dtsOnly) {
278
407
  var _options_external;
279
408
  const externals = options.noExternal ? [] : [
280
409
  pkg.peerDependencies,
@@ -285,8 +414,13 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
285
414
  ] : []));
286
415
  const { useTypescript , runtime , target: jscTarget , minify } = options;
287
416
  const hasSpecifiedTsTarget = Boolean((tsCompilerOptions == null ? void 0 : tsCompilerOptions.target) && tsConfigPath);
417
+ const sizePlugin = sizeCollector.plugin(cwd);
418
+ const commonPlugins = [
419
+ shebang__default.default(),
420
+ sizePlugin
421
+ ];
288
422
  const plugins = (dtsOnly ? [
289
- shebang(),
423
+ ...commonPlugins,
290
424
  useTypescript && require('rollup-plugin-dts').default({
291
425
  compilerOptions: _extends$1({}, tsCompilerOptions, {
292
426
  declaration: true,
@@ -304,7 +438,8 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
304
438
  })
305
439
  })
306
440
  ] : [
307
- replace({
441
+ ...commonPlugins,
442
+ replace__default.default({
308
443
  values: getBuildEnv(options.env || []),
309
444
  preventAssignment: true
310
445
  }),
@@ -318,11 +453,10 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
318
453
  '.jsx'
319
454
  ]
320
455
  }),
321
- commonjs({
456
+ commonjs__default.default({
322
457
  include: /node_modules\//
323
458
  }),
324
- json(),
325
- shebang(),
459
+ json__default.default(),
326
460
  rollupPluginSwc3.swc({
327
461
  include: /\.(m|c)?[jt]sx?$/,
328
462
  exclude: 'node_modules',
@@ -375,20 +509,28 @@ function buildInputConfig(entry, pkg, options, { tsConfigPath , tsCompilerOption
375
509
  }
376
510
  };
377
511
  }
378
- function buildOutputConfigs(options, pkg, { tsCompilerOptions , dtsOnly }) {
512
+ function hasEsmExport(exportPaths, tsCompilerOptions) {
513
+ let hasEsm = false;
514
+ for(const key in exportPaths){
515
+ const exportInfo = exportPaths[key];
516
+ if (exportInfo.import || exportInfo.module) {
517
+ hasEsm = true;
518
+ break;
519
+ }
520
+ }
521
+ return Boolean(hasEsm || (tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop));
522
+ }
523
+ function buildOutputConfigs(pkg, options, cwd, { tsCompilerOptions }, dtsOnly) {
379
524
  const { format , exportCondition } = options;
380
525
  const exportPaths = getExportPaths(pkg);
381
- // respect if tsconfig.json has `esModuleInterop` config;
382
- // add ESModule mark if cjs and ESModule are both generated;
383
- // TODO: support `import` in exportCondition
384
- const mainExport = exportPaths['.'];
385
- const useEsModuleMark = Boolean(tsCompilerOptions.esModuleInterop || mainExport.main && mainExport.module);
526
+ // Add esm mark and interop helper if esm export is detected
527
+ const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions);
386
528
  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');
529
+ const file = options.file && path.resolve(cwd, options.file);
530
+ const dtsDir = typings ? path.dirname(path.resolve(cwd, typings)) : path.resolve(cwd, 'dist');
389
531
  // file base name without extension
390
532
  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);
533
+ 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
534
  // If there's dts file, use `output.file`
393
535
  const dtsPathConfig = dtsFile ? {
394
536
  file: dtsFile
@@ -402,79 +544,164 @@ function buildOutputConfigs(options, pkg, { tsCompilerOptions , dtsOnly }) {
402
544
  }, {
403
545
  format,
404
546
  exports: 'named',
405
- esModule: useEsModuleMark,
547
+ esModule: useEsModuleMark || 'if-default-prop',
548
+ interop: 'auto',
406
549
  freeze: false,
407
550
  strict: false,
408
551
  sourcemap: options.sourcemap
409
552
  });
410
553
  }
411
- function buildConfig(entry, pkg, bundleConfig, dtsOnly) {
554
+ // build configs for each entry from package exports
555
+ function buildEntryConfig(pkg, bundleConfig, cwd, tsOptions, dtsOnly) {
556
+ return _buildEntryConfig.apply(this, arguments);
557
+ }
558
+ function _buildEntryConfig() {
559
+ _buildEntryConfig = _async_to_generator$2(function*(pkg, bundleConfig, cwd, tsOptions, dtsOnly) {
560
+ const packageExports = pkg.exports || {};
561
+ const configs = Object.keys(packageExports).map(/*#__PURE__*/ _async_to_generator$2(function*(entryExport) {
562
+ const source = yield getSourcePathFromExportPath(cwd, entryExport);
563
+ if (!source) return undefined;
564
+ if (dtsOnly && !(tsOptions == null ? void 0 : tsOptions.tsConfigPath)) return;
565
+ bundleConfig.exportCondition = {
566
+ source,
567
+ name: entryExport,
568
+ export: packageExports[entryExport]
569
+ };
570
+ const entry = resolveSourceFile(cwd, source);
571
+ const rollupConfig = buildConfig(entry, pkg, bundleConfig, cwd, tsOptions, dtsOnly);
572
+ return rollupConfig;
573
+ }));
574
+ return (yield Promise.all(configs)).filter((n)=>Boolean(n));
575
+ });
576
+ return _buildEntryConfig.apply(this, arguments);
577
+ }
578
+ function buildConfig(entry, pkg, bundleConfig, cwd, tsOptions, dtsOnly) {
412
579
  var _options_exportCondition;
413
580
  const { file } = bundleConfig;
414
- const useTypescript = isTypescript(entry);
581
+ const useTypescript = Boolean(tsOptions.tsConfigPath);
415
582
  const options = _extends$1({}, bundleConfig, {
416
583
  useTypescript
417
584
  });
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);
585
+ const inputOptions = buildInputConfig(entry, pkg, options, cwd, tsOptions, dtsOnly);
586
+ const outputExports = options.exportCondition ? getExportConditionDist(pkg, options.exportCondition.export, cwd) : getExportDist(pkg, cwd);
439
587
  let outputConfigs = [];
440
588
  // Generate dts job - single config
441
589
  if (dtsOnly) {
442
590
  outputConfigs = [
443
- buildOutputConfigs(_extends$1({}, bundleConfig, {
591
+ buildOutputConfigs(pkg, _extends$1({}, bundleConfig, {
444
592
  format: 'es',
445
593
  useTypescript
446
- }), pkg, typescriptOptions)
594
+ }), cwd, tsOptions, dtsOnly)
447
595
  ];
448
596
  } else {
449
597
  // multi outputs with specified format
450
598
  outputConfigs = outputExports.map((exportDist)=>{
451
- return buildOutputConfigs(_extends$1({}, bundleConfig, {
599
+ return buildOutputConfigs(pkg, _extends$1({}, bundleConfig, {
452
600
  file: exportDist.file,
453
601
  format: exportDist.format,
454
602
  useTypescript
455
- }), pkg, typescriptOptions);
603
+ }), cwd, tsOptions, dtsOnly);
456
604
  });
457
605
  // CLI output option is always prioritized
458
606
  if (file) {
459
607
  var _outputExports_;
460
608
  const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format;
461
609
  outputConfigs = [
462
- buildOutputConfigs(_extends$1({}, bundleConfig, {
610
+ buildOutputConfigs(pkg, _extends$1({}, bundleConfig, {
463
611
  file,
464
612
  format: bundleConfig.format || fallbackFormat,
465
613
  useTypescript
466
- }), pkg, typescriptOptions)
614
+ }), cwd, tsOptions, dtsOnly)
467
615
  ];
468
616
  }
469
617
  }
470
618
  return {
471
619
  input: inputOptions,
472
620
  output: outputConfigs,
473
- exportName: ((_options_exportCondition = options.exportCondition) == null ? void 0 : _options_exportCondition.name) || '.',
474
- dtsOnly
621
+ exportName: ((_options_exportCondition = options.exportCondition) == null ? void 0 : _options_exportCondition.name) || '.'
475
622
  };
476
623
  }
477
624
 
625
+ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
626
+ try {
627
+ var info = gen[key](arg);
628
+ var value = info.value;
629
+ } catch (error) {
630
+ reject(error);
631
+ return;
632
+ }
633
+ if (info.done) {
634
+ resolve(value);
635
+ } else {
636
+ Promise.resolve(value).then(_next, _throw);
637
+ }
638
+ }
639
+ function _async_to_generator$1(fn) {
640
+ return function() {
641
+ var self = this, args = arguments;
642
+ return new Promise(function(resolve, reject) {
643
+ var gen = fn.apply(self, args);
644
+ function _next(value) {
645
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
646
+ }
647
+ function _throw(err) {
648
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
649
+ }
650
+ _next(undefined);
651
+ });
652
+ };
653
+ }
654
+ let hasLoggedTsWarning = false;
655
+ function resolveTypescript(cwd) {
656
+ let ts;
657
+ const m = new module$1.Module('', undefined);
658
+ m.paths = module$1.Module._nodeModulePaths(cwd);
659
+ try {
660
+ ts = m.require('typescript');
661
+ } catch (_) {
662
+ console.error(_);
663
+ if (!hasLoggedTsWarning) {
664
+ hasLoggedTsWarning = true;
665
+ exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency');
666
+ }
667
+ }
668
+ return ts;
669
+ }
670
+ function resolveTsConfig(cwd) {
671
+ return _resolveTsConfig.apply(this, arguments);
672
+ }
673
+ function _resolveTsConfig() {
674
+ _resolveTsConfig = _async_to_generator$1(function*(cwd) {
675
+ let tsCompilerOptions = {};
676
+ let tsConfigPath;
677
+ const ts = resolveTypescript(cwd);
678
+ tsConfigPath = path.resolve(cwd, 'tsconfig.json');
679
+ if (yield fileExists(tsConfigPath)) {
680
+ const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
681
+ const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
682
+ tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
683
+ } else {
684
+ tsConfigPath = undefined;
685
+ return null;
686
+ }
687
+ return {
688
+ tsCompilerOptions,
689
+ tsConfigPath
690
+ };
691
+ });
692
+ return _resolveTsConfig.apply(this, arguments);
693
+ }
694
+
695
+ function logSizeStats() {
696
+ const stats = sizeCollector.getSizeStats();
697
+ const maxLength = Math.max(...stats.map(([filename])=>filename.length));
698
+ stats.forEach(([filename, prettiedSize])=>{
699
+ const padding = ' '.repeat(maxLength - filename.length);
700
+ const action = filename.endsWith('.d.ts') ? 'Typed' : 'Built';
701
+ logger.log(` ✓ ${action} ${filename}${padding} - ${prettiedSize}`);
702
+ });
703
+ }
704
+
478
705
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
479
706
  try {
480
707
  var info = gen[key](arg);
@@ -530,48 +757,11 @@ function _object_without_properties_loose(source, excluded) {
530
757
  }
531
758
  return target;
532
759
  }
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
760
  function assignDefault(options, name, defaultValue) {
539
761
  if (!(name in options) || options[name] == null) {
540
762
  options[name] = defaultValue;
541
763
  }
542
764
  }
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
765
  function hasMultiEntryExport(pkg) {
576
766
  const packageExportsField = pkg.exports || {};
577
767
  if (typeof packageExportsField === 'string') return false;
@@ -583,58 +773,42 @@ function bundle(entryPath) {
583
773
  }
584
774
  function _bundle() {
585
775
  _bundle = _async_to_generator(function*(entryPath, _param = {}) {
586
- var { cwd } = _param, options = _object_without_properties_loose(_param, [
776
+ var { cwd: _cwd } = _param, options = _object_without_properties_loose(_param, [
587
777
  "cwd"
588
778
  ]);
589
- config.rootDir = path.resolve(process.cwd(), cwd || '');
779
+ const cwd = path.resolve(process.cwd(), _cwd || '');
590
780
  assignDefault(options, 'format', 'es');
591
781
  assignDefault(options, 'minify', false);
592
782
  assignDefault(options, 'target', 'es2015');
593
- const pkg = yield getPackageMeta(config.rootDir);
783
+ const pkg = yield getPackageMeta(cwd);
594
784
  const packageExportsField = pkg.exports || {};
595
785
  const isMultiEntries = hasMultiEntryExport(pkg);
786
+ const tsConfig = yield resolveTsConfig(cwd);
787
+ const hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
788
+ const defaultTsOptions = {
789
+ tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
790
+ tsCompilerOptions: (tsConfig == null ? void 0 : tsConfig.tsCompilerOptions) || {}
791
+ };
596
792
  // Handle single entry file
597
793
  if (!isMultiEntries) {
598
794
  // Use specified string file path if possible, then fallback to the default behavior entry picking logic
599
795
  // 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);
796
+ entryPath = entryPath || (yield getSourcePathFromExportPath(cwd, '.')) || '';
623
797
  }
624
798
  const bundleOrWatch = (rollupConfig)=>{
625
799
  const { input , exportName } = rollupConfig;
626
- const exportPath = getExportPath(pkg, exportName);
800
+ const exportPath = getExportPath(pkg, cwd, exportName);
627
801
  // Log original entry file relative path
628
- const source = typeof input.input === 'string' ? path.relative(config.rootDir, input.input) : exportPath;
802
+ const source = typeof input.input === 'string' ? path.relative(cwd, input.input) : exportPath;
629
803
  const buildMetadata = {
630
804
  source
631
805
  };
632
806
  if (options.watch) {
633
807
  return Promise.resolve(runWatch(rollupConfig, buildMetadata));
634
808
  }
635
- return runBundle(rollupConfig, buildMetadata);
809
+ return runBundle(rollupConfig);
636
810
  };
637
- const hasSpecifiedEntryFile = entryPath ? (yield fileExists(entryPath)) && (yield fs.stat(entryPath)).isFile() : false;
811
+ const hasSpecifiedEntryFile = entryPath ? (yield fileExists(entryPath)) && (yield fs__default.default.stat(entryPath)).isFile() : false;
638
812
  if (!hasSpecifiedEntryFile && !isMultiEntries) {
639
813
  const err = new Error(`Entry file \`${entryPath}\` is not existed`);
640
814
  err.name = 'NOT_EXISTED';
@@ -646,30 +820,26 @@ function _bundle() {
646
820
  if (hasTypings) {
647
821
  options.dts = hasTypings;
648
822
  }
823
+ let result;
649
824
  if (isMultiEntries) {
650
- const pkgExports = packageExportsField;
651
- const buildConfigs = yield buildEntryConfig(pkgExports, false);
825
+ const buildConfigs = yield buildEntryConfig(pkg, options, cwd, defaultTsOptions, false);
652
826
  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));
827
+ const typesJobs = options.dts ? (yield buildEntryConfig(pkg, options, cwd, defaultTsOptions, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
828
+ result = yield Promise.all(assetsJobs.concat(typesJobs));
829
+ } else {
830
+ // Generate types
831
+ if (hasTsConfig && options.dts) {
832
+ yield bundleOrWatch(buildConfig(entryPath, pkg, options, cwd, defaultTsOptions, true));
833
+ }
834
+ const rollupConfig = buildConfig(entryPath, pkg, options, cwd, defaultTsOptions, false);
835
+ result = yield bundleOrWatch(rollupConfig);
659
836
  }
660
- const rollupConfig = buildConfig(entryPath, pkg, options, false);
661
- return bundleOrWatch(rollupConfig);
837
+ logSizeStats();
838
+ return result;
662
839
  });
663
840
  return _bundle.apply(this, arguments);
664
841
  }
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) {
842
+ function runWatch({ input , output }, metadata) {
673
843
  const watchOptions = [
674
844
  _extends({}, input, {
675
845
  output: output,
@@ -681,7 +851,6 @@ function runWatch({ input , output , dtsOnly }, metadata) {
681
851
  })
682
852
  ];
683
853
  const watcher = rollup.watch(watchOptions);
684
- let startTime = Date.now();
685
854
  watcher.on('event', (event)=>{
686
855
  switch(event.code){
687
856
  case 'ERROR':
@@ -690,14 +859,11 @@ function runWatch({ input , output , dtsOnly }, metadata) {
690
859
  }
691
860
  case 'START':
692
861
  {
693
- startTime = Date.now();
694
862
  logger.log(`Start building ${metadata.source} ...`);
695
863
  break;
696
864
  }
697
865
  case 'END':
698
866
  {
699
- const duration = Date.now() - startTime;
700
- logBuild(metadata.source, dtsOnly, duration);
701
867
  break;
702
868
  }
703
869
  default:
@@ -706,15 +872,11 @@ function runWatch({ input , output , dtsOnly }, metadata) {
706
872
  });
707
873
  return watcher;
708
874
  }
709
- function runBundle({ input , output , dtsOnly }, jobOptions) {
710
- const startTime = Date.now();
875
+ function runBundle({ input , output }) {
711
876
  return rollup.rollup(input).then((bundle)=>{
712
877
  const writeJobs = output.map((options)=>bundle.write(options));
713
878
  return Promise.all(writeJobs);
714
- }, onError).then(()=>{
715
- const duration = Date.now() - startTime;
716
- logBuild(jobOptions.source, dtsOnly, duration);
717
- });
879
+ }, onError);
718
880
  }
719
881
  function onError(error) {
720
882
  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.1",
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",