forked from hackclub/blot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.js
94 lines (73 loc) · 2.76 KB
/
build.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// should be in same directory as server
import { JSDOM } from 'jsdom';
import esbuild from 'esbuild';
import fs from 'fs';
import path from 'path';
import alias from 'esbuild-plugin-alias';
import inlineWorkerPlugin from 'esbuild-plugin-inline-worker';
import { spawn } from 'child_process';
spawn('npx', ['tailwindcss', '-i', './styles.css', '-o', './dist/styles.css']);
const OUTPUT_DIR = "./dist";
// Function to bundle script sources found in HTML
export const bundleHtmlScripts = async (name, htmlContent, outputPath = OUTPUT_DIR) => {
const dom = new JSDOM(htmlContent);
const { document } = dom.window;
const scripts = [...document.querySelectorAll('script[src]')];
for (const script of scripts) {
const src = script.getAttribute('src');
if (src.includes("http") || script.hasAttribute("leave-it")) continue;
const inputFile = path.resolve(src); // Assuming src is a relative path
const outputFile = path.join(outputPath, 'assets', path.basename(src));
// Use esbuild to bundle the script
await esbuild.build({
entryPoints: [inputFile],
bundle: true,
sourcemap: true,
outfile: outputFile,
jsxFactory: 'h',
jsxFragment: 'Fragment',
inject: ['./backend/preact-shim.js'],
plugins: [inlineWorkerPlugin()]
}).catch(() => process.exit(1));;
// Update script src to point to the new bundled file
script.setAttribute('src', "./" + path.relative(outputPath, outputFile));
}
// Write the modified HTML to the dist directory
fs.writeFileSync(path.join(outputPath, `${name}.html`), dom.serialize(), 'utf-8');
};
export function deleteAllFiles(directory) {
const entries = fs.readdirSync(directory, { withFileTypes: true });
for (const entry of entries) {
const entryPath = path.join(directory, entry.name);
if (entry.isDirectory()) {
// Recursively delete everything in the subdirectory
deleteAllFiles(entryPath);
// Delete the now-empty subdirectory
fs.rmdirSync(entryPath);
} else {
// Delete the file
fs.unlinkSync(entryPath);
}
}
}
export async function build(htmls) {
if (!fs.existsSync(OUTPUT_DIR)) {
// If the folder does not exist, create it
fs.mkdirSync(OUTPUT_DIR);
console.log(`Folder '${OUTPUT_DIR}' created.`);
} else {
// If the folder exists, print a message
console.log(`Folder '${OUTPUT_DIR}' already exists.`);
}
// console.time("DELETE")
await deleteAllFiles(OUTPUT_DIR);
// console.timeEnd("DELETE")
// console.time("BUILD")
await Promise.all(Object.entries(htmls).map(async ([name, content]) => {
return bundleHtmlScripts(name, content);
}));
// console.timeEnd("BUILD")
// console.time("COPY")
await fs.cpSync("./public", OUTPUT_DIR, { recursive: true });
// console.timeEnd("COPY")
}