bunchee 5.0.0-beta.4 → 5.0.0-beta.6

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/bin/cli.js CHANGED
@@ -456,7 +456,7 @@ function lint$1(pkg) {
456
456
  }
457
457
  }
458
458
 
459
- var version = "5.0.0-beta.4";
459
+ var version = "5.0.0-beta.6";
460
460
 
461
461
  function relativify(path) {
462
462
  return path.startsWith('.') ? path : `./${path}`;
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
2
 
3
- var rollup = require('rollup');
4
3
  var fsp = require('fs/promises');
5
4
  var fs = require('fs');
6
5
  var path = require('path');
@@ -19,6 +18,7 @@ var MagicString = require('magic-string');
19
18
  var CleanCSS = require('clean-css');
20
19
  var pluginutils = require('@rollup/pluginutils');
21
20
  var prettyBytes = require('pretty-bytes');
21
+ var rollup = require('rollup');
22
22
 
23
23
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
24
24
 
@@ -187,18 +187,6 @@ function isTypescriptFile(filename) {
187
187
  function fileExists(filePath) {
188
188
  return fs__default.default.existsSync(filePath);
189
189
  }
190
- async function removeDir(dirPath) {
191
- try {
192
- const dirStat = await fsp__default.default.stat(dirPath);
193
- if (dirStat.isDirectory()) {
194
- await rimraf.rimraf(dirPath);
195
- }
196
- } catch (err) {
197
- if (err.code !== 'ENOENT') {
198
- throw err;
199
- }
200
- }
201
- }
202
190
  const isNotNull = (n)=>Boolean(n);
203
191
  function resolveSourceFile(cwd, filename) {
204
192
  return path__default.default.resolve(cwd, SRC, filename);
@@ -261,10 +249,10 @@ const getMainFieldExportType = (pkg)=>{
261
249
  // TODO: add unit test
262
250
  const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
263
251
  const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
264
- const memoize = (fn, resolver)=>{
252
+ const memoize = (fn, cacheKey)=>{
265
253
  const cache = new Map();
266
254
  return (...args)=>{
267
- const key = resolver ? resolver(...args) : JSON.stringify({
255
+ const key = cacheKey ? typeof cacheKey === 'function' ? cacheKey(...args) : cacheKey : JSON.stringify({
268
256
  args
269
257
  });
270
258
  const existing = cache.get(key);
@@ -276,6 +264,7 @@ const memoize = (fn, resolver)=>{
276
264
  return result;
277
265
  };
278
266
  };
267
+ const memoizeByKey = (fn)=>(cacheKey)=>memoize(fn, cacheKey);
279
268
  function joinRelativePath(...segments) {
280
269
  let result = path__default.default.join(...segments);
281
270
  // If the first segment starts with '.', ensure the result does too.
@@ -287,9 +276,29 @@ function joinRelativePath(...segments) {
287
276
  function isESModulePackage(packageType) {
288
277
  return packageType === 'module';
289
278
  }
279
+ async function removeDir(dirPath) {
280
+ try {
281
+ const dirStat = await fsp__default.default.stat(dirPath);
282
+ if (dirStat.isDirectory()) {
283
+ await rimraf.rimraf(dirPath);
284
+ }
285
+ } catch (err) {
286
+ if (err.code !== 'ENOENT') {
287
+ throw err;
288
+ }
289
+ }
290
+ }
291
+ const removedDirs = new Set();
292
+ async function removeOutputDir(output, cwd) {
293
+ const dir = output.dir;
294
+ if (dir && dir !== cwd && !removedDirs.has(dir)) {
295
+ await removeDir(dir);
296
+ removedDirs.add(dir);
297
+ }
298
+ }
290
299
 
291
300
  let hasLoggedTsWarning = false;
292
- function resolveTypescriptHandler(cwd) {
301
+ function resolveTypescript(cwd) {
293
302
  let ts;
294
303
  const m = new module$1.Module('', undefined);
295
304
  m.paths = module$1.Module._nodeModulePaths(cwd);
@@ -304,12 +313,12 @@ function resolveTypescriptHandler(cwd) {
304
313
  }
305
314
  return ts;
306
315
  }
307
- const resolveTypescript = memoize(resolveTypescriptHandler);
308
316
  function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
309
317
  let tsCompilerOptions = {};
310
318
  let tsConfigPath;
311
319
  tsConfigPath = path.resolve(cwd, tsconfig);
312
320
  if (fileExists(tsConfigPath)) {
321
+ // Use the original ts handler to avoid memory leak
313
322
  const ts = resolveTypescript(cwd);
314
323
  const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
315
324
  const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
@@ -324,6 +333,7 @@ function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
324
333
  }
325
334
  const resolveTsConfig = memoize(resolveTsConfigHandler);
326
335
  async function convertCompilerOptions(cwd, json) {
336
+ // Use the original ts handler to avoid memory leak
327
337
  const ts = resolveTypescript(cwd);
328
338
  return ts.convertCompilerOptionsFromJson(json, './');
329
339
  }
@@ -1042,6 +1052,44 @@ const swcMinifyOptions = {
1042
1052
  toplevel: true
1043
1053
  }
1044
1054
  };
1055
+ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, cwd) {
1056
+ const enableIncrementalWithoutBuildInfo = tsCompilerOptions.incremental && !tsCompilerOptions.tsBuildInfoFile;
1057
+ const incrementalOptions = enableIncrementalWithoutBuildInfo ? {
1058
+ incremental: false
1059
+ } : undefined;
1060
+ const compositeOptions = tsCompilerOptions.composite ? {
1061
+ composite: false
1062
+ } : undefined;
1063
+ const { options: overrideResolvedTsOptions } = await convertCompilerOptions(cwd, {
1064
+ declaration: true,
1065
+ noEmit: false,
1066
+ noEmitOnError: true,
1067
+ emitDeclarationOnly: true,
1068
+ checkJs: false,
1069
+ declarationMap: false,
1070
+ skipLibCheck: true,
1071
+ // preserveSymlinks should always be set to false to avoid issues with
1072
+ // resolving types from <reference> from node_modules
1073
+ preserveSymlinks: false,
1074
+ target: 'ESNext',
1075
+ ...!tsCompilerOptions.jsx ? {
1076
+ jsx: 'react-jsx'
1077
+ } : undefined,
1078
+ // error TS5074: Option '--incremental' can only be specified using tsconfig, emitting to single
1079
+ // file or when option '--tsBuildInfoFile' is specified.
1080
+ ...incrementalOptions,
1081
+ // error TS6379: Composite projects may not disable incremental compilation.
1082
+ ...compositeOptions
1083
+ });
1084
+ const dtsPlugin = require('rollup-plugin-dts').default({
1085
+ tsconfig: tsConfigPath,
1086
+ compilerOptions: overrideResolvedTsOptions
1087
+ });
1088
+ return dtsPlugin;
1089
+ }
1090
+ // Avoid create multiple dts plugins instance and parsing the same tsconfig multi times,
1091
+ // This will avoid memory leak and performance issue.
1092
+ const memoizeDtsPluginByKey = memoizeByKey(createDtsPlugin);
1045
1093
  /**
1046
1094
  * return {
1047
1095
  * <absolute source path>: <pkg>/<export>
@@ -1125,38 +1173,11 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1125
1173
  })
1126
1174
  ];
1127
1175
  if (useTypeScript) {
1128
- const enableIncrementalWithoutBuildInfo = tsCompilerOptions.incremental && !tsCompilerOptions.tsBuildInfoFile;
1129
- const incrementalOptions = enableIncrementalWithoutBuildInfo ? {
1130
- incremental: false
1131
- } : undefined;
1132
- const compositeOptions = tsCompilerOptions.composite ? {
1133
- composite: false
1134
- } : undefined;
1135
- const { options: overrideResolvedTsOptions } = await convertCompilerOptions(cwd, {
1136
- declaration: true,
1137
- noEmit: false,
1138
- noEmitOnError: true,
1139
- emitDeclarationOnly: true,
1140
- checkJs: false,
1141
- declarationMap: false,
1142
- skipLibCheck: true,
1143
- // preserveSymlinks should always be set to false to avoid issues with
1144
- // resolving types from <reference> from node_modules
1145
- preserveSymlinks: false,
1146
- target: 'ESNext',
1147
- ...!tsCompilerOptions.jsx ? {
1148
- jsx: 'react-jsx'
1149
- } : undefined,
1150
- // error TS5074: Option '--incremental' can only be specified using tsconfig, emitting to single
1151
- // file or when option '--tsBuildInfoFile' is specified.
1152
- ...incrementalOptions,
1153
- // error TS6379: Composite projects may not disable incremental compilation.
1154
- ...compositeOptions
1155
- });
1156
- const dtsPlugin = require('rollup-plugin-dts').default({
1157
- tsconfig: tsConfigPath,
1158
- compilerOptions: overrideResolvedTsOptions
1159
- });
1176
+ // Each process should be unique
1177
+ // Each package build should be unique
1178
+ // Composing above factors into a unique cache key to retrieve the memoized dts plugin with tsconfigs
1179
+ const uniqueProcessId = 'dts-plugin:' + process.pid + (buildContext.pkg.name || '');
1180
+ const dtsPlugin = await memoizeDtsPluginByKey(uniqueProcessId)(tsCompilerOptions, tsConfigPath, cwd);
1160
1181
  typesPlugins.push(dtsPlugin);
1161
1182
  }
1162
1183
  const plugins = (dts ? typesPlugins : [
@@ -1472,6 +1493,9 @@ function createOutputState({ entries }) {
1472
1493
  if (chunk.type !== 'chunk') {
1473
1494
  return;
1474
1495
  }
1496
+ if (!chunk.isEntry) {
1497
+ return;
1498
+ }
1475
1499
  const size = chunk.code.length;
1476
1500
  const sourceFileName = chunk.facadeModuleId || '';
1477
1501
  const exportPath = removeScope(reversedMapping.get(sourceFileName) || '.');
@@ -1552,6 +1576,53 @@ function logOutputState(sizeCollector) {
1552
1576
  });
1553
1577
  }
1554
1578
 
1579
+ async function createAssetRollupJobs(options, buildContext, { isFromCli, generateTypes }) {
1580
+ const assetsConfigs = await buildEntryConfig(options, buildContext, false);
1581
+ const typesConfigs = generateTypes ? await buildEntryConfig(options, buildContext, true) : [];
1582
+ const allConfigs = assetsConfigs.concat(typesConfigs);
1583
+ for (const config of allConfigs){
1584
+ if (options.clean && !isFromCli) {
1585
+ await removeOutputDir(config.output, buildContext.cwd);
1586
+ }
1587
+ }
1588
+ const rollupJobs = allConfigs.map((rollupConfig)=>bundleOrWatch(options, rollupConfig));
1589
+ return await Promise.all(rollupJobs);
1590
+ }
1591
+ async function bundleOrWatch(options, rollupConfig) {
1592
+ if (options.watch) {
1593
+ return runWatch(rollupConfig);
1594
+ }
1595
+ return runBundle(rollupConfig);
1596
+ }
1597
+ function runBundle({ input, output }) {
1598
+ return rollup.rollup(input).then((bundle)=>{
1599
+ return bundle.write(output);
1600
+ }, catchErrorHandler);
1601
+ }
1602
+ function runWatch({ input, output }) {
1603
+ const watchOptions = [
1604
+ {
1605
+ ...input,
1606
+ output: output,
1607
+ watch: {
1608
+ exclude: [
1609
+ 'node_modules/**'
1610
+ ]
1611
+ }
1612
+ }
1613
+ ];
1614
+ const watcher = rollup.watch(watchOptions);
1615
+ return watcher;
1616
+ }
1617
+ function catchErrorHandler(error) {
1618
+ if (!error) return;
1619
+ logger.error(error);
1620
+ // filter out the rollup plugin error information such as loc/frame/code...
1621
+ const err = new Error(error.message);
1622
+ err.stack = error.stack;
1623
+ throw err;
1624
+ }
1625
+
1555
1626
  function assignDefault(options, name, defaultValue) {
1556
1627
  if (!(name in options) || options[name] == null) {
1557
1628
  options[name] = defaultValue;
@@ -1609,17 +1680,6 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1609
1680
  ].filter(Boolean));
1610
1681
  }
1611
1682
  }
1612
- const bundleOrWatch = async (rollupConfig)=>{
1613
- if (options.clean) {
1614
- if (!isFromCli) {
1615
- await removeOutputDir(rollupConfig.output, cwd);
1616
- }
1617
- }
1618
- if (options.watch) {
1619
- return runWatch(rollupConfig);
1620
- }
1621
- return runBundle(rollupConfig);
1622
- };
1623
1683
  const hasSpecifiedEntryFile = cliEntryPath ? fs__default.default.existsSync(cliEntryPath) && (await fsp__default.default.stat(cliEntryPath)).isFile() : false;
1624
1684
  const hasNoEntry = !hasSpecifiedEntryFile && !isMultiEntries && !hasBin;
1625
1685
  if (hasNoEntry) {
@@ -1663,34 +1723,21 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1663
1723
  entriesAlias
1664
1724
  }
1665
1725
  };
1666
- const assetsJobs = (await buildEntryConfig(options, buildContext, false)).map((rollupConfig)=>bundleOrWatch(rollupConfig));
1667
- const typesJobs = hasTsConfig && options.dts !== false ? (await buildEntryConfig(options, buildContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
1668
- const totalJobs = assetsJobs.concat(typesJobs);
1669
- const result = await Promise.all(totalJobs);
1670
- if (result.length === 0) {
1726
+ const generateTypes = hasTsConfig && options.dts !== false;
1727
+ const rollupJobsOptions = {
1728
+ isFromCli,
1729
+ generateTypes
1730
+ };
1731
+ const assetJobs = await createAssetRollupJobs(options, buildContext, rollupJobsOptions);
1732
+ if (assetJobs.length === 0) {
1671
1733
  logger.warn('The "src" directory does not contain any entry files. ' + 'For proper usage, please refer to the following link: ' + 'https://github.com/huozhi/bunchee#usage');
1672
1734
  }
1673
- if (!options.watch) {
1674
- logOutputState(sizeCollector);
1735
+ if (options.watch) {
1736
+ logWatcherBuildTime(assetJobs);
1675
1737
  } else {
1676
- logWatcherBuildTime(result);
1738
+ logOutputState(sizeCollector);
1677
1739
  }
1678
- return result;
1679
- }
1680
- function runWatch({ input, output }) {
1681
- const watchOptions = [
1682
- {
1683
- ...input,
1684
- output: output,
1685
- watch: {
1686
- exclude: [
1687
- 'node_modules/**'
1688
- ]
1689
- }
1690
- }
1691
- ];
1692
- const watcher = rollup.watch(watchOptions);
1693
- return watcher;
1740
+ return;
1694
1741
  }
1695
1742
  function logWatcherBuildTime(result) {
1696
1743
  let watcherCounter = 0;
@@ -1727,15 +1774,6 @@ function logWatcherBuildTime(result) {
1727
1774
  });
1728
1775
  });
1729
1776
  }
1730
- async function removeOutputDir(output, cwd) {
1731
- const dir = output.dir;
1732
- if (dir && dir !== cwd) await removeDir(dir);
1733
- }
1734
- function runBundle({ input, output }) {
1735
- return rollup.rollup(input).then((bundle)=>{
1736
- return bundle.write(output);
1737
- }, catchErrorHandler);
1738
- }
1739
1777
  function logError(error) {
1740
1778
  if (!error) return;
1741
1779
  // logging source code in format
@@ -1743,13 +1781,5 @@ function logError(error) {
1743
1781
  process.stderr.write(error.frame + '\n');
1744
1782
  }
1745
1783
  }
1746
- function catchErrorHandler(error) {
1747
- if (!error) return;
1748
- logError(error);
1749
- // filter out the rollup plugin error information such as loc/frame/code...
1750
- const err = new Error(error.message);
1751
- err.stack = error.stack;
1752
- throw err;
1753
- }
1754
1784
 
1755
1785
  exports.bundle = bundle;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "5.0.0-beta.4",
3
+ "version": "5.0.0-beta.6",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",
@@ -12,7 +12,8 @@
12
12
  "clean": "rm -rf ./dist",
13
13
  "typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
14
14
  "prepublishOnly": "pnpm clean && pnpm build && chmod +x ./dist/bin/cli.js && pnpm test",
15
- "build": "tsx ./src/bin/index.ts --runtime node",
15
+ "tsx": "node -r @swc-node/register",
16
+ "build": "node -r @swc-node/register ./src/bin/index.ts --runtime node",
16
17
  "format": "prettier --write .",
17
18
  "prepare": "husky install"
18
19
  },
@@ -53,14 +54,14 @@
53
54
  "@rollup/plugin-replace": "^5.0.5",
54
55
  "@rollup/plugin-wasm": "^6.2.2",
55
56
  "@rollup/pluginutils": "^5.1.0",
56
- "@swc/core": "^1.3.106",
57
- "@swc/helpers": "^0.5.3",
57
+ "@swc/core": "^1.4.8",
58
+ "@swc/helpers": "^0.5.6",
58
59
  "arg": "^5.0.2",
59
60
  "clean-css": "^5.3.3",
60
- "magic-string": "^0.30.6",
61
+ "magic-string": "^0.30.8",
61
62
  "pretty-bytes": "^5.6.0",
62
63
  "rimraf": "^5.0.5",
63
- "rollup": "^4.12.0",
64
+ "rollup": "^4.13.0",
64
65
  "rollup-plugin-dts": "^6.1.0",
65
66
  "rollup-plugin-swc3": "^0.11.0",
66
67
  "rollup-preserve-directives": "^1.1.1",
@@ -79,6 +80,7 @@
79
80
  },
80
81
  "devDependencies": {
81
82
  "@huozhi/testing-package": "1.0.0",
83
+ "@swc-node/register": "^1.9.0",
82
84
  "@swc/jest": "^0.2.31",
83
85
  "@swc/types": "^0.1.5",
84
86
  "@types/clean-css": "^4.2.11",
@@ -91,7 +93,6 @@
91
93
  "picocolors": "^1.0.0",
92
94
  "prettier": "^3.0.0",
93
95
  "react": "^18.2.0",
94
- "tsx": "^4.6.2",
95
96
  "typescript": "^5.3.2"
96
97
  },
97
98
  "lint-staged": {