bunchee 5.0.0-beta.2 → 5.0.0-beta.4

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
@@ -14,7 +14,7 @@
14
14
  </a>
15
15
  </p>
16
16
 
17
- Bunchee makes bundling your library into one file effortless, with zero configuration required. It is built on top of Rollup and SWC ⚡️, allowing you to focus on writing code and generating multiple module types (CommonJS, ESModules) simultaneously.
17
+ **bunchee** is a zero configuration bundler makes bundling JS/tS library effortless. It's built on top of Rollup and SWC ⚡️, allowing you to focus on writing code and generating multiple bundles (CommonJS or ESModule) at the same time.
18
18
  It uses the standard exports configuration in `package.json` as the only source of truth, and uses entry file conventions to match your exports and build them into bundles.
19
19
 
20
20
  ## Quick Start
@@ -252,6 +252,63 @@ Then when the library is integrated to an app such as Next.js, app bundler can t
252
252
  If you're using `"use client"` or `"use server"` in entry file, then it will be preserved on top and the dist file of that entry will become a client component.
253
253
  If you're using `"use client"` or `"use server"` in a file that used as a dependency for an entry, then that file containing directives be split into a separate chunk and hoist the directives to the top of the chunk.
254
254
 
255
+ ### Shared Modules
256
+
257
+ There're always cases that you need to share code among bundles but they don't have to be a separate entry or exports. You want to have them bundled into a shared chunk and then use them in different bundles. You can use shared module convention `[name].[layer]-runtime.[ext]` to create shared modules bundles.
258
+
259
+ <details>
260
+ <summary>Shared Utils Example</summary>
261
+
262
+ ```js
263
+ // src/util.shared-runtime.js
264
+ export function sharedUtil() {
265
+ /* ... */
266
+ }
267
+ ```
268
+
269
+ Then you can use them in different entry files:
270
+
271
+ ```js
272
+ // src/index.js
273
+ import { sharedUtil } from './util.shared-runtime'
274
+ ```
275
+
276
+ ```js
277
+ // src/lite.js
278
+ import { sharedUtil } from './util.shared-runtime'
279
+ ```
280
+
281
+ `bunchee` will bundle the shared module into a separate **layer** which matches the file name convention, in the above case it's "shared", and that bundle will be referenced by the different entry bundles.
282
+
283
+ </details>
284
+
285
+ With multiple runtime bundles, such as having `default` and `react-server` together. They could have the modules that need to be shared and kept as only one instance among different runtime bundles. You can use the shared module convention to create shared modules bundles for different runtime bundles.
286
+
287
+ <details>
288
+ <summary>Shared Runtime Module Example</summary>
289
+
290
+ ```js
291
+ 'use client'
292
+ // src/app-context.shared-runtime.js
293
+ export const AppContext = React.createContext(null)
294
+ ```
295
+
296
+ Then you can use them in different entry files:
297
+
298
+ ```js
299
+ // src/index.js
300
+ import { AppContext } from './app-context.shared-runtime'
301
+ ```
302
+
303
+ ```js
304
+ // src/index.react-server.js
305
+ import { AppContext } from './app-context.shared-runtime'
306
+ ```
307
+
308
+ `app-context.shared-runtime` will be bundled into a separate chunk that only has one instance and be shared among different runtime bundles.
309
+
310
+ </details>
311
+
255
312
  ### CLI
256
313
 
257
314
  #### CLI Options
@@ -269,6 +326,7 @@ If you're using `"use client"` or `"use server"` in a file that used as a depend
269
326
  - Minify (`-m`): Compress output.
270
327
  - Watch (`-w`): Watch for source file changes.
271
328
  - No Clean(`--no-clean`): Do not clean the dist folder before building. (default: `false`)
329
+ - TSConfig (`--tsconfig <path>`): Specify the path to the TypeScript configuration file. (default: `tsconfig.json`)
272
330
 
273
331
  ```sh
274
332
  cd <project-root-dir>
@@ -401,6 +459,7 @@ await bundle(path.resolve('./src/index.ts'), {
401
459
  runtime: 'nodejs', // 'browser' | 'nodejs'
402
460
  cwd: process.cwd(), // string
403
461
  clean: true, // boolean
462
+ tsconfig: 'tsconfig.json', // string
404
463
  })
405
464
  ```
406
465
 
package/dist/bin/cli.js CHANGED
@@ -350,8 +350,7 @@ function lint$1(pkg) {
350
350
  if (hasCjsExtension(exports)) {
351
351
  state.badMainExport = true;
352
352
  }
353
- }
354
- if (typeof exports !== 'object') {
353
+ } else if (typeof exports !== 'object') {
355
354
  state.invalidExportsFieldType = true;
356
355
  } else {
357
356
  parsedExports.forEach((outputPairs)=>{
@@ -389,8 +388,7 @@ function lint$1(pkg) {
389
388
  if (path__default.default.extname(exports) === '.mjs') {
390
389
  state.badMainExport = true;
391
390
  }
392
- }
393
- if (typeof exports !== 'object') {
391
+ } else if (typeof exports !== 'object') {
394
392
  state.invalidExportsFieldType = true;
395
393
  } else {
396
394
  parsedExports.forEach((outputPairs)=>{
@@ -458,7 +456,7 @@ function lint$1(pkg) {
458
456
  }
459
457
  }
460
458
 
461
- var version = "5.0.0-beta.2";
459
+ var version = "5.0.0-beta.4";
462
460
 
463
461
  function relativify(path) {
464
462
  return path.startsWith('.') ? path : `./${path}`;
@@ -801,6 +799,7 @@ Options:
801
799
  --sourcemap enable sourcemap generation, default: false
802
800
  --dts determine if need to generate types, default: undefined
803
801
  --no-dts do not generate types, default: undefined
802
+ --tsconfig path to tsconfig file, default: tsconfig.json
804
803
  `;
805
804
  function help() {
806
805
  logger.log(helpMessage);
@@ -832,6 +831,7 @@ function parseCliArgs(argv) {
832
831
  '--no-external': Boolean,
833
832
  '--no-clean': Boolean,
834
833
  '--prepare': Boolean,
834
+ '--tsconfig': String,
835
835
  '-h': '--help',
836
836
  '-v': '--version',
837
837
  '-w': '--watch',
@@ -859,13 +859,14 @@ function parseCliArgs(argv) {
859
859
  external: !!args['--no-external'] ? null : args['--external'],
860
860
  clean: !args['--no-clean'],
861
861
  env: args['--env'],
862
- prepare: !!args['--prepare']
862
+ prepare: !!args['--prepare'],
863
+ tsconfig: args['--tsconfig']
863
864
  };
864
865
  return parsedArgs;
865
866
  }
866
867
  async function run(args) {
867
868
  var _args_external;
868
- const { source, format, watch, minify, sourcemap, target, runtime, dts, env, clean } = args;
869
+ const { source, format, watch, minify, sourcemap, target, runtime, dts, env, clean, tsconfig } = args;
869
870
  const cwd = args.cwd || process.cwd();
870
871
  const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
871
872
  const bundleConfig = {
@@ -880,7 +881,8 @@ async function run(args) {
880
881
  minify: !!minify,
881
882
  sourcemap: sourcemap === false ? false : true,
882
883
  env: (env == null ? void 0 : env.split(',')) || [],
883
- clean
884
+ clean,
885
+ tsconfig
884
886
  };
885
887
  if (args.version) {
886
888
  return logger.log(version);
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ type BundleConfig = {
18
18
  runtime?: string;
19
19
  pkg?: PackageMetadata;
20
20
  clean?: boolean;
21
+ tsconfig?: string;
21
22
  };
22
23
  type PackageMetadata = {
23
24
  name?: string;
package/dist/index.js CHANGED
@@ -305,10 +305,10 @@ function resolveTypescriptHandler(cwd) {
305
305
  return ts;
306
306
  }
307
307
  const resolveTypescript = memoize(resolveTypescriptHandler);
308
- function resolveTsConfigHandler(cwd) {
308
+ function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
309
309
  let tsCompilerOptions = {};
310
310
  let tsConfigPath;
311
- tsConfigPath = path.resolve(cwd, 'tsconfig.json');
311
+ tsConfigPath = path.resolve(cwd, tsconfig);
312
312
  if (fileExists(tsConfigPath)) {
313
313
  const ts = resolveTypescript(cwd);
314
314
  const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
@@ -1223,10 +1223,11 @@ function getCustomModuleLayer(moduleId) {
1223
1223
  const segments = path__default.default.basename(moduleId).split('.');
1224
1224
  if (segments.length >= 2) {
1225
1225
  const [layerSegment, ext] = segments.slice(-2);
1226
+ const baseName = segments[0];
1226
1227
  const match = layerSegment.match(/^(\w+)-runtime$/);
1227
1228
  const layer = match && match[1];
1228
1229
  if (availableExtensions.has(ext) && layer && layer.length > 0) {
1229
- return layer;
1230
+ return baseName + '-' + layer;
1230
1231
  }
1231
1232
  }
1232
1233
  return undefined;
@@ -1243,6 +1244,15 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
1243
1244
  const { isEntry } = moduleInfo;
1244
1245
  const moduleMeta = moduleInfo.meta;
1245
1246
  const moduleLayer = getModuleLater(moduleMeta);
1247
+ if (!isEntry) {
1248
+ const cachedCustomModuleLayer = splitChunksGroupMap.get(id);
1249
+ if (cachedCustomModuleLayer) return cachedCustomModuleLayer;
1250
+ const customModuleLayer = getCustomModuleLayer(id);
1251
+ if (customModuleLayer) {
1252
+ splitChunksGroupMap.set(id, customModuleLayer);
1253
+ return customModuleLayer;
1254
+ }
1255
+ }
1246
1256
  // Collect the sub modules of the entry, if they're having layer, and the same layer with the entry, push them to the dependencyGraphMap.
1247
1257
  if (isEntry) {
1248
1258
  const subModuleIds = ctx.getModuleIds();
@@ -1263,15 +1273,6 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
1263
1273
  }
1264
1274
  }
1265
1275
  }
1266
- if (!isEntry) {
1267
- const cachedCustomModuleLayer = splitChunksGroupMap.get(id);
1268
- if (cachedCustomModuleLayer) return cachedCustomModuleLayer;
1269
- const customModuleLayer = getCustomModuleLayer(id);
1270
- if (customModuleLayer) {
1271
- splitChunksGroupMap.set(id, customModuleLayer);
1272
- return customModuleLayer;
1273
- }
1274
- }
1275
1276
  // If current module has a layer, and it's not an entry
1276
1277
  if (moduleLayer && !isEntry) {
1277
1278
  // If the module is imported by the entry:
@@ -1572,7 +1573,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1572
1573
  // Original input file path, client path might change later
1573
1574
  const inputFile = cliEntryPath;
1574
1575
  const isFromCli = Boolean(cliEntryPath);
1575
- let tsConfig = resolveTsConfig(cwd);
1576
+ let tsConfig = resolveTsConfig(cwd, options.tsconfig);
1576
1577
  let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
1577
1578
  const defaultTsOptions = {
1578
1579
  tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
@@ -1662,8 +1663,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1662
1663
  entriesAlias
1663
1664
  }
1664
1665
  };
1665
- const buildConfigs = await buildEntryConfig(options, buildContext, false);
1666
- const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig));
1666
+ const assetsJobs = (await buildEntryConfig(options, buildContext, false)).map((rollupConfig)=>bundleOrWatch(rollupConfig));
1667
1667
  const typesJobs = hasTsConfig && options.dts !== false ? (await buildEntryConfig(options, buildContext, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : [];
1668
1668
  const totalJobs = assetsJobs.concat(typesJobs);
1669
1669
  const result = await Promise.all(totalJobs);
package/package.json CHANGED
@@ -1,10 +1,21 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "5.0.0-beta.2",
3
+ "version": "5.0.0-beta.4",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
+ "scripts": {
9
+ "test": "jest --env node",
10
+ "test:update": "TEST_UPDATE_SNAPSHOT=1 pnpm test",
11
+ "test:post": "POST_BUILD=1 pnpm jest test/compile.test.ts test/integration.test.ts",
12
+ "clean": "rm -rf ./dist",
13
+ "typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
14
+ "prepublishOnly": "pnpm clean && pnpm build && chmod +x ./dist/bin/cli.js && pnpm test",
15
+ "build": "tsx ./src/bin/index.ts --runtime node",
16
+ "format": "prettier --write .",
17
+ "prepare": "husky install"
18
+ },
8
19
  "type": "commonjs",
9
20
  "keywords": [
10
21
  "bundler",
@@ -104,14 +115,5 @@
104
115
  ],
105
116
  "testTimeout": 60000
106
117
  },
107
- "packageManager": "pnpm@8.8.0",
108
- "scripts": {
109
- "test": "jest --env node",
110
- "test:update": "TEST_UPDATE_SNAPSHOT=1 pnpm test",
111
- "test:post": "POST_BUILD=1 pnpm jest test/compile.test.ts test/integration.test.ts",
112
- "clean": "rm -rf ./dist",
113
- "typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
114
- "build": "tsx ./src/bin/index.ts --runtime node",
115
- "format": "prettier --write ."
116
- }
117
- }
118
+ "packageManager": "pnpm@8.8.0"
119
+ }