@hypernym/bundler 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -105,32 +105,32 @@ npx hyperbundler --config hyper.config.ts
105
105
 
106
106
  ## Formats
107
107
 
108
- During transformation, file formats are automatically resolved and in most cases there is no need for additional configuration.
108
+ During transformation, file formats are automatically resolved, and in most cases, no additional configuration is required.
109
109
 
110
- `Hyperbundler` module environment for generated files defaults to `esm`, which means the outputs will have a `.mjs` extension unless otherwise specified. For TypeScript declarations, the appropriate extension will be `.d.mts`.
110
+ The default module environment for generated files is `esm`, which means output files will have a `.mjs` extension unless otherwise specified. For TypeScript declarations, the corresponding extension will be `.d.mts`.
111
111
 
112
- Formats can also be explicitly specified for each entry, if necessary.
112
+ Formats can also be explicitly specified for each entry, if needed.
113
113
 
114
114
  ### Inputs
115
115
 
116
- Default transformation behaviour for all `chunk` entries:
116
+ Default transformation behavior for all `chunk` entries:
117
117
 
118
- - `./srcDir/file.js` resolves to `./outDir/file.mjs`
119
- - `./srcDir/file.mjs` resolves to `./outDir/file.mjs`
120
- - `./srcDir/file.cjs` resolves to `./outDir/file.cjs`
121
- - `./srcDir/file.ts` resolves to `./outDir/file.mjs`
122
- - `./srcDir/file.mts` resolves to `./outDir/file.mjs`
123
- - `./srcDir/file.cts` resolves to `./outDir/file.cjs`
118
+ - `./srcDir/file.js` `./outDir/file.mjs`
119
+ - `./srcDir/file.mjs` `./outDir/file.mjs`
120
+ - `./srcDir/file.cjs` `./outDir/file.cjs`
121
+ - `./srcDir/file.ts` `./outDir/file.mjs`
122
+ - `./srcDir/file.mts` `./outDir/file.mjs`
123
+ - `./srcDir/file.cts` `./outDir/file.cjs`
124
124
 
125
125
  ### Declarations
126
126
 
127
- Default transformation behaviour for all `dts` entries:
127
+ Default transformation behavior for all `dts` entries:
128
128
 
129
- - `./srcDir/file.ts` resolves to `./outDir/file.d.mts`
129
+ - `./srcDir/file.ts` `./outDir/file.d.mts`
130
130
 
131
131
  ## Options
132
132
 
133
- All options are documented with descriptions and examples so autocompletion will be offered as you type. Simply hover over the property and see what it does in the quick info tooltip.
133
+ All options come with descriptions and examples. As you type, you’ll get suggestions and can see quick info by hovering over any property.
134
134
 
135
135
  ### entries
136
136
 
@@ -247,7 +247,7 @@ export default defineConfig({
247
247
 
248
248
  ### outDir
249
249
 
250
- - Type: `string`
250
+ - Type: `string | undefined`
251
251
  - Default: `dist`
252
252
 
253
253
  Specifies the output directory for production bundle.
@@ -258,14 +258,14 @@ Specifies the output directory for production bundle.
258
258
  import { defineConfig } from '@hypernym/bundler'
259
259
 
260
260
  export default defineConfig({
261
- outDir: 'output',
261
+ outDir: './output',
262
262
  })
263
263
  ```
264
264
 
265
265
  ### externals
266
266
 
267
- - Type: `(string | RegExp)[]`
268
- - Default: `[/^node:/, /^@types/, /^@rollup/, /^@hypernym/, /^rollup/, ...pkg.dependencies]`
267
+ - Type: `(string | RegExp)[] | undefined`
268
+ - Default: `[/^node:/, /^@types/, /^@rollup/, /^@rolldown/, /^@hypernym/, /^rollup/, /^rolldown/, ...pkg.dependencies]`
269
269
 
270
270
  Specifies the module IDs or regular expressions that match module IDs to be treated as external and excluded from the bundle.
271
271
 
@@ -296,10 +296,15 @@ export default defineConfig({
296
296
 
297
297
  ### minify
298
298
 
299
- - Type: `boolean`
299
+ - Type: `boolean | 'dce-only' | MinifyOptions | undefined`
300
300
  - Default: `undefined`
301
301
 
302
- Specifies the minification for all `chunk` entries.
302
+ Controls code minification for all `chunk` entries.
303
+
304
+ - `true`: Enable full minification including code compression and dead code elimination.
305
+ - `false`: Disable minification (default).
306
+ - `'dce-only'`: Only perform dead code elimination without code compression.
307
+ - `MinifyOptions`: Fine-grained control over minification settings.
303
308
 
304
309
  ```ts
305
310
  // bundler.config.ts
@@ -339,7 +344,7 @@ List of lifecycle hooks that are called at various phases:
339
344
 
340
345
  ### bundle:start
341
346
 
342
- - Type: `(options: Options) => void | Promise<void>`
347
+ - Type: `(options: Options) => void | Promise<void> | undefined`
343
348
  - Default: `undefined`
344
349
 
345
350
  Called at the beginning of bundling.
@@ -360,7 +365,7 @@ export default defineConfig({
360
365
 
361
366
  ### build:start
362
367
 
363
- - Type: `(options: Options, stats: BuildStats) => void | Promise<void>`
368
+ - Type: `(options: Options, stats: BuildStats) => void | Promise<void> | undefined`
364
369
  - Default: `undefined`
365
370
 
366
371
  Called at the beginning of building.
@@ -381,7 +386,7 @@ export default defineConfig({
381
386
 
382
387
  ### build:entry:start
383
388
 
384
- - Type: `(entry: BuildEntryOptions, stats: BuildEntryStats) => void | Promise<void>`
389
+ - Type: `(entry: BuildEntryOptions, stats: BuildEntryStats) => void | Promise<void> | undefined`
385
390
  - Default: `undefined`
386
391
 
387
392
  Called on each entry just before the build process.
@@ -405,7 +410,7 @@ export default defineConfig({
405
410
 
406
411
  ### build:entry:end
407
412
 
408
- - Type: `(entry: BuildEntryOptions, stats: BuildEntryStats) => void | Promise<void>`
413
+ - Type: `(entry: BuildEntryOptions, stats: BuildEntryStats) => void | Promise<void> | undefined`
409
414
  - Default: `undefined`
410
415
 
411
416
  Called on each entry right after the build process is completed.
@@ -426,7 +431,7 @@ export default defineConfig({
426
431
 
427
432
  ### build:end
428
433
 
429
- - Type: `(options: Options, stats: BuildStats) => void | Promise<void>`
434
+ - Type: `(options: Options, stats: BuildStats) => void | Promise<void> | undefined`
430
435
  - Default: `undefined`
431
436
 
432
437
  Called right after building is complete.
@@ -447,7 +452,7 @@ export default defineConfig({
447
452
 
448
453
  ### bundle:end
449
454
 
450
- - Type: `(options: Options) => void | Promise<void>`
455
+ - Type: `(options: Options) => void | Promise<void> | undefined`
451
456
  - Default: `undefined`
452
457
 
453
458
  Called right after bundling is complete.
@@ -9,7 +9,7 @@ import { build as build$1 } from "../build/index.mjs";
9
9
 
10
10
  //#region src/bin/meta.ts
11
11
  const name = `Hyperbundler`;
12
- const version = `0.20.0`;
12
+ const version = `0.21.0`;
13
13
 
14
14
  //#endregion
15
15
  //#region src/utils/logger.ts
@@ -114,7 +114,7 @@ async function loadConfig(filePath, defaults) {
114
114
  input: resolve(cwd$1, filePath),
115
115
  write: false,
116
116
  external: (id) => !(isAbsolute(id) || /^(\.|@\/|~\/)/.test(id)),
117
- resolve: { tsconfigFilename: defaults.tsconfig },
117
+ tsconfig: defaults.tsconfig,
118
118
  output: { format: "esm" }
119
119
  });
120
120
  const tempConfig = resolve(cwd$1, "node_modules/.hypernym/bundler/config.mjs");
@@ -92,6 +92,11 @@ function getOutputPath(outDir, input, { extension = "auto" } = {}) {
92
92
  }
93
93
  return outDir.startsWith("./") || outDir.startsWith("../") ? output : `./${output}`;
94
94
  }
95
+ function parseOutputPath(path) {
96
+ if (!path) return;
97
+ if (path.startsWith("./")) return path;
98
+ else return `./${path}`;
99
+ }
95
100
 
96
101
  //#endregion
97
102
  //#region src/bin/build.ts
@@ -109,7 +114,7 @@ function logEntryStats(stats) {
109
114
  if (stats.logs) for (const log of stats.logs) cl$1("!", log.level.padEnd(5), output.padEnd(outputLength), dim(log.log.message));
110
115
  }
111
116
  async function build(options) {
112
- const { cwd: cwdir = cwd(), outDir = "dist", tsconfig, hooks } = options;
117
+ const { cwd: cwdir = cwd(), outDir = "dist", entries, externals, tsconfig, hooks, minify } = options;
113
118
  let start = 0;
114
119
  const buildStats = {
115
120
  cwd: cwdir,
@@ -118,164 +123,100 @@ async function build(options) {
118
123
  files: []
119
124
  };
120
125
  await hooks?.["build:start"]?.(options, buildStats);
121
- if (options.entries) {
126
+ if (entries) {
122
127
  start = Date.now();
123
- for (const entry of options.entries) {
128
+ for (const entry of entries) {
124
129
  const entryStart = Date.now();
125
- if (entry.input) {
130
+ if (entry.input || entry.dts) {
126
131
  const buildLogs = [];
127
- const _output = entry.output || getOutputPath(outDir, entry.input);
132
+ const isChunk = !isUndefined(entry.input);
133
+ const outputRawPath = parseOutputPath(entry.output) || getOutputPath(outDir, entry.input || entry.dts, { extension: isChunk ? "auto" : "dts" });
134
+ const outputResolvePath = resolve(cwdir, outputRawPath);
128
135
  let format = entry.format || "esm";
129
- if (_output.endsWith(".cjs")) format = "cjs";
130
- const _entry = {
131
- ...entry,
132
- input: entry.input,
133
- output: _output,
134
- format,
135
- externals: entry.externals || options.externals,
136
- minify: !isUndefined(entry.minify) ? entry.minify : options.minify
137
- };
138
- const input = resolve(cwdir, _entry.input);
139
- const output = resolve(cwdir, _entry.output);
140
- const entryStats = {
141
- cwd: cwdir,
142
- path: _entry.output,
143
- size: 0,
144
- buildTime: entryStart,
145
- format,
146
- logs: buildLogs
147
- };
148
- await hooks?.["build:entry:start"]?.(_entry, entryStats);
149
- const bundle = await rolldown({
150
- input,
151
- external: _entry.externals,
152
- plugins: _entry.plugins,
136
+ if (outputRawPath.endsWith(".cjs")) format = "cjs";
137
+ const entryInput = {
138
+ input: resolve(cwdir, entry.input || entry.dts),
139
+ external: entry.externals || externals,
140
+ plugins: isChunk ? entry.plugins : entry.plugins || [dts({
141
+ ...entry.dtsPlugin,
142
+ emitDtsOnly: true
143
+ })],
153
144
  onLog: (level, log, handler) => {
154
- if (_entry.onLog) _entry.onLog(level, log, handler, buildLogs);
145
+ if (entry.onLog) entry.onLog(level, log, handler, buildLogs);
155
146
  else buildLogs.push({
156
147
  level,
157
148
  log
158
149
  });
159
150
  },
160
- resolve: {
161
- ..._entry.resolve,
162
- tsconfigFilename: _entry.resolve?.tsconfigFilename || tsconfig
163
- },
164
- define: _entry.define
165
- });
166
- await bundle.write({
167
- file: output,
168
- minify: _entry.minify,
169
- format: _entry.format,
170
- banner: _entry.banner,
171
- footer: _entry.footer,
172
- intro: _entry.intro,
173
- outro: _entry.outro,
174
- name: _entry.name,
175
- globals: _entry.globals,
176
- extend: _entry.extend,
177
- plugins: _entry.paths ? [outputPaths(_entry.paths)] : void 0
178
- });
179
- const stats = await stat(output);
180
- entryStats.size = stats.size;
181
- entryStats.buildTime = Date.now() - entryStart;
182
- entryStats.logs = buildLogs;
183
- buildStats.files.push(entryStats);
184
- buildStats.size = buildStats.size + stats.size;
185
- logEntryStats(entryStats);
186
- await hooks?.["build:entry:end"]?.(_entry, entryStats);
187
- }
188
- if (entry.dts) {
189
- const buildLogs = [];
190
- const _entry = {
191
- ...entry,
192
- output: entry.output || getOutputPath(outDir, entry.dts, { extension: "dts" }),
193
- externals: entry.externals || options.externals,
194
- format: entry.format || "esm",
195
- plugins: [dts({
196
- ...entry.dtsPlugin,
197
- emitDtsOnly: true
198
- })]
151
+ resolve: entry.resolve,
152
+ define: entry.define,
153
+ inject: entry.inject,
154
+ tsconfig: entry.tsconfig || tsconfig
155
+ };
156
+ const entryOutput = {
157
+ file: isChunk ? outputResolvePath : void 0,
158
+ minify: isChunk ? !isUndefined(entry.minify) ? entry.minify : minify : void 0,
159
+ format,
160
+ banner: entry.banner,
161
+ footer: entry.footer,
162
+ intro: entry.intro,
163
+ outro: entry.outro,
164
+ name: entry.name,
165
+ globals: entry.globals,
166
+ extend: entry.extend,
167
+ plugins: entry.paths ? [outputPaths(entry.paths)] : void 0
168
+ };
169
+ const entryOptions = {
170
+ ...entryInput,
171
+ ...entryOutput,
172
+ externals: entryInput.external
199
173
  };
200
- const input = resolve(cwdir, _entry.dts);
201
- const output = resolve(cwdir, _entry.output);
202
174
  const entryStats = {
203
175
  cwd: cwdir,
204
- path: _entry.output,
176
+ path: outputRawPath,
205
177
  size: 0,
206
178
  buildTime: entryStart,
207
- format: "dts",
179
+ format: isChunk ? format : "dts",
208
180
  logs: buildLogs
209
181
  };
210
- await hooks?.["build:entry:start"]?.(_entry, entryStats);
211
- const bundle = await rolldown({
212
- input,
213
- external: _entry.externals,
214
- plugins: _entry.plugins,
215
- onLog: (level, log, handler) => {
216
- if (_entry.onLog) _entry.onLog(level, log, handler, buildLogs);
217
- else buildLogs.push({
218
- level,
219
- log
220
- });
221
- },
222
- resolve: {
223
- ..._entry.resolve,
224
- tsconfigFilename: _entry.resolve?.tsconfigFilename || tsconfig
225
- },
226
- define: _entry.define
227
- });
228
- const generated = await bundle.generate({
229
- format: _entry.format,
230
- banner: _entry.banner,
231
- footer: _entry.footer,
232
- intro: _entry.intro,
233
- outro: _entry.outro,
234
- name: _entry.name,
235
- globals: _entry.globals,
236
- extend: _entry.extend,
237
- plugins: _entry.paths ? [outputPaths(_entry.paths)] : void 0
238
- });
239
- await write(_entry.output, generated.output[0].code);
240
- const stats = await stat(output);
182
+ await hooks?.["build:entry:start"]?.(entryOptions, entryStats);
183
+ const bundle = await rolldown(entryInput);
184
+ if (isChunk) await bundle.write(entryOutput);
185
+ else {
186
+ const generated = await bundle.generate(entryOutput);
187
+ await write(outputResolvePath, generated.output[0].code);
188
+ }
189
+ const stats = await stat(outputResolvePath);
241
190
  entryStats.size = stats.size;
242
191
  entryStats.buildTime = Date.now() - entryStart;
243
192
  entryStats.logs = buildLogs;
244
193
  buildStats.files.push(entryStats);
245
194
  buildStats.size = buildStats.size + stats.size;
246
195
  logEntryStats(entryStats);
247
- await hooks?.["build:entry:end"]?.(_entry, entryStats);
196
+ await hooks?.["build:entry:end"]?.(entryOptions, entryStats);
248
197
  }
249
198
  if (entry.copy) {
250
- const outputPath = getOutputPath(outDir, entry.copy, { extension: "original" });
251
- const _entry = {
252
- input: entry.copy,
253
- output: entry.output || outputPath
254
- };
255
- const input = resolve(cwdir, _entry.input);
256
- const output = resolve(cwdir, _entry.output);
257
- await copy(input, output, {
199
+ const inputResolvePath = resolve(cwdir, entry.copy);
200
+ const outputRawPath = parseOutputPath(entry.output) || getOutputPath(outDir, entry.copy, { extension: "original" });
201
+ const outputResolvePath = resolve(cwdir, outputRawPath);
202
+ await copy(inputResolvePath, outputResolvePath, {
258
203
  recursive: entry.recursive || true,
259
204
  filter: entry.filter
260
205
  }).catch(error);
261
- const stats = await stat(output);
206
+ const stats = await stat(outputResolvePath);
262
207
  let totalSize = 0;
263
208
  if (!stats.isDirectory()) totalSize = stats.size;
264
209
  else {
265
- const files = await readdir(output);
210
+ const files = await readdir(outputResolvePath);
266
211
  for (const file of files) {
267
- const filePath = resolve(output, file);
212
+ const filePath = resolve(outputResolvePath, file);
268
213
  const fileStat = await stat(filePath);
269
214
  totalSize = totalSize + fileStat.size;
270
215
  }
271
216
  }
272
- const parseOutput = (path) => {
273
- if (path.startsWith("./")) return path;
274
- else return `./${path}`;
275
- };
276
217
  const entryStats = {
277
218
  cwd: cwdir,
278
- path: parseOutput(_entry.output),
219
+ path: outputRawPath,
279
220
  size: totalSize,
280
221
  buildTime: Date.now() - entryStart,
281
222
  format: "copy",
@@ -286,11 +227,13 @@ async function build(options) {
286
227
  logEntryStats(entryStats);
287
228
  }
288
229
  if (entry.template && entry.output) {
289
- await write(entry.output, entry.template);
290
- const stats = await stat(resolve(cwdir, entry.output));
230
+ const outputRawPath = parseOutputPath(entry.output);
231
+ const outputResolvePath = resolve(cwdir, outputRawPath);
232
+ await write(outputResolvePath, entry.template);
233
+ const stats = await stat(outputResolvePath);
291
234
  const entryStats = {
292
235
  cwd: cwdir,
293
- path: entry.output,
236
+ path: outputRawPath,
294
237
  size: stats.size,
295
238
  buildTime: Date.now() - entryStart,
296
239
  format: "tmp",
package/dist/index.d.mts CHANGED
@@ -138,12 +138,26 @@ interface EntryBase {
138
138
  * @default undefined
139
139
  */
140
140
  define?: InputOptions['define'];
141
+ /**
142
+ * Specifies Rolldown `inject` options.
143
+ *
144
+ * @default undefined
145
+ */
146
+ inject?: InputOptions['inject'];
141
147
  /**
142
148
  * Specifies Rolldown plugins.
143
149
  *
144
150
  * @default undefined
145
151
  */
146
152
  plugins?: RolldownPluginOption;
153
+ /**
154
+ * Specifies the path to the `tsconfig` file.
155
+ *
156
+ * By default, if the file `tsconfig.json` exists in the project root, it will be used as the default config file.
157
+ *
158
+ * @default undefined
159
+ */
160
+ tsconfig?: InputOptions['tsconfig'];
147
161
  }
148
162
  interface EntryChunk extends EntryBase {
149
163
  /**
@@ -202,11 +216,16 @@ interface EntryChunk extends EntryBase {
202
216
  */
203
217
  extend?: OutputOptions['extend'];
204
218
  /**
205
- * Minifies the generated code if enabled.
219
+ * Controls code minification.
220
+ *
221
+ * - `true`: Enable full minification including code compression and dead code elimination.
222
+ * - `false`: Disable minification (default).
223
+ * - `'dce-only'`: Only perform dead code elimination without code compression.
224
+ * - `MinifyOptions`: Fine-grained control over minification settings.
206
225
  *
207
226
  * @default undefined
208
227
  */
209
- minify?: boolean;
228
+ minify?: OutputOptions['minify'];
210
229
  dts?: never;
211
230
  dtsPlugin?: never;
212
231
  copy?: never;
@@ -387,7 +406,7 @@ interface Options {
387
406
  *
388
407
  * ```ts
389
408
  * export default defineConfig({
390
- * outDir: 'output',
409
+ * outDir: './output',
391
410
  * })
392
411
  * ```
393
412
  *
@@ -432,7 +451,12 @@ interface Options {
432
451
  */
433
452
  hooks?: HooksOptions;
434
453
  /**
435
- * Specifies the minification for all `chunk` entries.
454
+ * Controls code minification for all `chunk` entries.
455
+ *
456
+ * - `true`: Enable full minification including code compression and dead code elimination.
457
+ * - `false`: Disable minification (default).
458
+ * - `'dce-only'`: Only perform dead code elimination without code compression.
459
+ * - `MinifyOptions`: Fine-grained control over minification settings.
436
460
  *
437
461
  * @example
438
462
  *
@@ -457,7 +481,7 @@ interface Options {
457
481
  *
458
482
  * @default undefined
459
483
  */
460
- minify?: boolean;
484
+ minify?: OutputOptions['minify'];
461
485
  /**
462
486
  * Specifies the path to the project root (current working directory).
463
487
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypernym/bundler",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "author": "Hypernym Studio",
5
5
  "description": "ESM & TS module bundler.",
6
6
  "license": "MIT",
@@ -58,8 +58,8 @@
58
58
  "@hypernym/args": "^0.3.3",
59
59
  "@hypernym/colors": "^1.0.5",
60
60
  "@hypernym/utils": "^3.4.5",
61
- "rolldown": "1.0.0-beta.32",
62
- "rolldown-plugin-dts": "^0.15.7"
61
+ "rolldown": "^1.0.0-beta.34",
62
+ "rolldown-plugin-dts": "^0.15.9"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@hypernym/eslint-config": "^3.6.3",