const MinifyHTML = require('html-minifier').minify const UglifyJS = require('uglify-js') const CleanCss = require('clean-css') const Zlib = require('zlib') const fs = require('fs') const path = require('path') const input_dir = "/deploy/in" const output_dir = "/deploy/out" function ensureDirectoryExists(file_path) { const file_dir = path.dirname(file_path) if (!fs.existsSync(file_dir)) { fs.mkdirSync(file_dir) } } function minifyHtml(input_file, output_file) { const opts = {keep_spaces_between_attributes: true, keep_comments: true} const minified = MinifyHTML(fs.readFileSync(input_file, 'utf8'), opts) ensureDirectoryExists(output_file) fs.writeFileSync(output_file, minified, 'utf8') } function minifyCss(input_file, output_file) { input = fs.readFileSync(input_file) const output = new CleanCss().minify(input) fs.writeFileSync(output_file, output.styles) } function minifyJs(input_file, output_file) { const input = fs.readFileSync(input_file, 'utf8') const minified = UglifyJS.minify(input) fs.writeFileSync(output_file, minified.code, 'utf8') } function minifyJson(input_file, output_file) { const json = fs.readFileSync(input_file, 'utf8') const parsed = JSON.parse(json) const minified = JSON.stringify(parsed) fs.writeFileSync(output_file, minified, 'utf8') } function minifyXml(input_file, output_file) { // Not yet available } function compressGzip(input_path, output_path) { const input = fs.createReadStream(input_path) const gzip = Zlib.createGzip() const output = fs.createWriteStream(output_path) input.pipe(gzip).pipe(output) output.on('finish', () => { return }) } function compressBrotli(input_path, output_path) { const input = fs.createReadStream(input_path) const brotli = Zlib.createBrotliCompress() const output = fs.createWriteStream(output_path) input.pipe(brotli).pipe(output) output.on('finish', () => { return }) } processable_extentions = ['.html', '.css', '.js', '.json', '.xml', '.log', '.md', '.svg', '.wasm', '.yaml', '.yml', '.vcard', '.ical'] // Loop over file and subdirectories function processFiles(inputDir, outputDir) { fs.readdirSync(inputDir).forEach(file => { const inputFile = path.join(inputDir, file); const outputFile = path.join(outputDir, file); if (fs.statSync(inputFile).isDirectory()) { const nestedOutputDir = path.join(outputDir, file); fs.mkdirSync(nestedOutputDir, { recursive: true }); processFiles(inputFile, nestedOutputDir); // Recursive call with nested input and output directories } else { const extension = path.extname(file).toLowerCase(); switch (extension) { case '.html': minifyHtml(inputFile, outputFile); break; case '.css': minifyCss(inputFile, outputFile); break; case '.js': minifyJs(inputFile, outputFile); break; case '.json': minifyJson(inputFile, outputFile); break; case '.xml': minifyXml(inputFile, outputFile); break; default: fs.copyFileSync(inputFile, outputFile); } } }); } function compressFiles(directory) { fs.readdirSync(directory).forEach(file => { const file_path = path.join(directory, file); if (fs.statSync(file_path).isDirectory()) { compressFiles(file_path); } else { const extension = path.extname(file).toLowerCase(); if (processable_extentions.includes(extension)) { compressGzip(file_path, file_path + '.gz'); compressBrotli(file_path, file_path + '.br'); } } }); } processFiles(input_dir, output_dir); compressFiles(output_dir);