html-bundle 5.4.18 → 5.5.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/cjs/bundle.js DELETED
@@ -1,695 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault =
4
- (this && this.__importDefault) ||
5
- function (mod) {
6
- return mod && mod.__esModule ? mod : { default: mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const fs_1 = __importDefault(require("fs"));
10
- const perf_hooks_1 = require("perf_hooks");
11
- const events_1 = __importDefault(require("events"));
12
- const glob_1 = __importDefault(require("glob"));
13
- const path_1 = __importDefault(require("path"));
14
- const fastify_1 = __importDefault(require("fastify"));
15
- const fastify_static_1 = __importDefault(require("fastify-static"));
16
- const postcss_1 = __importDefault(require("postcss"));
17
- const postcss_load_config_1 = __importDefault(require("postcss-load-config"));
18
- const cssnano_1 = __importDefault(require("cssnano"));
19
- const esbuild_1 = __importDefault(require("esbuild"));
20
- const critical_1 = __importDefault(require("critical"));
21
- const html_minifier_terser_1 = require("html-minifier-terser");
22
- const chokidar_1 = require("chokidar");
23
- const parse5_1 = require("parse5");
24
- const parse5_utils_1 = require("@web/parse5-utils");
25
- // CLI and options
26
- const isCritical = process.argv.includes("--critical");
27
- const isHMR = process.argv.includes("--hmr");
28
- const isCSP = process.argv.includes("--csp");
29
- const isSecure = process.argv.includes("--secure");
30
- const isServeOnly = process.argv.includes("--serveOnly");
31
- let fastify;
32
- if (isServeOnly) {
33
- createDefaultServer();
34
- fastify.listen(5000);
35
- console.log(`💻 Sever listening on port 5000.`);
36
- } else {
37
- process.env.NODE_ENV = isHMR ? "development" : "production";
38
- let { plugins, options, file } = createPostCSSConfig();
39
- let CSSprocessor = (0, postcss_1.default)(plugins);
40
- // Performance Observer and file watcher
41
- const globHTML = new events_1.default.EventEmitter();
42
- const taskEmitter = new events_1.default.EventEmitter();
43
- const start = perf_hooks_1.performance.now();
44
- let expectedTasks = 0; // This will be increased in globHandlers
45
- let finishedTasks = 0; // Current status
46
- taskEmitter.on("done", () => {
47
- finishedTasks++;
48
- if (finishedTasks === expectedTasks) {
49
- console.log(
50
- `🚀 Build finished in ${(
51
- perf_hooks_1.performance.now() - start
52
- ).toFixed(2)}ms ✨`
53
- );
54
- if (isHMR) {
55
- if (file) {
56
- const postCSSWatcher = (0, chokidar_1.watch)(file);
57
- postCSSWatcher.on("change", () => {
58
- console.log("⚡ modified postcss.config – CSS will rebuild now.");
59
- const newConfig = createPostCSSConfig();
60
- plugins = newConfig.plugins;
61
- options = newConfig.options;
62
- CSSprocessor = (0, postcss_1.default)(plugins);
63
- (0, glob_1.default)(
64
- `${SOURCE_FOLDER}/**/*.css`,
65
- {},
66
- (err, files) => {
67
- errorHandler(err);
68
- expectedTasks += files.length;
69
- for (const filename of files) {
70
- const [buildFilename, buildPathDir] = getBuildNames(filename);
71
- fs_1.default.mkdirSync(buildPathDir, { recursive: true });
72
- minifyCSS(filename, buildFilename);
73
- }
74
- }
75
- );
76
- });
77
- }
78
- console.log(`⌛ Waiting for file changes ...`);
79
- const watcher = (0, chokidar_1.watch)(SOURCE_FOLDER);
80
- // The add watcher will add all the files initially - do not rebuild them
81
- let initialAdd = 0;
82
- let hasJSTS = false;
83
- watcher.on("add", (filename) => {
84
- // Return if it was added by the build system itself
85
- if (/-bundle-\d+\.(j|t)sx?$/.test(filename)) {
86
- return;
87
- }
88
- filename = String.raw`${filename}`.replace(/\\/g, "/");
89
- if (filename.endsWith(".html") || filename.endsWith(".css")) {
90
- initialAdd++;
91
- } else if (hasJSTS === false && /\.(j|t)sx?$/.test(filename)) {
92
- hasJSTS = true;
93
- initialAdd++;
94
- }
95
- if (initialAdd <= expectedTasks) return;
96
- const [buildFilename, buildPathDir] = getBuildNames(filename);
97
- fs_1.default.mkdir(buildPathDir, { recursive: true }, (err) => {
98
- errorHandler(err);
99
- rebuild(filename);
100
- console.log(`⚡ added ${buildFilename}`);
101
- });
102
- });
103
- watcher.on("change", (filename) => {
104
- // Return if it was changed by the build system itself
105
- if (/-bundle-\d+\.(j|t)sx?$/.test(filename)) {
106
- return;
107
- }
108
- filename = String.raw`${filename}`.replace(/\\/g, "/");
109
- rebuild(filename);
110
- const [buildFilename] = getBuildNames(filename);
111
- console.log(`⚡ modified ${buildFilename}`);
112
- });
113
- watcher.on("unlink", (filename) => {
114
- // Return if it was deleted by the build system itself
115
- if (/-bundle-\d+\.(j|t)sx?$/.test(filename)) {
116
- return;
117
- }
118
- filename = String.raw`${filename}`.replace(/\\/g, "/");
119
- JSTSFiles.delete(filename);
120
- const [buildFilename, buildPathDir] = getBuildNames(filename);
121
- fs_1.default.rm(tsMaybeX2JS(buildFilename), (err) => {
122
- errorHandler(err);
123
- console.log(`⚡ deleted ${buildFilename}`);
124
- const length = fs_1.default.readdirSync(buildPathDir).length;
125
- if (!length) fs_1.default.rmdir(buildPathDir, errorHandler);
126
- });
127
- });
128
- }
129
- }
130
- });
131
- // Basic configuration
132
- const SOURCE_FOLDER = "src";
133
- const BUILD_FOLDER = "build";
134
- const TEMPLATE_LITERAL_MINIFIER = /\n\s+/g;
135
- const CONNECTIONS = []; // HMR
136
- let htmlTasks = 0;
137
- let serverSentEvents;
138
- if (isHMR) {
139
- fastify = (0, fastify_1.default)(
140
- isSecure
141
- ? {
142
- http2: true,
143
- https: {
144
- key: fs_1.default.readFileSync(
145
- path_1.default.join(process.cwd(), "localhost-key.pem")
146
- ),
147
- cert: fs_1.default.readFileSync(
148
- path_1.default.join(process.cwd(), "localhost.pem")
149
- ),
150
- },
151
- }
152
- : void 0
153
- );
154
- fastify.setNotFoundHandler((_req, reply) => {
155
- const file = fs_1.default.readFileSync(
156
- path_1.default.join(process.cwd(), BUILD_FOLDER, "/index.html"),
157
- {
158
- encoding: "utf-8",
159
- }
160
- );
161
- reply.header("Content-Type", "text/html; charset=UTF-8");
162
- return reply.send(addHMRCode(file, "build/index.html"));
163
- });
164
- fastify.register(fastify_static_1.default, {
165
- root: path_1.default.join(process.cwd(), BUILD_FOLDER),
166
- });
167
- fastify.get("/events", (_req, reply) => {
168
- reply.raw.setHeader("Content-Type", "text/event-stream");
169
- reply.raw.setHeader("Cache-Control", "no-cache");
170
- !isSecure && reply.raw.setHeader("Connection", "keep-alive");
171
- CONNECTIONS.push(reply.raw);
172
- serverSentEvents = (data) =>
173
- CONNECTIONS.forEach((rep) => {
174
- rep.write(`data: ${JSON.stringify(data)}\n\n`);
175
- });
176
- });
177
- }
178
- // THE BUNDLE CODE
179
- // Glob all files and transform the code
180
- (0, glob_1.default)(`${SOURCE_FOLDER}/**/*.html`, {}, (err, files) => {
181
- errorHandler(err);
182
- expectedTasks += files.length;
183
- htmlTasks += files.length;
184
- if (isHMR) {
185
- createHMRHandlers(files);
186
- fastify.listen(5000);
187
- console.log(`💻 Sever listening on port 5000.`);
188
- }
189
- });
190
- (0, glob_1.default)(`${SOURCE_FOLDER}/**/*.css`, {}, (err, files) => {
191
- errorHandler(err);
192
- expectedTasks += files.length;
193
- for (const filename of files) {
194
- const [buildFilename, buildPathDir] = getBuildNames(filename);
195
- fs_1.default.mkdirSync(buildPathDir, { recursive: true });
196
- minifyCSS(filename, buildFilename);
197
- }
198
- });
199
- const JSTSFiles = new Set();
200
- (0, glob_1.default)(
201
- `${SOURCE_FOLDER}/**/!(*.d).{ts,js,tsx,jsx}`,
202
- {},
203
- (err, files) => {
204
- errorHandler(err);
205
- if (files.length) {
206
- expectedTasks += 1;
207
- } else {
208
- globHTML.emit("getReady");
209
- }
210
- files.forEach((file) => JSTSFiles.add(file));
211
- minifyTSJS().catch(errorHandler);
212
- }
213
- );
214
- globHTML.on("getReady", () => {
215
- if (expectedTasks - htmlTasks === finishedTasks) {
216
- // After CSS and JS because critical needs file built css files and inline script might reference js files.
217
- (0, glob_1.default)(
218
- `${SOURCE_FOLDER}/**/*.html`,
219
- {},
220
- async (err, files) => {
221
- errorHandler(err);
222
- await createGlobalJS(files);
223
- files.forEach((filename) => {
224
- const [buildFilename, buildPathDir] = getBuildNames(filename);
225
- fs_1.default.mkdirSync(buildPathDir, { recursive: true });
226
- minifyHTML(filename, buildFilename);
227
- });
228
- }
229
- );
230
- }
231
- });
232
- function createGlobalJS(files) {
233
- const scriptFilenames = [];
234
- files.forEach((filename) => {
235
- const fileText = fs_1.default.readFileSync(filename, {
236
- encoding: "utf-8",
237
- });
238
- let DOM;
239
- if (fileText.includes("<!DOCTYPE html>") || fileText.includes("<html")) {
240
- DOM = (0, parse5_1.parse)(fileText);
241
- } else {
242
- DOM = (0, parse5_1.parseFragment)(fileText);
243
- }
244
- const scripts = (0, parse5_utils_1.findElements)(
245
- DOM,
246
- (e) => (0, parse5_utils_1.getTagName)(e) === "script"
247
- );
248
- scripts.forEach((script, index) => {
249
- const scriptTextNode = script.childNodes[0];
250
- const isReferencedScript = script.attrs.find((a) => a.name === "src");
251
- //@ts-ignore
252
- const scriptContent =
253
- scriptTextNode === null || scriptTextNode === void 0
254
- ? void 0
255
- : scriptTextNode.value;
256
- if (!scriptContent || isReferencedScript) return;
257
- const jsFilename = filename.replace(".html", `-bundle-${index}.js`);
258
- scriptFilenames.push(jsFilename);
259
- fs_1.default.writeFileSync(jsFilename, scriptContent);
260
- });
261
- });
262
- scriptFilenames.forEach((file) => JSTSFiles.add(file));
263
- return minifyTSJS(true)
264
- .catch(console.error)
265
- .finally(() =>
266
- scriptFilenames.forEach((file) => {
267
- JSTSFiles.delete(file);
268
- try {
269
- fs_1.default.rmSync(file);
270
- } catch (_a) {}
271
- })
272
- );
273
- }
274
- function minifyTSJS(isInline = false, file) {
275
- return esbuild_1
276
- .build({
277
- entryPoints: Array.from(JSTSFiles),
278
- charset: "utf8",
279
- format: "esm",
280
- incremental: isHMR,
281
- sourcemap: isHMR,
282
- splitting: true,
283
- define: {
284
- "process.env.NODE_ENV": isHMR ? '"development"' : '"production"',
285
- },
286
- loader: { ".js": "jsx", ".ts": "tsx" },
287
- bundle: true,
288
- minify: true,
289
- outdir: BUILD_FOLDER,
290
- outbase: SOURCE_FOLDER,
291
- })
292
- .then(() => {
293
- if (!isInline) {
294
- taskEmitter.emit("done");
295
- globHTML.emit("getReady");
296
- if (serverSentEvents) {
297
- const changedFile = tsMaybeX2JS(file);
298
- const [buildFilename] = getBuildNames(changedFile);
299
- const js = fs_1.default.readFileSync(buildFilename, {
300
- encoding: "utf8",
301
- });
302
- serverSentEvents({
303
- js,
304
- filename: buildFilename.split(`${BUILD_FOLDER}/`).pop(),
305
- });
306
- }
307
- }
308
- });
309
- }
310
- function minifyCSS(filename, buildFilename) {
311
- const fileText = fs_1.default.readFileSync(filename, { encoding: "utf-8" });
312
- return CSSprocessor.process(
313
- fileText,
314
- Object.assign(Object.assign({}, options), {
315
- from: filename,
316
- to: buildFilename,
317
- })
318
- )
319
- .then((result) => {
320
- fs_1.default.writeFileSync(buildFilename, result.css);
321
- taskEmitter.emit("done");
322
- globHTML.emit("getReady");
323
- if (serverSentEvents) {
324
- serverSentEvents({
325
- css: result.css,
326
- filename: buildFilename.split(`${BUILD_FOLDER}/`).pop(),
327
- });
328
- }
329
- })
330
- .catch((err) => {
331
- console.error(err);
332
- });
333
- }
334
- async function minifyHTML(filename, buildFilename) {
335
- let fileText = fs_1.default.readFileSync(filename, { encoding: "utf-8" });
336
- let DOM;
337
- if (fileText.includes("<!DOCTYPE html>") || fileText.includes("<html")) {
338
- DOM = (0, parse5_1.parse)(fileText);
339
- } else {
340
- DOM = (0, parse5_1.parseFragment)(fileText);
341
- }
342
- // Minify Code
343
- const scripts = (0, parse5_utils_1.findElements)(
344
- DOM,
345
- (e) => (0, parse5_utils_1.getTagName)(e) === "script"
346
- );
347
- scripts.forEach((script, index) => {
348
- const scriptTextNode = script.childNodes[0];
349
- const isReferencedScript = script.attrs.find((a) => a.name === "src");
350
- //@ts-ignore
351
- if (
352
- !(scriptTextNode === null || scriptTextNode === void 0
353
- ? void 0
354
- : scriptTextNode.value) ||
355
- isReferencedScript
356
- )
357
- return;
358
- // Use bundled file and remove it from fs
359
- const bundledFilename = buildFilename.replace(
360
- ".html",
361
- `-bundle-${index}.js`
362
- );
363
- try {
364
- const scriptContent = fs_1.default.readFileSync(bundledFilename, {
365
- encoding: "utf-8",
366
- });
367
- fs_1.default.rmSync(bundledFilename);
368
- // Replace src with bundled code
369
- //@ts-ignore
370
- scriptTextNode.value = scriptContent.replace(
371
- TEMPLATE_LITERAL_MINIFIER,
372
- " "
373
- );
374
- } catch (_a) {}
375
- });
376
- // Minify Inline Style
377
- const styles = (0, parse5_utils_1.findElements)(
378
- DOM,
379
- (e) => (0, parse5_utils_1.getTagName)(e) === "style"
380
- );
381
- for (const style of styles) {
382
- const node = style.childNodes[0];
383
- //@ts-ignore
384
- const styleContent =
385
- node === null || node === void 0 ? void 0 : node.value;
386
- if (!styleContent) continue;
387
- const { css } = await CSSprocessor.process(
388
- styleContent,
389
- Object.assign(Object.assign({}, options), { from: undefined })
390
- );
391
- //@ts-ignore
392
- node.value = css;
393
- }
394
- fileText = (0, parse5_1.serialize)(DOM);
395
- // Minify HTML
396
- fileText = await (0, html_minifier_terser_1.minify)(fileText, {
397
- collapseWhitespace: true,
398
- removeComments: true,
399
- });
400
- if (isCritical) {
401
- const buildFilenameArr = buildFilename.split("/");
402
- const fileWithBase = buildFilenameArr.pop();
403
- const buildDir = buildFilenameArr.join("/");
404
- // critical is generating the files on the fs
405
- return critical_1.default
406
- .generate({
407
- base: buildDir,
408
- html: fileText,
409
- target: fileWithBase,
410
- inline: !isCSP,
411
- extract: true,
412
- rebase: () => {},
413
- })
414
- .then(({ html }) => {
415
- taskEmitter.emit("done");
416
- if (serverSentEvents) {
417
- serverSentEvents({
418
- html: addHMRCode(html, buildFilename),
419
- filename: buildFilename,
420
- });
421
- }
422
- })
423
- .catch((err) => {
424
- console.error(err);
425
- });
426
- } else {
427
- fs_1.default.writeFileSync(buildFilename, fileText);
428
- taskEmitter.emit("done");
429
- if (serverSentEvents) {
430
- serverSentEvents({
431
- html: addHMRCode(fileText, buildFilename),
432
- filename: buildFilename,
433
- });
434
- }
435
- }
436
- }
437
- // Helper functions from here
438
- function createPostCSSConfig() {
439
- try {
440
- return postcss_load_config_1.default.sync({});
441
- } catch (_a) {
442
- return { plugins: [cssnano_1.default], options: {}, file: "" };
443
- }
444
- }
445
- function getBuildNames(filename) {
446
- const buildFilename = filename.replace(
447
- `${SOURCE_FOLDER}/`,
448
- `${BUILD_FOLDER}/`
449
- );
450
- const buildFilenameArr = buildFilename.split("/");
451
- buildFilenameArr.pop();
452
- const buildPathDir = buildFilenameArr.join("/");
453
- return [buildFilename, buildPathDir];
454
- }
455
- async function rebuild(filename) {
456
- const [buildFilename] = getBuildNames(filename);
457
- if (/\.(j|t)sx?$/.test(filename)) {
458
- JSTSFiles.add(filename);
459
- } else if (filename.endsWith(".css")) {
460
- await minifyCSS(filename, buildFilename);
461
- }
462
- (0, glob_1.default)(
463
- `${SOURCE_FOLDER}/**/*.html`,
464
- {},
465
- async (err, files) => {
466
- errorHandler(err);
467
- await createGlobalJS(files);
468
- if (filename.endsWith(".html")) {
469
- minifyHTML(filename, buildFilename);
470
- } else if (
471
- /\.(j|t)sx?$/.test(filename) ||
472
- (filename.endsWith(".css") && isCritical)
473
- ) {
474
- for (const htmlFilename of files) {
475
- const [htmlBuildFilename] = getBuildNames(htmlFilename);
476
- await minifyHTML(htmlFilename, htmlBuildFilename);
477
- }
478
- if (/\.(j|t)sx?$/.test(filename) && serverSentEvents) {
479
- const jsFile = tsMaybeX2JS(buildFilename);
480
- try {
481
- // Do not try to send empty files
482
- serverSentEvents({
483
- js: fs_1.default.readFileSync(jsFile, { encoding: "utf-8" }),
484
- filename: jsFile.split(`${BUILD_FOLDER}/`).pop(),
485
- });
486
- } catch (_a) {}
487
- }
488
- }
489
- }
490
- );
491
- }
492
- const getHMRCode = (
493
- filename,
494
- id
495
- ) => `import { render, html, setShouldSetReactivity, $$, setGlobalSchedule, setInsertDiffing } from "https://unpkg.com/hydro-js/dist/library.js";
496
-
497
- if (!window.eventsource${id}) {
498
- setGlobalSchedule(false);
499
- setShouldSetReactivity(false);
500
-
501
- window.eventsource${id} = new EventSource("/events");
502
- window.eventsource${id}.addEventListener("message", ({ data }) => {
503
- const dataObj = JSON.parse(data);
504
-
505
- if ("html" in dataObj && "${filename}" === dataObj.filename) {
506
- setInsertDiffing(true);
507
-
508
- let newHTML;
509
- let isBody;
510
-
511
- if (dataObj.html.startsWith('<!DOCTYPE html>') || dataObj.html.startsWith('<html')) {
512
- newHTML = html\`\${dataObj.html}\`;
513
- } else {
514
- newHTML = html\`<body>\${dataObj.html}</body>\`
515
- isBody = true
516
- }
517
-
518
- if (isBody) {
519
- const hmrID = "${id}";
520
- const hmrElems = Array.from(newHTML.childNodes);
521
- const hmrWheres = Array.from($$(\`[data-hmr="\${hmrID}"]\`))
522
- // Render new Elements in old Elements, also remove rest old Elements and add add new elements after the last old one
523
- hmrWheres.forEach((where, index) => {
524
- if (index < hmrElems.length) {
525
- render(hmrElems[index], where);
526
- } else {
527
- where.remove();
528
- }
529
- });
530
- for (let rest = hmrWheres.length; rest < hmrElems.length; rest++) {
531
- if (hmrWheres.length) {
532
- const template = document.createElement('template');
533
- hmrElems[hmrWheres.length - 1].after(template);
534
- render(hmrElems[rest], template);
535
- template.remove();
536
- } else {
537
- render(hmrElems[rest])
538
- }
539
- }
540
- } else {
541
- const oldElementCount = document.body.querySelectorAll('*').length;
542
- render(newHTML, document.documentElement);
543
- const newElementCount = document.body.querySelectorAll('*').length;
544
-
545
- // Looks like JS did not reload? Last resort - hard refresh
546
- if (newElementCount < 5 && Math.abs(newElementCount - oldElementCount) > 10) {
547
- location.reload()
548
- }
549
- }
550
- setInsertDiffing(false);
551
- if (dataObj.filename === 'build/index.html') {
552
- dispatchEvent(new Event("popstate"));
553
- }
554
- } else if ("css" in dataObj) {
555
- window.onceEveryXTime(100, window.updateCSS, [updateAttr]);
556
- } else if ("js" in dataObj) {
557
- window.onceEveryXTime(100, window.updateJS, [updateAttr]);
558
- }
559
-
560
- function updateAttr (attr, forceUpdate = false) {
561
- return (elem) => {
562
- const attrValue = elem[attr].replace(/\\?v=.*/, "");
563
- if (forceUpdate || attrValue.endsWith(dataObj.filename)) {
564
- elem[attr] = \`\${attrValue}?v=\${Math.random().toFixed(4)}\`;
565
- } else if (elem.localName === 'script' && !elem.src && new RegExp(\`["']\${dataObj.filename}["']\`).test(elem.textContent)) {
566
- elem.setAttribute('data-inline', String(Math.random().toFixed(4)).slice(2));
567
- }
568
- }
569
- };
570
- });
571
-
572
- if (!window.updateCSS) {
573
- window.updateCSS = function updateCSS(updateAttr) {
574
- $$('link').forEach(updateAttr("href"));
575
- window.fnToLastCalled.set(window.updateCSS, performance.now())
576
- }
577
- }
578
- if (!window.updateJS) {
579
- window.updateJS = function updateJS(updateAttr) {
580
- window.fnToLastCalled.set(window.updateJS, performance.now());
581
- const copy = html\`\${document.documentElement.outerHTML}\`;
582
- copy.querySelectorAll('script').forEach(updateAttr("src"));
583
- render(copy, document.documentElement);
584
- }
585
- }
586
- if (!window.fnToLastCalled) {
587
- window.fnToLastCalled = new Map();
588
- }
589
- if (!window.onceEveryXTime) {
590
- window.onceEveryXTime = function (time, fn, params) {
591
- if (!window.fnToLastCalled.has(fn) || performance.now() - window.fnToLastCalled.get(fn) > time) {
592
- fn(...params)
593
- }
594
- }
595
- }
596
- }`;
597
- function randomText() {
598
- return Math.random().toString(32).slice(2);
599
- }
600
- const htmlIdMap = new Map();
601
- function addHMRCode(html, filename) {
602
- if (!htmlIdMap.has(filename)) {
603
- htmlIdMap.set(filename, randomText());
604
- }
605
- const script = (0, parse5_utils_1.createScript)(
606
- { type: "module" },
607
- getHMRCode(filename, htmlIdMap.get(filename))
608
- );
609
- let ast;
610
- if (html.includes("<!DOCTYPE html>") || html.includes("<html")) {
611
- ast = (0, parse5_1.parse)(html);
612
- const headNode = (0, parse5_utils_1.findElement)(
613
- ast,
614
- (e) => (0, parse5_utils_1.getTagName)(e) === "head"
615
- );
616
- (0, parse5_utils_1.appendChild)(headNode, script);
617
- } else {
618
- ast = (0, parse5_1.parseFragment)(html);
619
- (0, parse5_utils_1.appendChild)(ast, script);
620
- ast.childNodes.forEach((node) => {
621
- var _a;
622
- //@ts-ignore
623
- return (_a = node.attrs) === null || _a === void 0
624
- ? void 0
625
- : _a.push({ name: "data-hmr", value: htmlIdMap.get(filename) });
626
- });
627
- }
628
- // Burst CSS cache
629
- (0, parse5_utils_1.findElements)(
630
- ast,
631
- (e) => (0, parse5_utils_1.getTagName)(e) === "link"
632
- ).forEach((link) => {
633
- const href = link.attrs.find((attr) => attr.name === "href");
634
- const rel = link.attrs.find((attr) => attr.name === "rel");
635
- if (rel.value === "stylesheet") {
636
- href.value += `?v=${Math.random().toFixed(4)}`;
637
- }
638
- });
639
- return (0, parse5_1.serialize)(ast);
640
- }
641
- function createHMRHandlers(files) {
642
- files.forEach((filename) => {
643
- const newFilename = "/" + filename.replace(/src\//, "");
644
- const filePath = newFilename.split("/");
645
- const endName = filePath.pop();
646
- if (endName.endsWith("index.html")) {
647
- //@ts-ignore
648
- fastify.get(filePath.join("/") + "/", HMRHandler);
649
- }
650
- //@ts-ignore
651
- fastify.get(newFilename, HMRHandler);
652
- });
653
- }
654
- function HMRHandler(request, reply) {
655
- let filename = request.url;
656
- if (filename.endsWith("/")) {
657
- filename += "index.html";
658
- }
659
- filename = BUILD_FOLDER + filename;
660
- const file = fs_1.default.readFileSync(filename, {
661
- encoding: "utf-8",
662
- });
663
- reply.header("Content-Type", "text/html; charset=UTF-8");
664
- return reply.send(addHMRCode(file, filename));
665
- }
666
- function errorHandler(err) {
667
- if (err) {
668
- console.error(err);
669
- process.exit(1);
670
- }
671
- }
672
- function tsMaybeX2JS(filename) {
673
- return filename.replace(".ts", ".js").replace(".jsx", ".js");
674
- }
675
- }
676
- function createDefaultServer(BUILD_FOLDER = "build") {
677
- fastify = (0, fastify_1.default)(
678
- isSecure
679
- ? {
680
- http2: true,
681
- https: {
682
- key: fs_1.default.readFileSync(
683
- path_1.default.join(process.cwd(), "localhost-key.pem")
684
- ),
685
- cert: fs_1.default.readFileSync(
686
- path_1.default.join(process.cwd(), "localhost.pem")
687
- ),
688
- },
689
- }
690
- : void 0
691
- );
692
- fastify.register(fastify_static_1.default, {
693
- root: path_1.default.join(process.cwd(), BUILD_FOLDER),
694
- });
695
- }