Skip to content

Commit 64075f4

Browse files
committed
init
0 parents  commit 64075f4

File tree

8 files changed

+657
-0
lines changed

8 files changed

+657
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist
2+
node_modules

build.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import fs from "node:fs";
2+
import path from "node:path";
3+
import { minify } from "html-minifier";
4+
import sharp from "sharp";
5+
import fse from "fs-extra";
6+
import { fileURLToPath } from "node:url";
7+
8+
// Get __dirname equivalent for ES modules
9+
const __filename = fileURLToPath(import.meta.url);
10+
const __dirname = path.dirname(__filename);
11+
12+
const srcDir = path.join(__dirname, "src");
13+
const distDir = path.join(__dirname, "dist");
14+
15+
// Create dist directory if it doesn't exist
16+
if (!fs.existsSync(distDir)) {
17+
fs.mkdirSync(distDir);
18+
}
19+
20+
// Function to resize images based on HTML attributes and compress them
21+
async function resizeImages(html) {
22+
const imgRegex =
23+
/<img[^>]+src="([^">]+)"[^>]+width="([^">]+)"[^>]+height="([^">]+)"[^>]*>/g;
24+
let match = imgRegex.exec(html);
25+
26+
while (match !== null) {
27+
const imgSrc = match[1];
28+
const width = Number.parseInt(match[2], 10);
29+
const height = Number.parseInt(match[3], 10);
30+
31+
const srcPath = path.join(srcDir, imgSrc);
32+
const distPath = path.join(distDir, imgSrc);
33+
34+
if (fs.existsSync(srcPath)) {
35+
console.log(`Resizing and compressing ${imgSrc} to ${width}x${height}`);
36+
37+
const sharpInstance = sharp(srcPath).resize(width, height);
38+
39+
// Use appropriate compression based on image type
40+
if (imgSrc.endsWith(".jpg") || imgSrc.endsWith(".jpeg")) {
41+
await sharpInstance.jpeg({ quality: 75 }).toFile(distPath);
42+
} else if (imgSrc.endsWith(".png")) {
43+
await sharpInstance.png({ quality: 80 }).toFile(distPath);
44+
} else {
45+
await sharpInstance.toFile(distPath); // For other formats
46+
}
47+
}
48+
49+
// Get the next match
50+
match = imgRegex.exec(html);
51+
}
52+
}
53+
54+
// Function to compress non-resized images using sharp
55+
async function compressImages() {
56+
const imageDir = path.join(srcDir, "images");
57+
const distImageDir = path.join(distDir, "images");
58+
59+
if (!fs.existsSync(imageDir)) return;
60+
61+
const images = fs.readdirSync(imageDir);
62+
63+
for (const img of images) {
64+
const srcPath = path.join(imageDir, img);
65+
const distPath = path.join(distImageDir, img);
66+
67+
if (!fs.existsSync(distPath)) {
68+
// Only compress if image wasn't resized
69+
console.log(`Compressing ${img}`);
70+
const sharpInstance = sharp(srcPath);
71+
72+
if (img.endsWith(".jpg") || img.endsWith(".jpeg")) {
73+
await sharpInstance.jpeg({ quality: 75 }).toFile(distPath);
74+
} else if (img.endsWith(".png")) {
75+
await sharpInstance.png({ quality: 80 }).toFile(distPath);
76+
} else {
77+
await sharpInstance.toFile(distPath); // For other formats
78+
}
79+
}
80+
}
81+
}
82+
83+
// Read component files and inject them into index.html
84+
async function buildHTML() {
85+
let html = fs.readFileSync(path.join(srcDir, "index.html"), "utf-8");
86+
87+
const componentRegex = /<component src="(.*)"><\/component>/g;
88+
html = html.replace(componentRegex, (_, componentPath) => {
89+
const component = fs.readFileSync(
90+
path.join(srcDir, "components", componentPath),
91+
"utf-8",
92+
);
93+
return component;
94+
});
95+
96+
// Minify HTML
97+
const minifiedHTML = minify(html, {
98+
collapseWhitespace: true,
99+
removeComments: true,
100+
minifyCSS: true,
101+
minifyJS: true,
102+
});
103+
104+
// Resize and compress images before saving final HTML
105+
await resizeImages(minifiedHTML);
106+
107+
fs.writeFileSync(path.join(distDir, "index.html"), minifiedHTML);
108+
}
109+
110+
// Copy all files from /src/assets to /dist/assets, and root style/script files to /dist
111+
function copyAssets() {
112+
const assetsSrc = path.join(srcDir, "assets");
113+
const assetsDist = path.join(distDir, "assets");
114+
115+
// Copy assets folder
116+
if (fs.existsSync(assetsSrc)) {
117+
fse.copySync(assetsSrc, assetsDist);
118+
console.log(`Copied assets from ${assetsSrc} to ${assetsDist}`);
119+
}
120+
121+
// Copy root CSS and JS files
122+
const filesToCopy = ["styles.css", "script.js"];
123+
for (const file in filesToCopy) {
124+
const srcFile = path.join(srcDir, file);
125+
const distFile = path.join(distDir, file);
126+
127+
if (fs.existsSync(srcFile)) {
128+
fs.copyFileSync(srcFile, distFile);
129+
console.log(`Copied ${file} to ${distDir}`);
130+
}
131+
}
132+
}
133+
134+
// Run build process with top-level await (Node.js 14+ supports it)
135+
(async () => {
136+
await buildHTML();
137+
copyAssets();
138+
await compressImages(); // Compress non-resized images after build
139+
console.log("Build completed!");
140+
})();

package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "bhoomy",
3+
"version": "1.0.0",
4+
"type": "module",
5+
"description": "",
6+
"main": "index.js",
7+
"scripts": {
8+
"test": "echo \"Error: no test specified\" && exit 1",
9+
"build": "node build.js"
10+
},
11+
"keywords": [],
12+
"author": "",
13+
"license": "ISC",
14+
"dependencies": {
15+
"@types/fs-extra": "^11.0.4",
16+
"@types/html-minifier": "^4.0.5",
17+
"fs-extra": "^11.2.0",
18+
"html-minifier": "^4.0.0",
19+
"sharp": "^0.33.5"
20+
}
21+
}

0 commit comments

Comments
 (0)