html-bundle 6.0.22 → 6.1.1
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 +13 -0
- package/dist/bundle.mjs +39 -18
- package/package.json +6 -5
- package/src/bundle.mts +35 -20
- package/src/config.d.ts +13 -0
- package/src/utils.mts +1 -13
package/README.md
CHANGED
|
@@ -63,6 +63,19 @@ Generate the config in the root and call it "bundle.config.js"
|
|
|
63
63
|
**html-minifier-terser:** Your additional config<br>
|
|
64
64
|
**critical:** Your additional config<br>
|
|
65
65
|
|
|
66
|
+
Example:
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
/** @type {import('html-bundle').Config} */
|
|
70
|
+
export default {
|
|
71
|
+
secure: true,
|
|
72
|
+
handler: "utils/staticFiles.js",
|
|
73
|
+
esbuild: {
|
|
74
|
+
external: ["images"],
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
66
79
|
## Concept
|
|
67
80
|
|
|
68
81
|
The bundler always globs all HTML, CSS and TS/JS files from the `src` (config) directory and processes them to the `build` (config) directory. PostCSS is being used for CSS files and inline styles, html-minifier-terser for HTML and esbuild to bundle, minify, etc. for inline and referenced TS/JS. Server-sent events and [hydro-js](https://github.com/Krutsch/hydro-js) are used for HMR. In order to trigger SPA Routers, the popstate event is being triggered after HMR Operations.
|
package/dist/bundle.mjs
CHANGED
|
@@ -103,7 +103,10 @@ async function build(files, firstRun = true) {
|
|
|
103
103
|
if (files.includes(file) || INLINE_BUNDLE_FILE.test(file)) {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
try {
|
|
107
|
+
await rebuild(file);
|
|
108
|
+
}
|
|
109
|
+
catch { }
|
|
107
110
|
console.log(`⚡ added ${file} to the build`);
|
|
108
111
|
});
|
|
109
112
|
watcher.on("change", async (file) => {
|
|
@@ -123,11 +126,14 @@ async function build(files, firstRun = true) {
|
|
|
123
126
|
const buildFile = getBuildPath(file)
|
|
124
127
|
.replace(".ts", ".js")
|
|
125
128
|
.replace(".jsx", ".js");
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
try {
|
|
130
|
+
await rm(buildFile);
|
|
131
|
+
const bfDir = buildFile.split("/").slice(0, -1).join("/");
|
|
132
|
+
const stats = await readdir(bfDir);
|
|
133
|
+
if (!stats.length)
|
|
134
|
+
await rm(bfDir);
|
|
135
|
+
}
|
|
136
|
+
catch { }
|
|
131
137
|
console.log(`⚡ deleted ${file} from the build`);
|
|
132
138
|
});
|
|
133
139
|
async function rebuild(file) {
|
|
@@ -162,6 +168,11 @@ async function build(files, firstRun = true) {
|
|
|
162
168
|
await fileCopy(file);
|
|
163
169
|
}
|
|
164
170
|
}
|
|
171
|
+
else if (handlerFile) {
|
|
172
|
+
const { stdout } = await execFilePromise("node", [handlerFile, file]);
|
|
173
|
+
if (String(stdout))
|
|
174
|
+
console.log("📋 Logging Handler: ", String(stdout));
|
|
175
|
+
}
|
|
165
176
|
serverSentEvents?.({ file, html });
|
|
166
177
|
}
|
|
167
178
|
}
|
|
@@ -177,7 +188,8 @@ async function minifyCSS(file, buildFile) {
|
|
|
177
188
|
await writeFile(buildFile, result.css);
|
|
178
189
|
}
|
|
179
190
|
catch (err) {
|
|
180
|
-
|
|
191
|
+
// @ts-ignore
|
|
192
|
+
console.error(err?.reason);
|
|
181
193
|
}
|
|
182
194
|
}
|
|
183
195
|
async function minifyCode() {
|
|
@@ -207,7 +219,7 @@ async function minifyCode() {
|
|
|
207
219
|
let missingPkg = false;
|
|
208
220
|
if (err?.errors) {
|
|
209
221
|
for (const error of err.errors) {
|
|
210
|
-
if (error.text?.startsWith("Could not resolve")) {
|
|
222
|
+
if (error.location && error.text?.startsWith("Could not resolve")) {
|
|
211
223
|
missingPkg = true;
|
|
212
224
|
const packageNameRegex = /(?<=").*(?=")/;
|
|
213
225
|
const [pkgName] = error.text.match(packageNameRegex);
|
|
@@ -282,11 +294,14 @@ async function minifyHTML(file, buildFile) {
|
|
|
282
294
|
continue;
|
|
283
295
|
// Use bundled file
|
|
284
296
|
const buildInlineScript = buildFile.replace(".html", `-bundle-${index}.js`);
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
297
|
+
try {
|
|
298
|
+
const scriptContent = await readFile(buildInlineScript, {
|
|
299
|
+
encoding: "utf-8",
|
|
300
|
+
});
|
|
301
|
+
await rm(buildInlineScript);
|
|
302
|
+
scriptTextNode.value = scriptContent.replace(TEMPLATE_LITERAL_MINIFIER, " ");
|
|
303
|
+
}
|
|
304
|
+
catch { }
|
|
290
305
|
}
|
|
291
306
|
// Minify Inline Style
|
|
292
307
|
const styles = findElements(DOM, (e) => getTagName(e) === "style");
|
|
@@ -295,11 +310,17 @@ async function minifyHTML(file, buildFile) {
|
|
|
295
310
|
const styleContent = node?.value;
|
|
296
311
|
if (!styleContent)
|
|
297
312
|
continue;
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
313
|
+
try {
|
|
314
|
+
const { css } = await CSSprocessor.process(styleContent, {
|
|
315
|
+
...options,
|
|
316
|
+
from: undefined,
|
|
317
|
+
});
|
|
318
|
+
node.value = css;
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
// @ts-ignore
|
|
322
|
+
console.error(err?.reason);
|
|
323
|
+
}
|
|
303
324
|
}
|
|
304
325
|
fileText = serialize(DOM);
|
|
305
326
|
// Minify HTML
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "html-bundle",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.1",
|
|
4
4
|
"description": "A very simple bundler for HTML SFC",
|
|
5
5
|
"bin": "./dist/bundle.mjs",
|
|
6
|
+
"types": "./src/config.d.ts",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"start": "tsc",
|
|
8
9
|
"update": "npx npm-check-updates -u && npx typesync && npm i && npm outdated"
|
|
@@ -31,19 +32,19 @@
|
|
|
31
32
|
},
|
|
32
33
|
"bugs": "https://github.com/Krutsch/html-bundle/issues",
|
|
33
34
|
"dependencies": {
|
|
34
|
-
"@fastify/static": "^
|
|
35
|
+
"@fastify/static": "^7.0.0",
|
|
35
36
|
"@web/parse5-utils": "^2.1.0",
|
|
36
37
|
"await-spawn": "^4.0.2",
|
|
37
38
|
"chokidar": "^3.5.3",
|
|
38
39
|
"critters": "^0.0.20",
|
|
39
40
|
"cssnano": "^6.0.3",
|
|
40
|
-
"esbuild": "^0.
|
|
41
|
-
"fastify": "^4.
|
|
41
|
+
"esbuild": "^0.20.0",
|
|
42
|
+
"fastify": "^4.26.0",
|
|
42
43
|
"glob": "^10.3.10",
|
|
43
44
|
"html-minifier-terser": "^7.2.0",
|
|
44
45
|
"hydro-js": "^1.5.14",
|
|
45
46
|
"parse5": "^7.1.2",
|
|
46
|
-
"postcss": "^8.4.
|
|
47
|
+
"postcss": "^8.4.34",
|
|
47
48
|
"postcss-load-config": "^5.0.2"
|
|
48
49
|
}
|
|
49
50
|
}
|
package/src/bundle.mts
CHANGED
|
@@ -138,7 +138,9 @@ async function build(files: string[], firstRun = true) {
|
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
try {
|
|
142
|
+
await rebuild(file);
|
|
143
|
+
} catch {}
|
|
142
144
|
|
|
143
145
|
console.log(`⚡ added ${file} to the build`);
|
|
144
146
|
});
|
|
@@ -162,11 +164,13 @@ async function build(files: string[], firstRun = true) {
|
|
|
162
164
|
const buildFile = getBuildPath(file)
|
|
163
165
|
.replace(".ts", ".js")
|
|
164
166
|
.replace(".jsx", ".js");
|
|
165
|
-
await rm(buildFile);
|
|
166
167
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
try {
|
|
169
|
+
await rm(buildFile);
|
|
170
|
+
const bfDir = buildFile.split("/").slice(0, -1).join("/");
|
|
171
|
+
const stats = await readdir(bfDir);
|
|
172
|
+
if (!stats.length) await rm(bfDir);
|
|
173
|
+
} catch {}
|
|
170
174
|
|
|
171
175
|
console.log(`⚡ deleted ${file} from the build`);
|
|
172
176
|
});
|
|
@@ -200,6 +204,9 @@ async function build(files: string[], firstRun = true) {
|
|
|
200
204
|
} else {
|
|
201
205
|
await fileCopy(file);
|
|
202
206
|
}
|
|
207
|
+
} else if (handlerFile) {
|
|
208
|
+
const { stdout } = await execFilePromise("node", [handlerFile, file]);
|
|
209
|
+
if (String(stdout)) console.log("📋 Logging Handler: ", String(stdout));
|
|
203
210
|
}
|
|
204
211
|
|
|
205
212
|
serverSentEvents?.({ file, html });
|
|
@@ -217,7 +224,8 @@ async function minifyCSS(file: string, buildFile: string) {
|
|
|
217
224
|
});
|
|
218
225
|
await writeFile(buildFile, result.css);
|
|
219
226
|
} catch (err) {
|
|
220
|
-
|
|
227
|
+
// @ts-ignore
|
|
228
|
+
console.error(err?.reason);
|
|
221
229
|
}
|
|
222
230
|
}
|
|
223
231
|
|
|
@@ -248,7 +256,7 @@ async function minifyCode(): Promise<unknown> {
|
|
|
248
256
|
let missingPkg = false;
|
|
249
257
|
if (err?.errors) {
|
|
250
258
|
for (const error of err.errors) {
|
|
251
|
-
if (error.text?.startsWith("Could not resolve")) {
|
|
259
|
+
if (error.location && error.text?.startsWith("Could not resolve")) {
|
|
252
260
|
missingPkg = true;
|
|
253
261
|
const packageNameRegex = /(?<=").*(?=")/;
|
|
254
262
|
const [pkgName] = error.text.match(packageNameRegex);
|
|
@@ -340,14 +348,16 @@ async function minifyHTML(file: string, buildFile: string) {
|
|
|
340
348
|
// Use bundled file
|
|
341
349
|
const buildInlineScript = buildFile.replace(".html", `-bundle-${index}.js`);
|
|
342
350
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
+
try {
|
|
352
|
+
const scriptContent = await readFile(buildInlineScript, {
|
|
353
|
+
encoding: "utf-8",
|
|
354
|
+
});
|
|
355
|
+
await rm(buildInlineScript);
|
|
356
|
+
scriptTextNode.value = scriptContent.replace(
|
|
357
|
+
TEMPLATE_LITERAL_MINIFIER,
|
|
358
|
+
" "
|
|
359
|
+
);
|
|
360
|
+
} catch {}
|
|
351
361
|
}
|
|
352
362
|
|
|
353
363
|
// Minify Inline Style
|
|
@@ -357,11 +367,16 @@ async function minifyHTML(file: string, buildFile: string) {
|
|
|
357
367
|
const styleContent = node?.value;
|
|
358
368
|
if (!styleContent) continue;
|
|
359
369
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
370
|
+
try {
|
|
371
|
+
const { css } = await CSSprocessor.process(styleContent, {
|
|
372
|
+
...options,
|
|
373
|
+
from: undefined,
|
|
374
|
+
});
|
|
375
|
+
node.value = css;
|
|
376
|
+
} catch {
|
|
377
|
+
// @ts-ignore
|
|
378
|
+
console.error(err?.reason);
|
|
379
|
+
}
|
|
365
380
|
}
|
|
366
381
|
|
|
367
382
|
fileText = serialize(DOM);
|
package/src/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type Config = {
|
|
2
|
+
build: string;
|
|
3
|
+
src: string;
|
|
4
|
+
port: number;
|
|
5
|
+
secure: boolean;
|
|
6
|
+
esbuild?: BuildOptions;
|
|
7
|
+
"html-minifier-terser"?: HTMLOptions;
|
|
8
|
+
critical?: Options;
|
|
9
|
+
deletePrev?: boolean;
|
|
10
|
+
isCritical?: boolean;
|
|
11
|
+
hmr?: boolean;
|
|
12
|
+
handler?: string;
|
|
13
|
+
};
|
package/src/utils.mts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
findElement,
|
|
17
17
|
appendChild,
|
|
18
18
|
} from "@web/parse5-utils";
|
|
19
|
+
import { Config } from "./config";
|
|
19
20
|
|
|
20
21
|
export const bundleConfig = await getBundleConfig();
|
|
21
22
|
|
|
@@ -89,19 +90,6 @@ export async function getPostCSSConfig() {
|
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
export type Config = {
|
|
93
|
-
build: string;
|
|
94
|
-
src: string;
|
|
95
|
-
port: number;
|
|
96
|
-
secure: boolean;
|
|
97
|
-
esbuild?: BuildOptions;
|
|
98
|
-
"html-minifier-terser"?: HTMLOptions;
|
|
99
|
-
critical?: Options;
|
|
100
|
-
deletePrev?: boolean;
|
|
101
|
-
isCritical?: boolean;
|
|
102
|
-
hmr?: boolean;
|
|
103
|
-
handler?: string;
|
|
104
|
-
};
|
|
105
93
|
async function getBundleConfig(): Promise<Config> {
|
|
106
94
|
const base = {
|
|
107
95
|
build: "build",
|