Tiny script for preparing web assets for deployment

update sass and use better options for cwebp

+18 -18
package-lock.json
··· 1 1 { 2 2 "name": "forking-build-shit", 3 - "version": "0.0.2", 3 + "version": "0.1.0", 4 4 "lockfileVersion": 3, 5 5 "requires": true, 6 6 "packages": { 7 7 "": { 8 8 "name": "forking-build-shit", 9 - "version": "0.0.2", 9 + "version": "0.1.0", 10 10 "license": "MIT", 11 11 "dependencies": { 12 12 "csso": "5.0.5", 13 - "sass": "1.86.0", 13 + "sass": "1.89.0", 14 14 "uglify-js": "3.19.3" 15 15 }, 16 16 "bin": { ··· 19 19 "devDependencies": { 20 20 "@sindresorhus/tsconfig": "7.0.0", 21 21 "@types/csso": "^5.0.4", 22 - "@types/node": "^22.13.10", 22 + "@types/node": "^22.15.23", 23 23 "@types/uglify-js": "^3.17.5", 24 - "typescript": "5.8.2" 24 + "typescript": "5.8.3" 25 25 } 26 26 }, 27 27 "node_modules/@parcel/watcher": { ··· 351 351 } 352 352 }, 353 353 "node_modules/@types/node": { 354 - "version": "22.13.10", 355 - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", 356 - "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", 354 + "version": "22.15.23", 355 + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.23.tgz", 356 + "integrity": "sha512-7Ec1zaFPF4RJ0eXu1YT/xgiebqwqoJz8rYPDi/O2BcZ++Wpt0Kq9cl0eg6NN6bYbPnR67ZLo7St5Q3UK0SnARw==", 357 357 "dev": true, 358 358 "license": "MIT", 359 359 "dependencies": { 360 - "undici-types": "~6.20.0" 360 + "undici-types": "~6.21.0" 361 361 } 362 362 }, 363 363 "node_modules/@types/uglify-js": { ··· 544 544 } 545 545 }, 546 546 "node_modules/sass": { 547 - "version": "1.86.0", 548 - "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.0.tgz", 549 - "integrity": "sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==", 547 + "version": "1.89.0", 548 + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.0.tgz", 549 + "integrity": "sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==", 550 550 "license": "MIT", 551 551 "dependencies": { 552 552 "chokidar": "^4.0.0", ··· 596 596 } 597 597 }, 598 598 "node_modules/typescript": { 599 - "version": "5.8.2", 600 - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 601 - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 599 + "version": "5.8.3", 600 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", 601 + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", 602 602 "dev": true, 603 603 "license": "Apache-2.0", 604 604 "bin": { ··· 622 622 } 623 623 }, 624 624 "node_modules/undici-types": { 625 - "version": "6.20.0", 626 - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 627 - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 625 + "version": "6.21.0", 626 + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", 627 + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", 628 628 "dev": true, 629 629 "license": "MIT" 630 630 }
+4 -4
package.json
··· 1 1 { 2 2 "name": "forking-build-shit", 3 - "version": "0.0.2", 3 + "version": "0.1.0", 4 4 "description": "Tiny script for preparing web assets for deployment", 5 5 "homepage": "https://github.com/CorySanin/build-shit#readme", 6 6 "bugs": { ··· 8 8 }, 9 9 "dependencies": { 10 10 "csso": "5.0.5", 11 - "sass": "1.86.0", 11 + "sass": "1.89.0", 12 12 "uglify-js": "3.19.3" 13 13 }, 14 14 "devDependencies": { 15 15 "@sindresorhus/tsconfig": "7.0.0", 16 16 "@types/csso": "^5.0.4", 17 - "@types/node": "^22.13.10", 17 + "@types/node": "^22.15.23", 18 18 "@types/uglify-js": "^3.17.5", 19 - "typescript": "5.8.2" 19 + "typescript": "5.8.3" 20 20 }, 21 21 "repository": { 22 22 "type": "git",
+31 -17
src/build-shit.ts
··· 34 34 } 35 35 } 36 36 37 + function getFileExtension(filename: string) { 38 + const split = filename.split('.'); 39 + return split[split.length - 1].toLowerCase(); 40 + } 41 + 37 42 // Process styles 38 43 async function styles() { 39 44 await mkdir([STYLEOUTDIR, STYLESDIR]); 40 45 await emptyDir(STYLEOUTDIR); 41 - let styles: string[] = []; 42 - let files = await fsp.readdir(STYLESDIR); 46 + const styles: string[] = []; 47 + const files = await fsp.readdir(STYLESDIR); 43 48 await Promise.all(files.map(f => new Promise(async (res, reject) => { 44 - let p = path.join(STYLESDIR, f); 49 + const p = path.join(STYLESDIR, f); 45 50 console.log(`Processing style ${p}`); 46 - let style = sass.compile(p).css; 51 + const style = sass.compile(p).css; 47 52 if (f.charAt(0) !== '_') { 48 53 if (SQUASH.test(f)) { 49 54 styles.push(style); 50 55 } 51 56 else { 52 - let o = path.join(STYLEOUTDIR, f.substring(0, f.lastIndexOf('.')) + '.css'); 57 + const o = path.join(STYLEOUTDIR, f.substring(0, f.lastIndexOf('.')) + '.css'); 53 58 await fsp.writeFile(o, csso.minify(style).css); 54 59 console.log(`Wrote ${o}`); 55 60 } 56 61 } 57 62 res(0); 58 63 }))); 59 - let out = csso.minify(styles.join('\n')).css; 60 - let outpath = path.join(STYLEOUTDIR, STYLEOUTFILE); 64 + const out = csso.minify(styles.join('\n')).css; 65 + const outpath = path.join(STYLEOUTDIR, STYLEOUTFILE); 61 66 await fsp.writeFile(outpath, out); 62 67 console.log(`Wrote ${outpath}`); 63 68 } ··· 66 71 async function scripts() { 67 72 await mkdir([SCRIPTSOUTDIR, SCRIPTSDIR]); 68 73 await emptyDir(SCRIPTSOUTDIR); 69 - let files = await fsp.readdir(SCRIPTSDIR); 74 + const files = await fsp.readdir(SCRIPTSDIR); 70 75 await Promise.all(files.map(f => new Promise(async (res, reject) => { 71 - let p = path.join(SCRIPTSDIR, f); 72 - let o = path.join(SCRIPTSOUTDIR, f); 76 + const p = path.join(SCRIPTSDIR, f); 77 + const o = path.join(SCRIPTSOUTDIR, f); 73 78 console.log(`Processing script ${p}`); 74 79 try { 75 80 await fsp.writeFile(o, uglifyjs.minify((await fsp.readFile(p)).toString()).code); ··· 84 89 85 90 // Process images 86 91 async function images(dir = '') { 87 - let p = path.join(IMAGESDIR, dir); 92 + const p = path.join(IMAGESDIR, dir); 88 93 await mkdir(p); 89 94 if (dir.length === 0) { 90 95 await mkdir(IMAGESOUTDIR) 91 96 await emptyDir(IMAGESOUTDIR); 92 97 } 93 - let files = await fsp.readdir(p, { 98 + const files = await fsp.readdir(p, { 94 99 withFileTypes: true 95 100 }); 96 101 if (files.length) { 97 102 await Promise.all(files.map(f => new Promise(async (res, reject) => { 98 103 if (f.isFile()) { 99 - let outDir = path.join(IMAGESOUTDIR, dir); 100 - let infile = path.join(p, f.name); 101 - let outfile = path.join(outDir, f.name.substring(0, f.name.lastIndexOf('.')) + '.webp'); 104 + const outDir = path.join(IMAGESOUTDIR, dir); 105 + const infile = path.join(p, f.name); 106 + const extension = getFileExtension(infile); 107 + const outfile = path.join(outDir, f.name.substring(0, f.name.lastIndexOf('.')) + '.webp'); 102 108 await mkdir(outDir); 103 109 console.log(`Processing image ${infile}`) 104 - let process = spawn('cwebp', ['-mt', '-q', '50', infile, '-o', outfile]); 105 - let timeout = setTimeout(() => { 110 + const libwebpArgs = ['-mt']; 111 + if (extension === 'jpeg' || extension === 'jpg') { 112 + libwebpArgs.push('-q', '60'); 113 + } 114 + else { 115 + libwebpArgs.push('-near_lossless', '55'); 116 + } 117 + libwebpArgs.push(infile, '-o', outfile); 118 + const process = spawn('cwebp', libwebpArgs); 119 + const timeout = setTimeout(() => { 106 120 reject('Timed out'); 107 121 process.kill(); 108 122 }, 30000);