bunchee 6.3.0 → 6.3.2

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,8 +14,11 @@
14
14
  </a>
15
15
  </p>
16
16
 
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
- 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.
17
+ ---
18
+
19
+ **bunchee** is a zero-configuration bundler designed to streamline package building by adhering to the `exports` field in your **package.json**. Powered by Rollup and SWC ⚡️, it generates output based on your config, supporting both CommonJS and ESModules.
20
+
21
+ By using the standard `exports` configuration as the single source of truth, **bunchee** automatically aligns entry file conventions with your exports, ensuring seamless and efficient builds.
19
22
 
20
23
  ## Quick Start
21
24
 
@@ -36,14 +39,14 @@ mkdir src && touch ./src/index.ts && touch package.json
36
39
 
37
40
  Add the exports in `package.json`.
38
41
 
39
- ```json
42
+ ```json5
40
43
  {
41
- "name": "coffee",
42
- "type": "module",
43
- "main": "./dist/index.js",
44
- "scripts": {
45
- "build": "bunchee"
46
- }
44
+ name: 'coffee',
45
+ type: 'module',
46
+ main: './dist/index.js',
47
+ scripts: {
48
+ build: 'bunchee',
49
+ },
47
50
  }
48
51
  ```
49
52
 
@@ -53,192 +56,118 @@ Add the exports in `package.json`.
53
56
  npm run build
54
57
  ```
55
58
 
56
- Then files in `src` folders will be treated as entry files and match the export names in package.json.
57
- Simply like Node.js module resolution, each export name will match the file in `src/` directory.
58
-
59
- For example:
60
-
61
- - `src/index.ts` will match the exports name `"."` or the only main export.
62
- - `src/lite.ts` will match the exports name `"./lite"`.
63
- - `src/react/index.ts` will match the exports name `"./react"`.
64
-
65
- Now just run `npm run build` (or `pnpm build` / `yarn build`) if you're using these package managers, `bunchee` will find the entry files and build them.
66
- The output format will based on the exports condition and also the file extension. Given an example:
67
-
68
- - It's CommonJS for `require` and ESM for `import` based on the exports condition.
69
- - It's CommonJS for `.js` and ESM for `.mjs` based on the extension regardless the exports condition. Then for export condition like "node" you could choose the format with your extension.
70
-
71
- > [!NOTE]
72
- > All the `dependencies` and `peerDependencies` will be marked as external automatically and not included in the bundle. If you want to include them in the bundle, you can use the `--no-external` option.
73
-
74
- #### Prepare Package
59
+ ## Usage
75
60
 
76
- ```sh
77
- # Use bunchee to prepare package.json configuration
78
- npm exec bunchee prepare
79
- # "If you're using other package manager such as pnpm"
80
- # pnpm bunchee prepare
61
+ ### Entry Files
81
62
 
82
- # "Or use with npx"
83
- # npx bunchee@latest prepare
84
- ```
85
-
86
- Or you can checkout the following cases to configure your package.json.
63
+ Then files in `src` folders will be treated as entry files and match the export names in package.json.
64
+ Simply like Node.js module resolution, each export name will match the file in `src/` directory.
87
65
 
88
- <details>
89
- <summary>JavaScript ESModule</summary>
66
+ Here's a example of entry files and exports configuration:
90
67
 
91
- Then use use the [exports field in package.json](https://nodejs.org/api/packages.html#exports-sugar) to configure different conditions and leverage the same functionality as other bundlers, such as webpack. The exports field allows you to define multiple conditions.
68
+ | **File** | **Exports Name** |
69
+ | -------------------- | ---------------------- |
70
+ | `src/index.ts` | `"."` (default export) |
71
+ | `src/lite.ts` | `"./lite"` |
72
+ | `src/react/index.ts` | `"./react"` |
92
73
 
93
- ```json
74
+ ```json5
94
75
  {
95
- "files": ["dist"],
96
- "type": "module",
97
- "exports": {
98
- ".": "./dist/es/index.js",
99
- "./react": "./dist/es/react.js"
76
+ name: 'coffee',
77
+ scripts: {
78
+ build: 'bunchee',
100
79
  },
101
- "scripts": {
102
- "build": "bunchee"
103
- }
104
- }
105
- ```
106
-
107
- </details>
108
-
109
- <details>
110
- <summary>TypeScript</summary>
111
-
112
- If you're build a TypeScript library, separate the types from the main entry file and specify the types path in package.json. Types exports need to stay on the top of each export with `types` condition, and you can use `default` condition for the JS bundle file.
113
-
114
- ```json
115
- {
116
- "files": ["dist"],
117
- "type": "module",
118
- "main": "./dist/index.js",
119
- "exports": {
120
- ".": {
121
- "types": "./dist/index.d.ts",
122
- "default": "./dist/index.js"
80
+ type: 'module',
81
+ exports: {
82
+ // entry: ./src/index.ts
83
+ '.': {
84
+ import: './dist/index.js',
85
+ require: './dist/index.cjs',
123
86
  },
124
- "./react": {
125
- "types": "./dist/react/index.d.ts",
126
- "default": "./dist/react/index.js"
127
- }
128
- },
129
- "scripts": {
130
- "build": "bunchee"
131
- }
132
- }
133
- ```
134
-
135
- </details>
136
87
 
137
- <details>
138
- <summary>Hybrid (CJS & ESM) Module Resolution with TypeScript</summary>
139
- If you're using TypeScript with Node 10 and Node 16 module resolution, you can use the `types` field in package.json to specify the types path. Then `bunchee` will generate the types file with the same extension as the main entry file.
88
+ // entry: ./src/lite.ts
89
+ './lite': './dist/lite.js',
140
90
 
141
- _NOTE_: When you're using `.mjs` or `.cjs` extensions with TypeScript and modern module resolution (above node16), TypeScript will require specific type declaration files like `.d.mts` or `.d.cts` to match the extension. `bunchee` can automatically generate them to match the types to match the condition and extensions.
142
-
143
- ```json
144
- {
145
- "files": ["dist"],
146
- "type": "module",
147
- "main": "./dist/index.js",
148
- "module": "./dist/index.js",
149
- "types": "./dist/index.d.ts",
150
- "exports": {
151
- "import": {
152
- "types": "./dist/index.d.ts",
153
- "default": "./dist/index.js"
154
- },
155
- "require": {
156
- "types": "./dist/index.d.cts",
157
- "default": "./dist/index.cjs"
158
- }
91
+ // entry: ./src/react/index.ts
92
+ './react': './dist/react.js',
159
93
  },
160
- "scripts": {
161
- "build": "bunchee"
162
- }
163
94
  }
164
95
  ```
165
96
 
166
- </details>
97
+ ### Output Formats
167
98
 
168
- #### Lint Package
99
+ **bunchee** detects the format of each entry-point based on export condition type or the file extension. It supports the following output formats:
169
100
 
170
- `lint` command will check the package.json configuration is valid or not, it can valid few things like:
101
+ | `package.json` Field | Output format |
102
+ | -------------------- | -------------------------------- |
103
+ | `main` | Default |
104
+ | `types` | TypeScript declaration |
105
+ | `exports` | Default |
106
+ | `exports.require` | CommonJS |
107
+ | `exports.import` | Default |
108
+ | `exports.types` | TypeScript declaration of export |
109
+ | `bin` | Default |
110
+ | `bin.<name>` | Default |
171
111
 
172
- - if the entry files are matched with the exports conditions.
173
- - if the entry files are matched with the exports paths.
112
+ The **Default** output format is determined by the file extension:
174
113
 
175
- ```sh
176
- # Use bunchee to lint if the package.json configuration is valid
177
- npm exec bunchee lint
178
- ```
114
+ | File Extension | Output format |
115
+ | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
116
+ | `.js` | Determined by `package.json#type`, CommonJS by default |
117
+ | `.cjs` | [CommonJS](https://nodejs.org/api/packages.html#:~:text=Files%20ending%20with%20.cjs%20are%20always%20loaded%20as%20CommonJS%20regardless%20of%20the%20nearest%20parent%20package.json) |
118
+ | `.mjs` | [ECMAScript Modules](https://nodejs.org/api/modules.html#the-mjs-extension) |
179
119
 
180
- ## Usage
120
+ ### External Dependencies
181
121
 
182
- ### File Conventions
122
+ The `dependencies` and `peerDependencies` will be marked as externalized and wont be included in the bundle. If you want to include them in the bundle, you can use the `--no-external` option. Or you can import the `devDependencies` in your source code to bundle them.
183
123
 
184
- While `exports` field is becoming the standard of exporting in node.js, bunchee also supports to build multiple exports all in one command.
124
+ ```json5
125
+ {
126
+ // Externalized
127
+ dependencies: {
128
+ /* ... */
129
+ },
130
+ peerDependencies: {
131
+ /* ... */
132
+ },
185
133
 
186
- Provide entry files with the name (`[name].[ext]`) that matches the exported name from exports field in package.json. For instance:
134
+ // Bundled
135
+ devDependencies: {
136
+ /* ... */
137
+ },
138
+ }
139
+ ```
187
140
 
188
- - `<cwd>/src/index.ts` will match `"."` export name or the if there's only one main export.
189
- - `<cwd>/src/lite.ts` will match `"./lite"` export name.
141
+ ### Multiple Runtime
190
142
 
191
- The build script can be just `bunchee` without configure any input sources for each exports. Of course you can still specify other arguments as you need.
192
- Briefly, the entry files from `src/` folder will do matching with `exports` conditions from `package.json` and build them into bundles.
143
+ For exports condition like `react-native`, `react-server` and `edge-light` as they're special platforms, they could have different exports or different code conditions. In this case bunchee provides an override input source file convention if you want to build them as different code bundle.
193
144
 
194
- Assuming you have default export package as `"."` and subpath export `"./lite"` with different exports condition listed in package.json
145
+ For instance:
195
146
 
196
- ```json
147
+ ```json5
197
148
  {
198
- "name": "example",
199
- "scripts": {
200
- "build": "bunchee"
149
+ exports: {
150
+ 'react-server': './dist/react-server.mjs',
151
+ 'edge-light': './dist/edge-light.mjs',
152
+ import: './dist/index.mjs',
201
153
  },
202
- "type": "module",
203
- "exports": {
204
- "./lite": "./dist/lite.js",
205
- ".": {
206
- "import": "./dist/index.js",
207
- "require": "./dist/index.cjs"
208
- }
209
- }
210
154
  }
211
155
  ```
212
156
 
213
- Then you need to add two entry files `index.ts` and `lite.ts` in project root directory to match the export name `"."` and `"./lite"`, bunchee will associate these entry files with export names then use them as input source and output paths information.
214
-
215
- ```
216
- - my-lib/
217
- |- src/
218
- |- lite.ts
219
- |- index.ts
220
- |- package.json
221
- ```
222
-
223
- It will also look up for `index.<ext>` file under the directory having the name of the export path. For example, if you have `"./lite": "./dist/lite.js"` in exports field, then it will look up for `./lite/index.js` as the entry file as well.
224
-
225
- ### Multiple Runtime
226
-
227
- For exports condition like `react-native`, `react-server` and `edge-light` as they're special platforms, they could have different exports or different code conditions. In this case bunchee provides an override input source file convention if you want to build them as different code bundle.
157
+ ### Path Alias
228
158
 
229
- For instance:
159
+ `bunchee` supports both TypeScript `paths` config and Node.js [`imports field`](https://nodejs.org/api/packages.html#subpath-imports) in `package.json` for path aliasing. It will resolve the path alias to the correct file path. If you're using modern TypeScript versions, you can also directly configure the `imports` field in `package.json` and it will work as a charm.
230
160
 
231
- ```json
161
+ ```json5
162
+ // package.json
232
163
  {
233
- "exports": {
234
- "react-server": "./dist/react-server.mjs",
235
- "edge-light": "./dist/edge-light.mjs",
236
- "import": "./dist/index.mjs"
237
- }
164
+ imports: {
165
+ '#util': './src/utils.ts',
166
+ },
238
167
  }
239
168
  ```
240
169
 
241
- ### Executables
170
+ ### Binary CLI
242
171
 
243
172
  To build executable files with the `bin` field in package.json, `bunchee` requires you to create the `bin` directory under `src` directory. The source file matching will be same as the entry files convention.
244
173
 
@@ -252,45 +181,49 @@ For example:
252
181
 
253
182
  This will match the `bin` field in package.json as:
254
183
 
255
- ```json
184
+ ```json5
256
185
  {
257
- "bin": "./dist/bin.js"
186
+ bin: './dist/bin.js',
258
187
  }
259
188
  ```
260
189
 
261
- For multiple executable files, you can create multiple files under the `bin` directory.
190
+ If you have multiple binaries, you can create multiple files under the `bin` directory. Check the below example for more details.
191
+
192
+ <details>
193
+ <summary>Multiple Binaries</summary>
194
+
195
+ For named executable files, you can create multiple files under the `bin` directory.
262
196
 
263
197
  ```bash
264
198
  |- src/
265
199
  |- bin/
266
- |- foo.ts
267
- |- bar.ts
200
+
268
201
  ```
269
202
 
270
203
  This will match the `bin` field in package.json as:
271
204
 
272
- ```json
205
+ ```json5
273
206
  {
274
- "bin": {
275
- "foo": "./dist/bin/a.js",
276
- "bar": "./dist/bin/b.js"
277
- }
207
+ bin: {
208
+ foo: './dist/bin/a.js',
209
+ bar: './dist/bin/b.js',
210
+ },
278
211
  }
279
212
  ```
280
213
 
214
+ </details>
215
+
281
216
  > Note: For multiple `bin` files, the filename should match the key name in the `bin` field.
282
217
 
283
218
  ### Server Components
284
219
 
285
- `bunchee` supports to build server components and server actions with library directives like `"use client"` or `"use server"`. It will generate the corresponding chunks for client and server that scope the client and server boundaries properly.
286
- Then when the library is integrated to an app such as Next.js, app bundler can transform the client components and server actions correctly and maximum the benefits.
287
-
288
- 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.
289
- 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.
220
+ **bunchee** supports building React Server Components and Server Actions with directives like `"use client"` or `"use server"`. It generates separate chunks for the server or client boundaries. When integrated to framework like Next.js, it can correctly handles the boundaries with the split chunks.
290
221
 
291
222
  ### Shared Modules
292
223
 
293
- In some cases, you may need to share code across multiple bundles without promoting them to separate entries or exports. These modules should be bundled into shared chunks that can be reused by various bundles. By convention, files or directories **prefixed with an underscore** (`_<name>.<ext>` or `_<name>/**`) are treated as **shared modules**. They're private and not exposed publicly as entry points or exports. Testing, mocking related files are ignored. e.g. `_foo/a.test.ts` will not be treated as shared module.
224
+ Sometimes, you may want to share a chunk across multiple bundles without promoting it to separate entries or exports, such as single instance of React context module, shared utils, etc. In these cases, **shared modules** will help you achieve the goal. Files or directories **prefixed with an underscore** (`_<name>.<ext>` or `_<name>/**`) will be treated as **shared modules**.
225
+
226
+ These conventions are kept private and are not going to be treat as shared modules or entry points. For example, test or mock files like `_foo/a.test.ts` will be ignored and not included as shared modules.
294
227
 
295
228
  <details>
296
229
  <summary>Shared Utils Example</summary>
@@ -351,38 +284,23 @@ This convention keeps shared modules private while enabling efficient bundling a
351
284
 
352
285
  #### CLI Options
353
286
 
354
- `bunchee` CLI provides few options to create different bundles or generating types.
355
-
356
- - Output (`-o <file>`): Specify output filename.
357
- - Format (`-f <format>`): Set output format (default: `'esm'`).
358
- - External (`--external <dep,>`): Specifying extra external dependencies, by default it is the list of `dependencies` and `peerDependencies` from `package.json`. Values are separate by comma.
359
- - Target (`--target <target>`): Set ECMAScript target (default: `'es2015'`).
360
- - Runtime (`--runtime <runtime>`): Set build runtime (default: `'browser'`).
361
- - Environment (`--env <env,>`): Define environment variables. (default: `[]`, separate by comma)
362
- - Working Directory (`--cwd <cwd>`): Set current working directory where containing `package.json`.
363
- - Minify (`-m`): Compress output.
364
- - Watch (`-w`): Watch for source file changes.
365
- - No Clean(`--no-clean`): Do not clean the dist folder before building. (default: `false`)
366
- - TSConfig (`--tsconfig <path>`): Specify the path to the TypeScript configuration file. (default: `tsconfig.json`)
367
- - Bundle Types (`--dts-bundle`): Bundle type declaration files. (default: `false`)
287
+ `bunchee` CLI provides few options to create different bundles or generating types. Call `bunchee --help` to see the help information in the terminal.
288
+
289
+ Here are the available options for the CLI:
368
290
 
369
291
  ```sh
370
292
  cd <project-root-dir>
371
293
 
372
- # specifying input, output and format
294
+ # Build based on the package.json configuration
295
+ bunchee --runtime node -o ./dist/bundle.js
296
+ bunchee -f esm -o --target es2022 ./dist/bundle.esm.js
373
297
 
374
- bunchee ./src/index.js -f cjs -o ./dist/bundle.js
375
- bunchee ./src/index.js -f esm -o ./dist/bundle.esm.js
376
-
377
- # build node.js library, or change target to es2019
378
- bunchee ./src/index.js --runtime node --target es2019
298
+ # Specify the input source file
299
+ bunchee ./src/foo.ts -o ./dist/foo.js
379
300
  ```
380
301
 
381
302
  #### Specifying extra external dependencies
382
303
 
383
- By default, `bunchee` will mark all the `dependencies` and `peerDependencies` as externals so you don't need to pass them as CLI args.
384
- But if there's any dependency that used but not in the dependency list and you want to mark as external, you can use the `--external` option to specify them.
385
-
386
304
  ```sh
387
305
  bunchee --external=dep1,dep2,dep3
388
306
  ```
@@ -399,6 +317,112 @@ bunchee --no-external
399
317
 
400
318
  This will include all dependencies within your output bundle.
401
319
 
320
+ #### Prepare Package
321
+
322
+ ```sh
323
+ # Use bunchee to prepare package.json configuration
324
+ npm exec bunchee prepare
325
+ # "If you're using other package manager such as pnpm"
326
+ # pnpm bunchee prepare
327
+
328
+ # "Or use with npx"
329
+ # npx bunchee@latest prepare
330
+ ```
331
+
332
+ Or you can checkout the following cases to configure your package.json.
333
+
334
+ <details>
335
+ <summary>JavaScript ESModule</summary>
336
+
337
+ Then use use the [exports field in package.json](https://nodejs.org/api/packages.html#exports-sugar) to configure different conditions and leverage the same functionality as other bundlers, such as webpack. The exports field allows you to define multiple conditions.
338
+
339
+ ```json5
340
+ {
341
+ files: ['dist'],
342
+ type: 'module',
343
+ exports: {
344
+ '.': './dist/es/index.js',
345
+ './react': './dist/es/react.js',
346
+ },
347
+ scripts: {
348
+ build: 'bunchee',
349
+ },
350
+ }
351
+ ```
352
+
353
+ </details>
354
+
355
+ <details>
356
+ <summary>TypeScript</summary>
357
+
358
+ If you're building a TypeScript library, separate the types from the main entry file and specify the types path in package.json. Types exports need to stay on the top of each export with `types` condition, and you can use `default` condition for the JS bundle file.
359
+
360
+ ```json5
361
+ {
362
+ files: ['dist'],
363
+ type: 'module',
364
+ main: './dist/index.js',
365
+ exports: {
366
+ '.': {
367
+ types: './dist/index.d.ts',
368
+ default: './dist/index.js',
369
+ },
370
+ './react': {
371
+ types: './dist/react/index.d.ts',
372
+ default: './dist/react/index.js',
373
+ },
374
+ },
375
+ scripts: {
376
+ build: 'bunchee',
377
+ },
378
+ }
379
+ ```
380
+
381
+ </details>
382
+
383
+ <details>
384
+ <summary>Hybrid (CJS & ESM) Module Resolution with TypeScript</summary>
385
+ If you're using TypeScript with Node 10 and Node 16 module resolution, you can use the `types` field in package.json to specify the types path. Then `bunchee` will generate the types file with the same extension as the main entry file.
386
+
387
+ _NOTE_: When you're using `.mjs` or `.cjs` extensions with TypeScript and modern module resolution (above node16), TypeScript will require specific type declaration files like `.d.mts` or `.d.cts` to match the extension. `bunchee` can automatically generate them to match the types to match the condition and extensions.
388
+
389
+ ```json5
390
+ {
391
+ files: ['dist'],
392
+ type: 'module',
393
+ main: './dist/index.js',
394
+ module: './dist/index.js',
395
+ types: './dist/index.d.ts',
396
+ exports: {
397
+ import: {
398
+ types: './dist/index.d.ts',
399
+ default: './dist/index.js',
400
+ },
401
+ require: {
402
+ types: './dist/index.d.cts',
403
+ default: './dist/index.cjs',
404
+ },
405
+ },
406
+ scripts: {
407
+ build: 'bunchee',
408
+ },
409
+ }
410
+ ```
411
+
412
+ </details>
413
+
414
+ #### Lint Package
415
+
416
+ `lint` command will check the package.json configuration is valid or not, it can valid few things like:
417
+
418
+ - if the entry files are matched with the exports conditions.
419
+ - if the entry files are matched with the exports paths.
420
+
421
+ ```sh
422
+ # Use bunchee to lint if the package.json configuration is valid
423
+ npm exec bunchee lint
424
+ ```
425
+
402
426
  ### Environment Variables
403
427
 
404
428
  To pass environment variables to your bundled code, use the --env option followed by a comma-separated list of environment variable names:
@@ -424,12 +448,12 @@ This will match the export name `"react-server"` and `"edge-light"` then use the
424
448
 
425
449
  `process.env.NODE_ENV` is injected by default if present that you don't need to manually inject yourself. If you need to separate the development build and production build, `bunchee` provides different export conditions for development and production mode with `development` and `production` export conditions.
426
450
 
427
- ```json
451
+ ```json5
428
452
  {
429
- "exports": {
430
- "development": "./dist/index.development.js",
431
- "production": "./dist/index.production.js"
432
- }
453
+ exports: {
454
+ development: './dist/index.development.js',
455
+ production: './dist/index.production.js',
456
+ },
433
457
  }
434
458
  ```
435
459
 
@@ -512,14 +536,14 @@ To target a range of browsers, you can use the `browserslist` field in `package.
512
536
 
513
537
  For example:
514
538
 
515
- ```json
539
+ ```json5
516
540
  {
517
- "browserslist": [
518
- "last 1 version",
519
- "> 1%",
520
- "maintained node versions",
521
- "not dead"
522
- ]
541
+ browserslist: [
542
+ 'last 1 version',
543
+ '> 1%',
544
+ 'maintained node versions',
545
+ 'not dead',
546
+ ],
523
547
  }
524
548
  ```
525
549
 
package/dist/bin/cli.js CHANGED
@@ -9,7 +9,7 @@ var require$$0 = require('tty');
9
9
  var picomatch = require('picomatch');
10
10
  var index_js = require('../index.js');
11
11
  require('module');
12
- var glob = require('glob');
12
+ var fastGlob = require('fast-glob');
13
13
  var prettyBytes = require('pretty-bytes');
14
14
 
15
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -69,9 +69,13 @@ const tsExtensions = new Set([
69
69
  ]);
70
70
  const DEFAULT_TS_CONFIG = {
71
71
  compilerOptions: {
72
+ target: 'ES2022',
72
73
  module: 'ESNext',
73
74
  moduleResolution: 'bundler'
74
- }
75
+ },
76
+ include: [
77
+ 'src'
78
+ ]
75
79
  };
76
80
  const BINARY_TAG = '$binary';
77
81
  const PRIVATE_GLOB_PATTERN = '**/_*/**';
@@ -642,7 +646,7 @@ function lint$1(pkg) {
642
646
  }
643
647
  }
644
648
 
645
- var version = "6.3.0";
649
+ var version = "6.3.2";
646
650
 
647
651
  async function writeDefaultTsconfig(tsConfigPath) {
648
652
  await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
@@ -726,10 +730,11 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
726
730
  ...availableExtensions
727
731
  ].join(',')}}`
728
732
  ];
729
- const entryFiles = await glob.glob(entryFilesPatterns, {
733
+ const entryFiles = await fastGlob.glob(entryFilesPatterns, {
730
734
  cwd: dirPath,
731
- nodir: true,
732
- ignore: PRIVATE_GLOB_PATTERN
735
+ ignore: [
736
+ PRIVATE_GLOB_PATTERN
737
+ ]
733
738
  });
734
739
  validateEntryFiles(entryFiles);
735
740
  for (const file of entryFiles){
@@ -774,17 +779,15 @@ async function collectSourceEntries(sourceFolderPath) {
774
779
  const srcPattern = `**/*.{${[
775
780
  ...availableExtensions
776
781
  ].join(',')}}`;
777
- const binMatches = await glob.glob(binPattern, {
782
+ const binMatches = await fastGlob.glob(binPattern, {
778
783
  cwd: sourceFolderPath,
779
- nodir: true,
780
784
  ignore: [
781
785
  PRIVATE_GLOB_PATTERN,
782
786
  TESTS_GLOB_PATTERN
783
787
  ]
784
788
  });
785
- const srcMatches = await glob.glob(srcPattern, {
789
+ const srcMatches = await fastGlob.glob(srcPattern, {
786
790
  cwd: sourceFolderPath,
787
- nodir: true,
788
791
  ignore: [
789
792
  PRIVATE_GLOB_PATTERN,
790
793
  TESTS_GLOB_PATTERN
@@ -1198,11 +1201,11 @@ async function run(args) {
1198
1201
  cwd,
1199
1202
  target,
1200
1203
  runtime,
1201
- external: args.external === null ? null : ((_args_external = args.external) == null ? void 0 : _args_external.split(',')) || [],
1204
+ external: args.external === null ? null : ((_args_external = args.external) == null ? undefined : _args_external.split(',')) || [],
1202
1205
  watch: !!watch,
1203
1206
  minify: !!minify,
1204
1207
  sourcemap: sourcemap === false ? false : true,
1205
- env: (env == null ? void 0 : env.split(',')) || [],
1208
+ env: (env == null ? undefined : env.split(',')) || [],
1206
1209
  clean,
1207
1210
  tsconfig
1208
1211
  };
@@ -1256,7 +1259,7 @@ async function run(args) {
1256
1259
  if (assetJobs.length === 0) {
1257
1260
  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');
1258
1261
  }
1259
- const outputState = initialBuildContext == null ? void 0 : initialBuildContext.pluginContext.outputState;
1262
+ const outputState = initialBuildContext == null ? undefined : initialBuildContext.pluginContext.outputState;
1260
1263
  if (outputState) {
1261
1264
  logOutputState(outputState.getSizeStats());
1262
1265
  }
@@ -1268,7 +1271,7 @@ async function run(args) {
1268
1271
  onBuildEnd
1269
1272
  };
1270
1273
  if (watch) {
1271
- logger.log(`Watching project ${cwd}...`);
1274
+ logger.log(`Watching changes in the project directory...`);
1272
1275
  }
1273
1276
  try {
1274
1277
  await index_js.bundle(cliEntry, bundleConfig);
@@ -1279,7 +1282,7 @@ async function run(args) {
1279
1282
  error: err
1280
1283
  };
1281
1284
  }
1282
- if ((buildError == null ? void 0 : buildError.digest) === 'bunchee:not-existed') {
1285
+ if ((buildError == null ? undefined : buildError.digest) === 'bunchee:not-existed') {
1283
1286
  help();
1284
1287
  } else {
1285
1288
  if (watch) {
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ var fsp = require('fs/promises');
4
4
  var fs = require('fs');
5
5
  var path = require('path');
6
6
  require('pretty-bytes');
7
- var glob = require('glob');
7
+ var fastGlob = require('fast-glob');
8
8
  var require$$0 = require('tty');
9
9
  var module$1 = require('module');
10
10
  var rollup = require('rollup');
@@ -249,9 +249,13 @@ const tsExtensions = new Set([
249
249
  ]);
250
250
  const DEFAULT_TS_CONFIG = {
251
251
  compilerOptions: {
252
+ target: 'ES2022',
252
253
  module: 'ESNext',
253
254
  moduleResolution: 'bundler'
254
- }
255
+ },
256
+ include: [
257
+ 'src'
258
+ ]
255
259
  };
256
260
  const BINARY_TAG = '$binary';
257
261
  const PRIVATE_GLOB_PATTERN = '**/_*/**';
@@ -813,10 +817,11 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
813
817
  ...availableExtensions
814
818
  ].join(',')}}`
815
819
  ];
816
- const entryFiles = await glob.glob(entryFilesPatterns, {
820
+ const entryFiles = await fastGlob.glob(entryFilesPatterns, {
817
821
  cwd: dirPath,
818
- nodir: true,
819
- ignore: PRIVATE_GLOB_PATTERN
822
+ ignore: [
823
+ PRIVATE_GLOB_PATTERN
824
+ ]
820
825
  });
821
826
  validateEntryFiles(entryFiles);
822
827
  for (const file of entryFiles){
@@ -880,10 +885,11 @@ async function collectSourceEntriesByExportPath(sourceFolderPath, originalSubpat
880
885
  ...availableExtensions
881
886
  ].join(',');
882
887
  const privatePattern = `**/_*{,/*}{,{.${suffixPattern}}}.{${extPattern}}`;
883
- const privateFiles = await glob.glob(privatePattern, {
888
+ const privateFiles = await fastGlob.glob(privatePattern, {
884
889
  cwd: sourceFolderPath,
885
- nodir: true,
886
- ignore: TESTS_GLOB_PATTERN
890
+ ignore: [
891
+ TESTS_GLOB_PATTERN
892
+ ]
887
893
  });
888
894
  for (const file of privateFiles){
889
895
  const sourceFileAbsolutePath = path__default.default.join(sourceFolderPath, file);
@@ -1003,7 +1009,7 @@ function createOutputState({ entries }) {
1003
1009
  };
1004
1010
  }
1005
1011
 
1006
- const memoize = (fn, cacheKey, cacheArg)=>{
1012
+ const createMemoize = (fn, cacheKey, cacheArg)=>{
1007
1013
  const cache = cacheArg || new Map();
1008
1014
  return (...args)=>{
1009
1015
  const key = cacheKey ? typeof cacheKey === 'function' ? cacheKey(...args) : cacheKey : JSON.stringify({
@@ -1020,8 +1026,9 @@ const memoize = (fn, cacheKey, cacheArg)=>{
1020
1026
  };
1021
1027
  const memoizeByKey = (fn)=>{
1022
1028
  const cache = new Map();
1023
- return (cacheKey)=>memoize(fn, cacheKey, cache);
1029
+ return (cacheKey)=>createMemoize(fn, cacheKey, cache);
1024
1030
  };
1031
+ const memoize = (fn)=>createMemoize(fn);
1025
1032
 
1026
1033
  let hasLoggedTsWarning = false;
1027
1034
  function resolveTypescript(cwd) {
@@ -1049,11 +1056,14 @@ function resolveTypescript(cwd) {
1049
1056
  }
1050
1057
  return ts;
1051
1058
  }
1052
- function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
1053
- let tsCompilerOptions = {};
1059
+ const resolveTsConfigPath = memoize((cwd, tsconfigFileName = 'tsconfig.json')=>{
1054
1060
  let tsConfigPath;
1055
- tsConfigPath = path.resolve(cwd, tsconfig);
1056
- if (fileExists(tsConfigPath)) {
1061
+ tsConfigPath = path.resolve(cwd, tsconfigFileName);
1062
+ return fileExists(tsConfigPath) ? tsConfigPath : undefined;
1063
+ });
1064
+ function resolveTsConfigHandler(cwd, tsConfigPath) {
1065
+ let tsCompilerOptions = {};
1066
+ if (tsConfigPath) {
1057
1067
  // Use the original ts handler to avoid memory leak
1058
1068
  const ts = resolveTypescript(cwd);
1059
1069
  const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
@@ -1067,7 +1077,7 @@ function resolveTsConfigHandler(cwd, tsconfig = 'tsconfig.json') {
1067
1077
  tsConfigPath
1068
1078
  };
1069
1079
  }
1070
- const resolveTsConfig = memoizeByKey(resolveTsConfigHandler)();
1080
+ const resolveTsConfig = memoize(resolveTsConfigHandler);
1071
1081
  async function convertCompilerOptions(cwd, json) {
1072
1082
  // Use the original ts handler to avoid memory leak
1073
1083
  const ts = resolveTypescript(cwd);
@@ -1345,7 +1355,7 @@ function aliasEntries({ entry: sourceFilePath, conditionNames, entries, format,
1345
1355
  if (dts) {
1346
1356
  var _exportMapEntries_find;
1347
1357
  // Find the type with format condition first
1348
- matchedBundlePath = (_exportMapEntries_find = exportMapEntries.find(findTypesFileCallback)) == null ? void 0 : _exportMapEntries_find.bundlePath;
1358
+ matchedBundlePath = (_exportMapEntries_find = exportMapEntries.find(findTypesFileCallback)) == null ? undefined : _exportMapEntries_find.bundlePath;
1349
1359
  // If theres no format specific types such as import.types or require.types,
1350
1360
  // fallback to the general types file.
1351
1361
  if (!matchedBundlePath) {
@@ -1355,13 +1365,13 @@ function aliasEntries({ entry: sourceFilePath, conditionNames, entries, format,
1355
1365
  ...item,
1356
1366
  format: undefined
1357
1367
  });
1358
- })) == null ? void 0 : _exportMapEntries_find1.bundlePath;
1368
+ })) == null ? undefined : _exportMapEntries_find1.bundlePath;
1359
1369
  }
1360
1370
  } else {
1361
1371
  var _exportMapEntries_find2;
1362
1372
  matchedBundlePath = (_exportMapEntries_find2 = exportMapEntries.find((item)=>{
1363
1373
  return findJsBundlePathCallback(item, specialCondition);
1364
- })) == null ? void 0 : _exportMapEntries_find2.bundlePath;
1374
+ })) == null ? undefined : _exportMapEntries_find2.bundlePath;
1365
1375
  }
1366
1376
  if (matchedBundlePath) {
1367
1377
  if (!sourceToRelativeBundleMap.has(exportCondition.source)) sourceToRelativeBundleMap.set(exportCondition.source, matchedBundlePath);
@@ -1519,7 +1529,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
1519
1529
  const sizePlugin = pluginContext.outputState.plugin(cwd);
1520
1530
  // common plugins for both dts and ts assets that need to be processed
1521
1531
  // If it's a .d.ts file under non-ESM package or .d.cts file, use cjs types alias.
1522
- const aliasFormat = dts ? ((_bundleConfig_file = bundleConfig.file) == null ? void 0 : _bundleConfig_file.endsWith('.d.cts')) || ((_bundleConfig_file1 = bundleConfig.file) == null ? void 0 : _bundleConfig_file1.endsWith('.d.ts')) && !isESModulePackage(pkg.type) ? 'cjs' : 'esm' : bundleConfig.format;
1532
+ const aliasFormat = dts ? ((_bundleConfig_file = bundleConfig.file) == null ? undefined : _bundleConfig_file.endsWith('.d.cts')) || ((_bundleConfig_file1 = bundleConfig.file) == null ? undefined : _bundleConfig_file1.endsWith('.d.ts')) && !isESModulePackage(pkg.type) ? 'cjs' : 'esm' : bundleConfig.format;
1523
1533
  const currentConditionNames = Object.keys(exportCondition.export)[0];
1524
1534
  const aliasPlugin = aliasEntries({
1525
1535
  entry,
@@ -1685,7 +1695,7 @@ async function buildOutputConfigs(bundleConfig, exportCondition, buildContext, d
1685
1695
  const { format } = bundleConfig;
1686
1696
  const { entries, pkg, cwd, tsOptions: { tsCompilerOptions }, pluginContext } = buildContext;
1687
1697
  // Add esm mark and interop helper if esm export is detected
1688
- const useEsModuleMark = tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop;
1698
+ const useEsModuleMark = tsCompilerOptions == null ? undefined : tsCompilerOptions.esModuleInterop;
1689
1699
  const absoluteOutputFile = path.resolve(cwd, bundleConfig.file);
1690
1700
  const isEsmPkg = isESModulePackage(pkg.type);
1691
1701
  const name = filePathWithoutExtension(absoluteOutputFile);
@@ -1893,11 +1903,12 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1893
1903
  // Original input file path, client path might change later
1894
1904
  const inputFile = cliEntryPath;
1895
1905
  const isFromCli = Boolean(cliEntryPath);
1896
- let tsConfig = resolveTsConfig(cwd, options.tsconfig);
1897
- let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
1906
+ const tsConfigPath = resolveTsConfigPath(cwd, options.tsconfig);
1907
+ let tsConfig = resolveTsConfig(cwd, tsConfigPath);
1908
+ let hasTsConfig = Boolean(tsConfig == null ? undefined : tsConfig.tsConfigPath);
1898
1909
  const defaultTsOptions = {
1899
- tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
1900
- tsCompilerOptions: (tsConfig == null ? void 0 : tsConfig.tsCompilerOptions) || {}
1910
+ tsConfigPath: tsConfig == null ? undefined : tsConfig.tsConfigPath,
1911
+ tsCompilerOptions: (tsConfig == null ? undefined : tsConfig.tsCompilerOptions) || {}
1901
1912
  };
1902
1913
  // Handle single entry file
1903
1914
  if (!isMultiEntries) {
@@ -1947,10 +1958,16 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1947
1958
  }
1948
1959
  const entries = await collectEntriesFromParsedExports(cwd, parsedExportsInfo, pkg, inputFile);
1949
1960
  const hasTypeScriptFiles = Object.values(entries).some((entry)=>isTypescriptFile(entry.source));
1961
+ // If there's no tsconfig, create one.
1950
1962
  if (hasTypeScriptFiles && !hasTsConfig) {
1951
- const tsConfigPath = path.resolve(cwd, 'tsconfig.json');
1952
- defaultTsOptions.tsConfigPath = tsConfigPath;
1953
- await writeDefaultTsconfig(tsConfigPath);
1963
+ // Check if tsconfig.json exists in the project first.
1964
+ // If not, create one with default settings.
1965
+ // Otherwise, use the existing one.
1966
+ const defaultTsConfigPath = path.resolve(cwd, 'tsconfig.json');
1967
+ if (!fileExists(defaultTsConfigPath)) {
1968
+ await writeDefaultTsconfig(defaultTsConfigPath);
1969
+ }
1970
+ defaultTsOptions.tsConfigPath = defaultTsConfigPath;
1954
1971
  hasTsConfig = true;
1955
1972
  }
1956
1973
  let browserslistConfig;
@@ -1972,14 +1989,14 @@ async function bundle(cliEntryPath, { cwd: _cwd, ...options } = {}) {
1972
1989
  moduleDirectiveLayerMap: new Map()
1973
1990
  }
1974
1991
  };
1975
- (_options__callbacks = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildStart = _options__callbacks.onBuildStart) == null ? void 0 : _options__callbacks_onBuildStart.call(_options__callbacks, buildContext);
1992
+ (_options__callbacks = options._callbacks) == null ? undefined : (_options__callbacks_onBuildStart = _options__callbacks.onBuildStart) == null ? undefined : _options__callbacks_onBuildStart.call(_options__callbacks, buildContext);
1976
1993
  const generateTypes = hasTsConfig && options.dts !== false;
1977
1994
  const rollupJobsOptions = {
1978
1995
  isFromCli,
1979
1996
  generateTypes
1980
1997
  };
1981
1998
  const assetJobs = await createAssetRollupJobs(options, buildContext, rollupJobsOptions);
1982
- (_options__callbacks1 = options._callbacks) == null ? void 0 : (_options__callbacks_onBuildEnd = _options__callbacks1.onBuildEnd) == null ? void 0 : _options__callbacks_onBuildEnd.call(_options__callbacks1, assetJobs);
1999
+ (_options__callbacks1 = options._callbacks) == null ? undefined : (_options__callbacks_onBuildEnd = _options__callbacks1.onBuildEnd) == null ? undefined : _options__callbacks_onBuildEnd.call(_options__callbacks1, assetJobs);
1983
2000
  }
1984
2001
 
1985
2002
  exports.bundle = bundle;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "6.3.0",
3
+ "version": "6.3.2",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",
@@ -24,7 +24,8 @@
24
24
  ],
25
25
  "prettier": {
26
26
  "semi": false,
27
- "singleQuote": true
27
+ "singleQuote": true,
28
+ "trailingComma": "all"
28
29
  },
29
30
  "engines": {
30
31
  "node": ">= 18.0.0"
@@ -36,25 +37,25 @@
36
37
  },
37
38
  "license": "MIT",
38
39
  "dependencies": {
39
- "@rollup/plugin-commonjs": "^28.0.1",
40
+ "@rollup/plugin-commonjs": "^28.0.2",
40
41
  "@rollup/plugin-json": "^6.1.0",
41
- "@rollup/plugin-node-resolve": "^15.3.0",
42
- "@rollup/plugin-replace": "^6.0.1",
42
+ "@rollup/plugin-node-resolve": "^16.0.0",
43
+ "@rollup/plugin-replace": "^6.0.2",
43
44
  "@rollup/plugin-wasm": "^6.2.2",
44
45
  "@rollup/pluginutils": "^5.1.3",
45
- "@swc/core": "^1.9.3",
46
+ "@swc/core": "^1.10.7",
46
47
  "@swc/helpers": "^0.5.11",
47
48
  "clean-css": "^5.3.3",
48
- "glob": "^11.0.0",
49
- "magic-string": "^0.30.14",
49
+ "fast-glob": "^3.3.3",
50
+ "magic-string": "^0.30.17",
50
51
  "ora": "^8.0.1",
51
52
  "picomatch": "^4.0.2",
52
53
  "pretty-bytes": "^5.6.0",
53
- "rollup": "^4.27.4",
54
+ "rollup": "^4.30.1",
54
55
  "rollup-plugin-dts": "^6.1.1",
55
56
  "rollup-plugin-swc3": "^0.11.1",
56
57
  "rollup-preserve-directives": "^1.1.3",
57
- "tslib": "^2.7.0",
58
+ "tslib": "^2.8.1",
58
59
  "yargs": "^17.7.2"
59
60
  },
60
61
  "peerDependencies": {
@@ -71,8 +72,8 @@
71
72
  "devDependencies": {
72
73
  "@huozhi/testing-package": "1.0.0",
73
74
  "@swc-node/register": "^1.10.9",
74
- "@swc/jest": "^0.2.31",
75
- "@swc/types": "^0.1.9",
75
+ "@swc/jest": "^0.2.37",
76
+ "@swc/types": "^0.1.17",
76
77
  "@types/clean-css": "^4.2.11",
77
78
  "@types/jest": "29.0.0",
78
79
  "@types/node": "^22.9.3",
@@ -82,11 +83,11 @@
82
83
  "bunchee": "link:./",
83
84
  "cross-env": "^7.0.3",
84
85
  "husky": "^9.0.11",
85
- "jest": "29.0.1",
86
+ "jest": "29.7.0",
86
87
  "lint-staged": "^15.2.2",
87
88
  "next": "^15.0.4",
88
89
  "picocolors": "^1.0.0",
89
- "prettier": "^3.0.0",
90
+ "prettier": "2.8.8",
90
91
  "react": "^19.0.0",
91
92
  "react-dom": "^19.0.0",
92
93
  "typescript": "^5.7.2"