const { lstatSync, readdirSync, mkdirSync, copyFileSync, writeFileSync, readFileSync } = require('fs') const { join, basename } = require('path') const includepaths = require("rollup-plugin-includepaths") const isDirectory = source => lstatSync(source).isDirectory() const getDirectories = source => readdirSync(source).map(name => join(source, name)).filter(isDirectory) function ensureDir(folder) { try { if (!isDirectory(folder)) mkdirSync(folder) } catch (e) { mkdirSync(folder) } } ensureDir("./out") const sass = require('sass'); function findHead(elm) { if (elm.tagName === "head") return elm; for (let i = 0; i < elm.childNodes.length; i++) { let res = findHead(elm.childNodes[i]) if (res) return res; } return undefined; } const rollup = require("rollup") const minify = require("html-minifier").minify const gzipSize = require('gzip-size'); async function buildPage(folder, name) { const pagename = basename(folder); const outpath = "./out/" + pagename; ensureDir(outpath) let bundle = await rollup.rollup({ input: `${folder}/${pagename}.js`, plugins: [includepaths({ paths: ["shared"] })], }) let { code, map } = await bundle.generate({ format: "iife", }) let sass_res = sass.renderSync({ file: folder + `/${pagename}.scss`, includePaths: ["./node_modules", folder, "./shared"], outputStyle: "compressed" }) let css = "\n"; let script = "\n"; let html = readFileSync(`${folder}/${pagename}.hbs`).toString("utf8"); let idx = html.indexOf("") if (idx < 0) throw new Error("No head element found") let idx2 = html.indexOf("") if (idx2 < 0) throw new Error("No body element found") if (idx < idx2) { let part1 = html.slice(0, idx) let part2 = html.slice(idx, idx2); let part3 = html.slice(idx2, html.length); html = part1 + css + part2 + script + part3; } else { let part1 = html.slice(0, idx2) let part2 = html.slice(idx2, idx); let part3 = html.slice(idx, html.length); html = part1 + script + part2 + css + part3; } let result = minify(html, { removeAttributeQuotes: true, collapseWhitespace: true, html5: true, keepClosingSlash: true, minifyCSS: true, minifyJS: true, removeComments: true, useShortDoctype: true }) let gzips = await gzipSize(result) writeFileSync(`${outpath}/${pagename}.html`, result) let stats = { sass: sass_res.stats, js: { chars: code.length }, css: { chars: css.length }, bundle_size: result.length, gzip_size: gzips } writeFileSync(outpath + `/stats.json`, JSON.stringify(stats, null, " ")) } async function run() { const pages = getDirectories("./src"); const ProgressBar = require('progress'); // const bar = new ProgressBar('[:bar] :current/:total :percent :elapseds :etas', { // // schema: '[:bar] :current/:total :percent :elapseds :etas', // total: pages.length // }); await Promise.all(pages.map(async e => { try { await buildPage(e) } catch (er) { console.error("Failed compiling", basename(e)) console.log(er.message) } // bar.tick() })) console.log("Finished compiling!") } if (process.argv.join(" ").toLowerCase().indexOf("watch") < 0) { run() } else { const nodemon = require('nodemon'); nodemon({ script: "dummy.js", ext: 'js hbs scss', ignore: ["out/"] }); nodemon.on('start', function () { run() }).on('quit', function () { process.exit(); }).on('restart', function (files) { // console.log('App restarted due to: ', files); }); }