quickbundle 0.0.0-next-6c096f7 → 0.0.0-next-63542e6

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
@@ -10,12 +10,12 @@
10
10
 
11
11
  Quickbundle allows you to bundle a library in a **quick**, **fast** and **easy** way:
12
12
 
13
- - Fast build and watch mode powered by Rollup[^1] and SWC[^2].
14
- - Zero configuration: define the build artifacts in your `package.json`, and you're all set!
15
- - Support of `cjs` & `esm` module formats output.
16
- - Support of several loaders including JavaScript, TypeScript, JSX, JSON, and Images.
17
- - TypeScript's declaration file (`.d.ts`) bundling.
18
- - Automatic dependency inclusion (`peerDependencies` and `dependencies` are not bundled in the final output, `devDependencies` are unless they're not imported).
13
+ - Fast build and watch mode powered by Rollup[^1] and SWC[^2].
14
+ - Zero configuration: define the build artifacts in your `package.json`, and you're all set!
15
+ - Support of `cjs` & `esm` module formats output.
16
+ - Support of several loaders including JavaScript, TypeScript, JSX, JSON, and Images.
17
+ - TypeScript's declaration file (`.d.ts`) bundling.
18
+ - Automatic dependency inclusion (`peerDependencies` and `dependencies` are not bundled in the final output, `devDependencies` are unless they're not imported).
19
19
 
20
20
  [^1]: A [module bundler](https://rollupjs.org/) optimized for better tree-shaking processing and seamless interoperability of CommonJS and ESM formats with minimal code footprint.
21
21
 
@@ -38,7 +38,7 @@ yarn add quickbundle
38
38
 
39
39
  2️⃣ Set up your package configuration (`package.json`):
40
40
 
41
- - When exporting exclusively ESM format:
41
+ - When exporting exclusively ESM format:
42
42
 
43
43
  ```jsonc
44
44
  {
@@ -63,7 +63,7 @@ yarn add quickbundle
63
63
  }
64
64
  ```
65
65
 
66
- - When exporting both CommonJS (CJS) and ECMAScript Modules (ESM) format (please be aware of [dual package hazard risk](https://nodejs.org/api/packages.html#dual-package-hazard)):
66
+ - When exporting both CommonJS (CJS) and ECMAScript Modules (ESM) format (please be aware of [dual package hazard risk](https://nodejs.org/api/packages.html#dual-package-hazard)):
67
67
 
68
68
  ```jsonc
69
69
  {
@@ -109,14 +109,14 @@ yarn build
109
109
 
110
110
  By default, Quickbundle does the following built-in optimizations during the bundling process:
111
111
 
112
- - Include, in the build output, only the code that is effectively imported and used in the source code. Setting the `sideEffects` package.json field to `false` marks the package as a side-effect-free one and helps Quickbundle to safely prune unused exports.
113
- - [Identify and annotate](https://rollupjs.org/configuration-options/#treeshake-annotations) side-effect-free code (functions, ...) to enable a fine-grained dead-code elimination process later consumer side. For example, if a consumer uses only one library API, build output annotations added by Quickbundle allow the consumer's bundler remove all other unused APIs.
112
+ - Include, in the build output, only the code that is effectively imported and used in the source code. Setting the `sideEffects` package.json field to `false` marks the package as a side-effect-free one and helps Quickbundle to safely prune unused exports.
113
+ - [Identify and annotate](https://rollupjs.org/configuration-options/#treeshake-annotations) side-effect-free code (functions, ...) to enable a fine-grained dead-code elimination process later consumer side. For example, if a consumer uses only one library API, build output annotations added by Quickbundle allow the consumer's bundler remove all other unused APIs.
114
114
 
115
115
  However, Quickbundle doesn't minify the build output. Indeed, in general, **if the build targets a library (the most Quickbundle use case)**, minification is not necessary since enabling it can introduce some challenges:
116
116
 
117
- - Reduce the build output discoverability inside the `node_modules` folder (minified code is an obfuscated code that can be hard to read for code audit/debugging purposes).
118
- - Generate suboptimal source maps for the bundled library, as the consumer bundler will generate source maps based on the already minified library build (transformed code, mangled variable names, etc.).
119
- - Risk of side effects with double optimizations (producer side and then consumer side).
117
+ - Reduce the build output discoverability inside the `node_modules` folder (minified code is an obfuscated code that can be hard to read for code audit/debugging purposes).
118
+ - Generate suboptimal source maps for the bundled library, as the consumer bundler will generate source maps based on the already minified library build (transformed code, mangled variable names, etc.).
119
+ - Risk of side effects with double optimizations (producer side and then consumer side).
120
120
 
121
121
  Popular open source libraries ([Vue](https://unpkg.com/browse/vue@3.4.24/dist/), [SolidJS](https://unpkg.com/browse/solid-js@1.8.17/dist/), [Material UI](https://unpkg.com/browse/@material-ui/core@4.12.4/), ...) do not provide minified builds as the build optimization is sensitive to the consumer context (e.g. environment targets (browser support), ...) and needs to be fully owned upstream (i.e. consumer/application-side).
122
122
 
@@ -142,7 +142,7 @@ Enabling source map generation is needed only if a build is [obfuscated (minifie
142
142
 
143
143
  ## 🤩 Used by
144
144
 
145
- - [@adbayb/stack](https://github.com/adbayb/stack) My opinionated toolbox for JavaScript/TypeScript projects.
145
+ - [@adbayb/stack](https://github.com/adbayb/stack) My opinionated toolbox for JavaScript/TypeScript projects.
146
146
 
147
147
  <br>
148
148
 
@@ -154,8 +154,8 @@ We're open to new contributions, you can find more details [here](./CONTRIBUTING
154
154
 
155
155
  ## 💙 Acknowledgements
156
156
 
157
- - The backend is powered by [Rollup](https://github.com/rollup/rollup) and its plugin ecosystem (including [SWC](https://github.com/swc-project/swc)) to make blazing-fast builds. A special shoutout to all contributors involved.
158
- - The zero-configuration approach was inspired by [microbundle](https://github.com/developit/microbundle). A special shoutout to its author [Jason Miller](https://github.com/developit) and [all contributors](https://github.com/developit/microbundle/graphs/contributors).
157
+ - The backend is powered by [Rollup](https://github.com/rollup/rollup) and its plugin ecosystem (including [SWC](https://github.com/swc-project/swc)) to make blazing-fast builds. A special shoutout to all contributors involved.
158
+ - The zero-configuration approach was inspired by [microbundle](https://github.com/developit/microbundle). A special shoutout to its author [Jason Miller](https://github.com/developit) and [all contributors](https://github.com/developit/microbundle/graphs/contributors).
159
159
 
160
160
  <br>
161
161
 
package/bin/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { createRequire } from "node:module";
4
3
  import { join } from "node:path";
4
+ import { createRequire } from "node:module";
5
5
 
6
6
  const pkg = createRequire(import.meta.url)("../package.json");
7
7
 
package/dist/index.mjs CHANGED
@@ -1,17 +1,34 @@
1
- #!/usr/bin/env node
2
1
  import { helpers, termost } from 'termost';
3
- import { gzipSize } from 'gzip-size';
4
- import { rollup, watch as watch$1 } from 'rollup';
5
- import commonjs from '@rollup/plugin-commonjs';
6
- import json from '@rollup/plugin-json';
7
- import { nodeResolve } from '@rollup/plugin-node-resolve';
8
- import url from '@rollup/plugin-url';
9
- import { createRequire } from 'node:module';
2
+ import { readFile as readFile$1 } from 'node:fs/promises';
3
+ import process from 'node:process';
4
+ import { watch as watch$1, rollup } from 'rollup';
10
5
  import { join } from 'node:path';
11
- import dts from 'rollup-plugin-dts';
12
- import externals from 'rollup-plugin-node-externals';
6
+ import { createRequire } from 'node:module';
13
7
  import { swc } from 'rollup-plugin-swc3';
14
- import { readFile as readFile$1 } from 'node:fs/promises';
8
+ import externals from 'rollup-plugin-node-externals';
9
+ import dts from 'rollup-plugin-dts';
10
+ import url from '@rollup/plugin-url';
11
+ import { nodeResolve } from '@rollup/plugin-node-resolve';
12
+ import json from '@rollup/plugin-json';
13
+ import commonjs from '@rollup/plugin-commonjs';
14
+ import { gzipSize } from 'gzip-size';
15
+
16
+ const CWD = process.cwd();
17
+
18
+ const readFile = readFile$1;
19
+ const createCommand = (program, input)=>{
20
+ return program.command(input).option({
21
+ key: "minification",
22
+ name: "minification",
23
+ description: "Enable minification",
24
+ defaultValue: false
25
+ }).option({
26
+ key: "sourceMaps",
27
+ name: "source-maps",
28
+ description: "Enable source maps generation",
29
+ defaultValue: false
30
+ });
31
+ };
15
32
 
16
33
  const onLog = (_, log)=>{
17
34
  if (log.message.includes("Generated an empty chunk")) return;
@@ -20,41 +37,51 @@ const isRecord = (value)=>{
20
37
  return typeof value === "object" && value !== null && !Array.isArray(value);
21
38
  };
22
39
 
23
- const build = async (configurations)=>{
24
- process.env.NODE_ENV ??= "production";
25
- const output = [];
26
- for (const config of configurations){
27
- const initialTime = Date.now();
28
- const bundle = await rollup({
40
+ const watch = (configurations)=>{
41
+ process.env.NODE_ENV ??= "development";
42
+ const watcher = watch$1(configurations.map((config)=>({
29
43
  ...config,
30
44
  onLog
31
- });
32
- if (config.output) {
33
- const outputEntries = Array.isArray(config.output) ? config.output : [
34
- config.output
35
- ];
36
- const promises = [];
37
- for (const outputEntry of outputEntries){
38
- const outputFilename = outputEntry.file ?? outputEntry.dir;
39
- if (!outputFilename) {
40
- throw new Error("Misconfigured file entry point. Make sure to define an `import`, `require`, or `default` field.");
45
+ })));
46
+ let startDuration;
47
+ console.clear();
48
+ watcher.on("event", async (event)=>{
49
+ switch(event.code){
50
+ case "START":
51
+ {
52
+ startDuration = Date.now();
53
+ clearLog(`Build in progress...`, {
54
+ type: "information"
55
+ });
56
+ return;
57
+ }
58
+ case "BUNDLE_END":
59
+ await event.result.close();
60
+ break;
61
+ case "END":
62
+ {
63
+ const duration = Date.now() - startDuration;
64
+ clearLog(`Build done in ${duration}ms (at ${new Date().toLocaleTimeString()})`, {
65
+ type: "success"
66
+ });
67
+ return;
68
+ }
69
+ case "ERROR":
70
+ {
71
+ const { error } = event;
72
+ clearLog(error.message, {
73
+ type: "error"
74
+ });
75
+ console.error("\n", error);
76
+ return;
41
77
  }
42
- promises.push(new Promise((resolve, reject)=>{
43
- bundle.write(outputEntry).then(()=>{
44
- resolve({
45
- elapsedTime: Date.now() - initialTime,
46
- filename: outputFilename
47
- });
48
- }).catch(reject);
49
- }));
50
- }
51
- output.push(...await Promise.all(promises));
52
78
  }
53
- }
54
- return output;
79
+ });
80
+ };
81
+ const clearLog = (...input)=>{
82
+ console.clear();
83
+ helpers.message(...input);
55
84
  };
56
-
57
- const CWD = process.cwd();
58
85
 
59
86
  const require = createRequire(import.meta.url);
60
87
  const PKG = require(join(CWD, "./package.json"));
@@ -218,24 +245,59 @@ const createTypesConfig = (entryPoints)=>{
218
245
  }))
219
246
  };
220
247
  };
221
- // eslint-disable-next-line import/no-default-export
222
248
  createConfigurations();
223
249
 
224
- const readFile = readFile$1;
225
- const createCommand = (program, input)=>{
226
- return program.command(input).option({
227
- key: "minification",
228
- name: "minification",
229
- description: "Enable minification",
230
- defaultValue: false
231
- }).option({
232
- key: "sourceMaps",
233
- name: "source-maps",
234
- description: "Enable source maps generation",
235
- defaultValue: false
250
+ const createWatchCommand = (program)=>{
251
+ return createCommand(program, {
252
+ name: "watch",
253
+ description: "Watch and rebuild on any code change (development mode)"
254
+ }).task({
255
+ handler (context) {
256
+ watch(createConfigurations({
257
+ minification: context.minification,
258
+ sourceMaps: context.sourceMaps,
259
+ standalone: false
260
+ }));
261
+ }
236
262
  });
237
263
  };
238
264
 
265
+ const build = async (configurations)=>{
266
+ process.env.NODE_ENV ??= "production";
267
+ const output = [];
268
+ for (const config of configurations){
269
+ const initialTime = Date.now();
270
+ const bundle = await rollup({
271
+ ...config,
272
+ onLog
273
+ });
274
+ if (config.output) {
275
+ const outputEntries = Array.isArray(config.output) ? config.output : [
276
+ config.output
277
+ ];
278
+ const promises = [];
279
+ for (const outputEntry of outputEntries){
280
+ const outputFilename = outputEntry.file ?? outputEntry.dir;
281
+ if (!outputFilename) {
282
+ throw new Error("Misconfigured file entry point. Make sure to define an `import`, `require`, or `default` field.");
283
+ }
284
+ promises.push(new Promise((resolve, reject)=>{
285
+ bundle.write(outputEntry).then(()=>{
286
+ resolve({
287
+ elapsedTime: Date.now() - initialTime,
288
+ filename: outputFilename
289
+ });
290
+ }).catch((reason)=>{
291
+ reject(reason);
292
+ });
293
+ }));
294
+ }
295
+ output.push(...await Promise.all(promises));
296
+ }
297
+ }
298
+ return output;
299
+ };
300
+
239
301
  const createBuildCommand = (program)=>{
240
302
  return createCommand(program, {
241
303
  name: "build",
@@ -295,67 +357,6 @@ const formatSize = (bytes)=>{
295
357
  return kiloBytes < 1 ? `${bytes} B` : `${kiloBytes.toFixed(2)} kB`;
296
358
  };
297
359
 
298
- const watch = (configurations)=>{
299
- process.env.NODE_ENV ??= "development";
300
- const watcher = watch$1(configurations.map((config)=>({
301
- ...config,
302
- onLog
303
- })));
304
- let startDuration;
305
- console.clear();
306
- watcher.on("event", async (event)=>{
307
- switch(event.code){
308
- case "START":
309
- {
310
- startDuration = Date.now();
311
- clearLog(`Build in progress...`, {
312
- type: "information"
313
- });
314
- return;
315
- }
316
- case "BUNDLE_END":
317
- await event.result.close();
318
- break;
319
- case "END":
320
- {
321
- const duration = Date.now() - startDuration;
322
- clearLog(`Build done in ${duration}ms (at ${new Date().toLocaleTimeString()})`, {
323
- type: "success"
324
- });
325
- return;
326
- }
327
- case "ERROR":
328
- {
329
- const { error } = event;
330
- clearLog(`${String(error)}`, {
331
- type: "error"
332
- });
333
- console.error("\n", error);
334
- return;
335
- }
336
- }
337
- });
338
- };
339
- const clearLog = (...input)=>{
340
- console.clear();
341
- helpers.message(...input);
342
- };
343
-
344
- const createWatchCommand = (program)=>{
345
- return createCommand(program, {
346
- name: "watch",
347
- description: "Watch and rebuild on any code change (development mode)"
348
- }).task({
349
- handler (context) {
350
- watch(createConfigurations({
351
- minification: context.minification,
352
- sourceMaps: context.sourceMaps,
353
- standalone: false
354
- }));
355
- }
356
- });
357
- };
358
-
359
360
  const createProgram = (...commandBuilders)=>{
360
361
  const program = termost("The zero-configuration transpiler and bundler for the web");
361
362
  for (const commandBuilder of commandBuilders){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quickbundle",
3
- "version": "0.0.0-next-6c096f7",
3
+ "version": "0.0.0-next-63542e6",
4
4
  "description": "The zero-configuration transpiler and bundler for the web",
5
5
  "author": {
6
6
  "name": "Ayoub Adib",
@@ -40,7 +40,7 @@
40
40
  }
41
41
  },
42
42
  "peerDependencies": {
43
- "typescript": ">=4.7.0"
43
+ "typescript": "^4.7.0 || ^5.0.0"
44
44
  },
45
45
  "peerDependenciesMeta": {
46
46
  "typescript": {