quickbundle 2.3.0 → 2.4.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 +12 -12
- package/dist/index.js +53 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,20 +34,18 @@ yarn add quickbundle
|
|
|
34
34
|
|
|
35
35
|
2️⃣ Set up your package configuration (`package.json`):
|
|
36
36
|
|
|
37
|
-
- When exporting
|
|
37
|
+
- When exporting exclusively ESM format:
|
|
38
38
|
|
|
39
39
|
```jsonc
|
|
40
40
|
{
|
|
41
41
|
"name": "lib", // Package name
|
|
42
42
|
"exports": {
|
|
43
43
|
".": {
|
|
44
|
-
"source": "src/index.ts(x)?", // Source code
|
|
45
|
-
"types": "./dist/index.d.ts", // Typing output file (if defined, can increase build time)
|
|
46
|
-
"
|
|
47
|
-
"require": "./dist/index.cjs", // CommonJS output file (matches when the module is loaded via require() consumer side)
|
|
48
|
-
"default": "./dist/index.mjs", // The generic fallback that always matches (this condition should always come last). By default, Quickbundle will always output ESM format for the `default` field. However, take care: if both `import` and `default` fields are defined, provide the same file path, as the `import` field export instruction will be the only one considered to define the output file path.
|
|
44
|
+
"source": "src/index.ts(x)?", // Source code entry point.
|
|
45
|
+
"types": "./dist/index.d.ts", // Typing output file (if defined, can increase build time). This condition should always come first after the custom `source` field definition.
|
|
46
|
+
"default": "./dist/index.mjs", // By default, Quickbundle will always output ESM format for the `default` field (this condition should always come last since it always matches as a generic fallback). However, take care: if both `import` and `default` fields are defined, provide the same file path, as the `import` field export instruction will be the only one considered to define the output file path.
|
|
49
47
|
},
|
|
50
|
-
"./
|
|
48
|
+
"./otherModulePath": {
|
|
51
49
|
// ...
|
|
52
50
|
}
|
|
53
51
|
}
|
|
@@ -59,18 +57,20 @@ yarn add quickbundle
|
|
|
59
57
|
}
|
|
60
58
|
```
|
|
61
59
|
|
|
62
|
-
- When exporting
|
|
60
|
+
- 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)):
|
|
63
61
|
|
|
64
62
|
```jsonc
|
|
65
63
|
{
|
|
66
64
|
"name": "lib", // Package name
|
|
67
65
|
"exports": {
|
|
68
66
|
".": {
|
|
69
|
-
"source": "src/index.ts(x)?", // Source code
|
|
70
|
-
"types": "./dist/index.d.ts", // Typing output file (if defined, can increase build time)
|
|
71
|
-
"
|
|
67
|
+
"source": "src/index.ts(x)?", // Source code entry point.
|
|
68
|
+
"types": "./dist/index.d.ts", // // Typing output file (if defined, can increase build time). This condition should always come first after the custom `source` field definition.
|
|
69
|
+
"require": "./dist/index.cjs", // CommonJS output file (matches when the module is loaded via require() consumer side).
|
|
70
|
+
"import": "./dist/index.mjs", // ESM output file (matches when the package is loaded via import or import() consumer side).
|
|
71
|
+
"default": "./dist/index.mjs", // By default, Quickbundle will always output ESM format for the `default` field (this condition should always come last since it always matches as a generic fallback). However, take care: if both `import` and `default` fields are defined, provide the same file path, as the `import` field export instruction will be the only one considered to define the output file path.
|
|
72
72
|
},
|
|
73
|
-
"./
|
|
73
|
+
"./otherModulePath": {
|
|
74
74
|
// ...
|
|
75
75
|
}
|
|
76
76
|
}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,9 @@ import { readFile as readFile$1 } from 'node:fs/promises';
|
|
|
16
16
|
const onLog = (_, log)=>{
|
|
17
17
|
if (log.message.includes("Generated an empty chunk")) return;
|
|
18
18
|
};
|
|
19
|
+
const isRecord = (value)=>{
|
|
20
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21
|
+
};
|
|
19
22
|
|
|
20
23
|
const build = async (configurations)=>{
|
|
21
24
|
var _process_env;
|
|
@@ -60,6 +63,20 @@ const createConfigurations = (options = {
|
|
|
60
63
|
minification: false,
|
|
61
64
|
sourceMaps: false
|
|
62
65
|
})=>{
|
|
66
|
+
return getBuildableExports().flatMap((buildableExport)=>{
|
|
67
|
+
return [
|
|
68
|
+
buildableExport.source && createMainConfig({
|
|
69
|
+
...buildableExport,
|
|
70
|
+
source: buildableExport.source
|
|
71
|
+
}, options),
|
|
72
|
+
buildableExport.source && buildableExport.types && createTypesConfig({
|
|
73
|
+
source: buildableExport.source,
|
|
74
|
+
types: buildableExport.types
|
|
75
|
+
})
|
|
76
|
+
].filter(Boolean);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const getBuildableExports = ()=>{
|
|
63
80
|
/**
|
|
64
81
|
* Entry-point resolution:
|
|
65
82
|
* Following the [package entry-point specification](https://nodejs.org/api/packages.html#package-entry-points),
|
|
@@ -68,34 +85,49 @@ const createConfigurations = (options = {
|
|
|
68
85
|
*/ if (PKG.main ?? PKG.module ?? PKG.types ?? !PKG.exports) {
|
|
69
86
|
throw new Error("Invalid package entry points contract. Use the recommended [`exports` field](https://nodejs.org/api/packages.html#package-entry-points) instead and, for TypeScript-based projects, update the `tsconfig.json` file to resolve it properly (`moduleResolution` must be set to `Bundler` (or `NodeNext`)).");
|
|
70
87
|
}
|
|
71
|
-
const
|
|
88
|
+
const buildableExportFields = [
|
|
72
89
|
"default",
|
|
73
90
|
"import",
|
|
74
91
|
"require",
|
|
75
92
|
"types"
|
|
76
93
|
];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
let singleExport = undefined;
|
|
95
|
+
const output = Object.entries(PKG.exports).map(([field, value])=>{
|
|
96
|
+
if (isRecord(value)) {
|
|
97
|
+
return [
|
|
98
|
+
field,
|
|
99
|
+
value
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
if ([
|
|
103
|
+
"source",
|
|
104
|
+
...buildableExportFields
|
|
105
|
+
].includes(field)) {
|
|
106
|
+
if (!singleExport) {
|
|
107
|
+
singleExport = {};
|
|
108
|
+
singleExport[field] = value;
|
|
109
|
+
return [
|
|
110
|
+
".",
|
|
111
|
+
singleExport
|
|
112
|
+
];
|
|
84
113
|
}
|
|
114
|
+
singleExport[field] = value;
|
|
85
115
|
}
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
return undefined;
|
|
117
|
+
}).reduce((buildableExports, currentExport)=>{
|
|
118
|
+
if (!currentExport) return buildableExports;
|
|
119
|
+
const [exportField, exportValue] = currentExport;
|
|
120
|
+
const conditionalExportFields = Object.keys(exportValue);
|
|
121
|
+
if (!conditionalExportFields.includes("source")) return buildableExports;
|
|
122
|
+
const hasAtLeastOneRequiredField = buildableExportFields.some((entryPointField)=>conditionalExportFields.includes(entryPointField));
|
|
123
|
+
if (hasAtLeastOneRequiredField) {
|
|
124
|
+
buildableExports.push(exportValue);
|
|
125
|
+
return buildableExports;
|
|
126
|
+
}
|
|
127
|
+
throw new Error(`A \`source\` field is defined without an output defined for the \`${exportField}\` export. Make sure to define at least one conditional entry point (including ${buildableExportFields.map((field)=>`\`${field}\``).join(", ")})`);
|
|
128
|
+
}, []);
|
|
97
129
|
if (output.length === 0) {
|
|
98
|
-
throw new Error("No `source` field is set for the targeted package. If a build step is necessary, make sure to configure at least one `source` field in the package `exports` contract.");
|
|
130
|
+
throw new Error("No `source` field is set for the targeted package. If a build step is necessary, make sure to configure at least one `source` field in the package `exports` contract. If not, do not execute quickbundle on this package.");
|
|
99
131
|
}
|
|
100
132
|
return output;
|
|
101
133
|
};
|
|
@@ -130,7 +162,7 @@ const createMainConfig = (entryPoints, options)=>{
|
|
|
130
162
|
const { minification, sourceMaps } = options;
|
|
131
163
|
const esmInput = entryPoints.import ?? entryPoints.default;
|
|
132
164
|
if (entryPoints.import && entryPoints.default && entryPoints.import !== entryPoints.default) {
|
|
133
|
-
throw new Error("Both `import` and `default` export fields have been defined but with different values. To preserve proper `default` field resolution on the consumer side, make sure to provide the same file path for both fields
|
|
165
|
+
throw new Error("Both `import` and `default` export fields have been defined but with different values. To preserve proper `default` field resolution on the consumer side (i.e. to target ESM format), make sure to provide the same file path for both fields.");
|
|
134
166
|
}
|
|
135
167
|
const output = [
|
|
136
168
|
entryPoints.require && {
|